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.inc15
-rw-r--r--src/lib/libc/crypt/arc4random.3110
-rw-r--r--src/lib/libc/crypt/arc4random.c182
-rw-r--r--src/lib/libc/crypt/bcrypt.c331
-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.3321
-rw-r--r--src/lib/libc/crypt/crypt.c700
-rw-r--r--src/lib/libc/crypt/crypt2.c108
-rw-r--r--src/lib/libc/crypt/md5crypt.c153
-rw-r--r--src/lib/libc/crypt/skipjack.c258
-rw-r--r--src/lib/libc/include/namespace.h2
-rw-r--r--src/lib/libc/include/thread_private.h134
-rw-r--r--src/lib/libc/net/Makefile.inc79
-rw-r--r--src/lib/libc/net/base64.c318
-rw-r--r--src/lib/libc/net/byteorder.3184
-rw-r--r--src/lib/libc/net/ethers.367
-rw-r--r--src/lib/libc/net/ethers.c179
-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.3577
-rw-r--r--src/lib/libc/net/getaddrinfo.c1885
-rw-r--r--src/lib/libc/net/gethostbyname.3230
-rw-r--r--src/lib/libc/net/gethostnamadr.c982
-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.3348
-rw-r--r--src/lib/libc/net/getnameinfo.c372
-rw-r--r--src/lib/libc/net/getnetbyaddr.c20
-rw-r--r--src/lib/libc/net/getnetbyname.c22
-rw-r--r--src/lib/libc/net/getnetent.383
-rw-r--r--src/lib/libc/net/getnetent.c40
-rw-r--r--src/lib/libc/net/getnetnamadr.c400
-rw-r--r--src/lib/libc/net/getproto.c16
-rw-r--r--src/lib/libc/net/getprotoent.362
-rw-r--r--src/lib/libc/net/getprotoent.c38
-rw-r--r--src/lib/libc/net/getprotoname.c16
-rw-r--r--src/lib/libc/net/getrrsetbyname.3165
-rw-r--r--src/lib/libc/net/getrrsetbyname.c512
-rw-r--r--src/lib/libc/net/getservbyname.c40
-rw-r--r--src/lib/libc/net/getservbyport.c16
-rw-r--r--src/lib/libc/net/getservent.370
-rw-r--r--src/lib/libc/net/getservent.c38
-rw-r--r--src/lib/libc/net/herror.c40
-rw-r--r--src/lib/libc/net/htonl.c18
-rw-r--r--src/lib/libc/net/htons.c13
-rw-r--r--src/lib/libc/net/if_indextoname.3136
-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.3250
-rw-r--r--src/lib/libc/net/inet6_option_space.3444
-rw-r--r--src/lib/libc/net/inet6_rthdr_space.3317
-rw-r--r--src/lib/libc/net/inet_addr.c93
-rw-r--r--src/lib/libc/net/inet_lnaof.c18
-rw-r--r--src/lib/libc/net/inet_makeaddr.c18
-rw-r--r--src/lib/libc/net/inet_net.3181
-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.c18
-rw-r--r--src/lib/libc/net/inet_network.c31
-rw-r--r--src/lib/libc/net/inet_ntoa.c16
-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.3123
-rw-r--r--src/lib/libc/net/ipx_addr.c224
-rw-r--r--src/lib/libc/net/ipx_ntoa.c49
-rw-r--r--src/lib/libc/net/iso_addr.319
-rw-r--r--src/lib/libc/net/iso_addr.c14
-rw-r--r--src/lib/libc/net/link_addr.3 (renamed from src/lib/libc/net/linkaddr.3)34
-rw-r--r--src/lib/libc/net/linkaddr.c14
-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.337
-rw-r--r--src/lib/libc/net/ns_addr.c26
-rw-r--r--src/lib/libc/net/ns_ntoa.c84
-rw-r--r--src/lib/libc/net/nsap_addr.c109
-rw-r--r--src/lib/libc/net/ntohl.c18
-rw-r--r--src/lib/libc/net/ntohs.c13
-rw-r--r--src/lib/libc/net/rcmd.3172
-rw-r--r--src/lib/libc/net/rcmd.c553
-rw-r--r--src/lib/libc/net/rcmdsh.396
-rw-r--r--src/lib/libc/net/rcmdsh.c193
-rw-r--r--src/lib/libc/net/recv.c14
-rw-r--r--src/lib/libc/net/res_comp.c229
-rw-r--r--src/lib/libc/net/res_data.c113
-rw-r--r--src/lib/libc/net/res_debug.c1530
-rw-r--r--src/lib/libc/net/res_init.c504
-rw-r--r--src/lib/libc/net/res_mkquery.c240
-rw-r--r--src/lib/libc/net/res_query.c225
-rw-r--r--src/lib/libc/net/res_random.c228
-rw-r--r--src/lib/libc/net/res_send.c872
-rw-r--r--src/lib/libc/net/resolver.3109
-rw-r--r--src/lib/libc/net/rresvport.c113
-rw-r--r--src/lib/libc/net/rthdr.c228
-rw-r--r--src/lib/libc/net/send.c14
-rw-r--r--src/lib/libc/net/sethostent.c29
-rw-r--r--src/lib/libc/net/vars6.c42
-rw-r--r--src/lib/libc/stdlib/Makefile.inc57
-rw-r--r--src/lib/libc/stdlib/_rand48.c4
-rw-r--r--src/lib/libc/stdlib/a64l.3133
-rw-r--r--src/lib/libc/stdlib/a64l.c28
-rw-r--r--src/lib/libc/stdlib/abort.326
-rw-r--r--src/lib/libc/stdlib/abort.c35
-rw-r--r--src/lib/libc/stdlib/abs.323
-rw-r--r--src/lib/libc/stdlib/abs.c9
-rw-r--r--src/lib/libc/stdlib/alloca.341
-rw-r--r--src/lib/libc/stdlib/atexit.319
-rw-r--r--src/lib/libc/stdlib/atexit.c141
-rw-r--r--src/lib/libc/stdlib/atexit.h57
-rw-r--r--src/lib/libc/stdlib/atof.313
-rw-r--r--src/lib/libc/stdlib/atof.c9
-rw-r--r--src/lib/libc/stdlib/atoi.332
-rw-r--r--src/lib/libc/stdlib/atoi.c9
-rw-r--r--src/lib/libc/stdlib/atol.319
-rw-r--r--src/lib/libc/stdlib/atol.c9
-rw-r--r--src/lib/libc/stdlib/atoll.3 (renamed from src/lib/libc/stdlib/calloc.3)59
-rw-r--r--src/lib/libc/stdlib/atoll.c41
-rw-r--r--src/lib/libc/stdlib/bsearch.325
-rw-r--r--src/lib/libc/stdlib/bsearch.c11
-rw-r--r--src/lib/libc/stdlib/calloc.c20
-rw-r--r--src/lib/libc/stdlib/cfree.c45
-rw-r--r--src/lib/libc/stdlib/div.323
-rw-r--r--src/lib/libc/stdlib/div.c9
-rw-r--r--src/lib/libc/stdlib/drand48.c4
-rw-r--r--src/lib/libc/stdlib/ecvt.3165
-rw-r--r--src/lib/libc/stdlib/ecvt.c103
-rw-r--r--src/lib/libc/stdlib/erand48.c4
-rw-r--r--src/lib/libc/stdlib/exit.331
-rw-r--r--src/lib/libc/stdlib/exit.c42
-rw-r--r--src/lib/libc/stdlib/free.382
-rw-r--r--src/lib/libc/stdlib/gcvt.c99
-rw-r--r--src/lib/libc/stdlib/getenv.372
-rw-r--r--src/lib/libc/stdlib/getenv.c72
-rw-r--r--src/lib/libc/stdlib/getopt.3252
-rw-r--r--src/lib/libc/stdlib/getopt.c118
-rw-r--r--src/lib/libc/stdlib/getopt_long.3377
-rw-r--r--src/lib/libc/stdlib/getopt_long.c544
-rw-r--r--src/lib/libc/stdlib/getsubopt.3143
-rw-r--r--src/lib/libc/stdlib/getsubopt.c102
-rw-r--r--src/lib/libc/stdlib/heapsort.c17
-rw-r--r--src/lib/libc/stdlib/insque.3100
-rw-r--r--src/lib/libc/stdlib/insque.c52
-rw-r--r--src/lib/libc/stdlib/jrand48.c4
-rw-r--r--src/lib/libc/stdlib/l64a.c15
-rw-r--r--src/lib/libc/stdlib/labs.335
-rw-r--r--src/lib/libc/stdlib/labs.c9
-rw-r--r--src/lib/libc/stdlib/lcong48.c4
-rw-r--r--src/lib/libc/stdlib/ldiv.329
-rw-r--r--src/lib/libc/stdlib/ldiv.c9
-rw-r--r--src/lib/libc/stdlib/llabs.c45
-rw-r--r--src/lib/libc/stdlib/lrand48.c4
-rw-r--r--src/lib/libc/stdlib/lsearch.3103
-rw-r--r--src/lib/libc/stdlib/lsearch.c86
-rw-r--r--src/lib/libc/stdlib/malloc.3399
-rw-r--r--src/lib/libc/stdlib/malloc.c1610
-rw-r--r--src/lib/libc/stdlib/memory.371
-rw-r--r--src/lib/libc/stdlib/merge.c23
-rw-r--r--src/lib/libc/stdlib/mrand48.c4
-rw-r--r--src/lib/libc/stdlib/multibyte.c15
-rw-r--r--src/lib/libc/stdlib/nrand48.c4
-rw-r--r--src/lib/libc/stdlib/putenv.c25
-rw-r--r--src/lib/libc/stdlib/qabs.318
-rw-r--r--src/lib/libc/stdlib/qabs.c9
-rw-r--r--src/lib/libc/stdlib/qdiv.322
-rw-r--r--src/lib/libc/stdlib/qdiv.c9
-rw-r--r--src/lib/libc/stdlib/qsort.391
-rw-r--r--src/lib/libc/stdlib/qsort.c40
-rw-r--r--src/lib/libc/stdlib/radixsort.350
-rw-r--r--src/lib/libc/stdlib/radixsort.c21
-rw-r--r--src/lib/libc/stdlib/rand.335
-rw-r--r--src/lib/libc/stdlib/rand.c24
-rw-r--r--src/lib/libc/stdlib/rand48.345
-rw-r--r--src/lib/libc/stdlib/rand48.h4
-rw-r--r--src/lib/libc/stdlib/random.3113
-rw-r--r--src/lib/libc/stdlib/random.c148
-rw-r--r--src/lib/libc/stdlib/realloc.3100
-rw-r--r--src/lib/libc/stdlib/realpath.340
-rw-r--r--src/lib/libc/stdlib/realpath.c43
-rw-r--r--src/lib/libc/stdlib/remque.c48
-rw-r--r--src/lib/libc/stdlib/seed48.c4
-rw-r--r--src/lib/libc/stdlib/setenv.c22
-rw-r--r--src/lib/libc/stdlib/srand48.c4
-rw-r--r--src/lib/libc/stdlib/strtod.343
-rw-r--r--src/lib/libc/stdlib/strtod.c254
-rw-r--r--src/lib/libc/stdlib/strtol.3148
-rw-r--r--src/lib/libc/stdlib/strtol.c76
-rw-r--r--src/lib/libc/stdlib/strtoll.c (renamed from src/lib/libc/stdlib/strtoq.c)96
-rw-r--r--src/lib/libc/stdlib/strtoul.3147
-rw-r--r--src/lib/libc/stdlib/strtoul.c50
-rw-r--r--src/lib/libc/stdlib/strtoull.c (renamed from src/lib/libc/stdlib/strtouq.c)68
-rw-r--r--src/lib/libc/stdlib/system.350
-rw-r--r--src/lib/libc/stdlib/system.c29
-rw-r--r--src/lib/libc/stdlib/tfind.c41
-rw-r--r--src/lib/libc/stdlib/tsearch.3116
-rw-r--r--src/lib/libc/stdlib/tsearch.c126
-rw-r--r--src/lib/libc/string/Makefile.inc64
-rw-r--r--src/lib/libc/string/__strerror.c46
-rw-r--r--src/lib/libc/string/__strsignal.c36
-rw-r--r--src/lib/libc/string/bcmp.316
-rw-r--r--src/lib/libc/string/bcmp.c14
-rw-r--r--src/lib/libc/string/bcopy.325
-rw-r--r--src/lib/libc/string/bcopy.c9
-rw-r--r--src/lib/libc/string/bm.3115
-rw-r--r--src/lib/libc/string/bm.c13
-rw-r--r--src/lib/libc/string/bstring.334
-rw-r--r--src/lib/libc/string/bzero.317
-rw-r--r--src/lib/libc/string/bzero.c19
-rw-r--r--src/lib/libc/string/ffs.315
-rw-r--r--src/lib/libc/string/ffs.c75
-rw-r--r--src/lib/libc/string/index.383
-rw-r--r--src/lib/libc/string/index.c14
-rw-r--r--src/lib/libc/string/memccpy.334
-rw-r--r--src/lib/libc/string/memccpy.c19
-rw-r--r--src/lib/libc/string/memchr.326
-rw-r--r--src/lib/libc/string/memchr.c18
-rw-r--r--src/lib/libc/string/memcmp.322
-rw-r--r--src/lib/libc/string/memcmp.c15
-rw-r--r--src/lib/libc/string/memcpy.331
-rw-r--r--src/lib/libc/string/memmove.326
-rw-r--r--src/lib/libc/string/memset.324
-rw-r--r--src/lib/libc/string/memset.c16
-rw-r--r--src/lib/libc/string/rindex.381
-rw-r--r--src/lib/libc/string/rindex.c16
-rw-r--r--src/lib/libc/string/strcasecmp.330
-rw-r--r--src/lib/libc/string/strcasecmp.c42
-rw-r--r--src/lib/libc/string/strcat.375
-rw-r--r--src/lib/libc/string/strcat.c24
-rw-r--r--src/lib/libc/string/strchr.358
-rw-r--r--src/lib/libc/string/strcmp.323
-rw-r--r--src/lib/libc/string/strcmp.c16
-rw-r--r--src/lib/libc/string/strcoll.317
-rw-r--r--src/lib/libc/string/strcoll.c12
-rw-r--r--src/lib/libc/string/strcpy.380
-rw-r--r--src/lib/libc/string/strcpy.c24
-rw-r--r--src/lib/libc/string/strcspn.337
-rw-r--r--src/lib/libc/string/strcspn.c17
-rw-r--r--src/lib/libc/string/strdup.361
-rw-r--r--src/lib/libc/string/strdup.c35
-rw-r--r--src/lib/libc/string/strerror.337
-rw-r--r--src/lib/libc/string/strerror.c14
-rw-r--r--src/lib/libc/string/strerror_r.c30
-rw-r--r--src/lib/libc/string/strftime.3202
-rw-r--r--src/lib/libc/string/strftime.c317
-rw-r--r--src/lib/libc/string/string.358
-rw-r--r--src/lib/libc/string/strlcat.c59
-rw-r--r--src/lib/libc/string/strlcpy.3179
-rw-r--r--src/lib/libc/string/strlcpy.c55
-rw-r--r--src/lib/libc/string/strlen.324
-rw-r--r--src/lib/libc/string/strlen.c29
-rw-r--r--src/lib/libc/string/strmode.380
-rw-r--r--src/lib/libc/string/strmode.c20
-rw-r--r--src/lib/libc/string/strncat.c18
-rw-r--r--src/lib/libc/string/strncmp.c17
-rw-r--r--src/lib/libc/string/strncpy.c18
-rw-r--r--src/lib/libc/string/strpbrk.322
-rw-r--r--src/lib/libc/string/strpbrk.c16
-rw-r--r--src/lib/libc/string/strrchr.359
-rw-r--r--src/lib/libc/string/strsep.390
-rw-r--r--src/lib/libc/string/strsep.c38
-rw-r--r--src/lib/libc/string/strsignal.311
-rw-r--r--src/lib/libc/string/strsignal.c15
-rw-r--r--src/lib/libc/string/strspn.336
-rw-r--r--src/lib/libc/string/strspn.c17
-rw-r--r--src/lib/libc/string/strstr.320
-rw-r--r--src/lib/libc/string/strstr.c16
-rw-r--r--src/lib/libc/string/strtok.390
-rw-r--r--src/lib/libc/string/strtok.c32
-rw-r--r--src/lib/libc/string/strxfrm.315
-rw-r--r--src/lib/libc/string/strxfrm.c32
-rw-r--r--src/lib/libc/string/swab.313
-rw-r--r--src/lib/libc/string/swab.c16
275 files changed, 25673 insertions, 6213 deletions
diff --git a/src/lib/libc/crypt/Makefile.inc b/src/lib/libc/crypt/Makefile.inc
new file mode 100644
index 0000000000..131e1d3f39
--- /dev/null
+++ b/src/lib/libc/crypt/Makefile.inc
@@ -0,0 +1,15 @@
1# $OpenBSD: Makefile.inc,v 1.15 2003/08/12 01:22:17 deraadt Exp $
2
3.PATH: ${LIBCSRCDIR}/arch/${MACHINE_ARCH}/crypt ${LIBCSRCDIR}/crypt
4
5SRCS+= cast.c crypt.c crypt2.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 bcrypt_gensalt.3 crypt.3 bcrypt.3 crypt.3 md5crypt.3
11MLINKS+=crypt.3 des_setkey.3 blowfish.3 blf_key.3 blowfish.3 blf_enc.3
12MLINKS+=blowfish.3 blf_dec.3 blowfish.3 blf_ecb_encrypt.3
13MLINKS+=blowfish.3 blf_ecb_decrypt.3 blowfish.3 blf_cbc_encrypt.3
14MLINKS+=blowfish.3 blf_cbc_decrypt.3
15MLINKS+=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..5b376488ec
--- /dev/null
+++ b/src/lib/libc/crypt/arc4random.c
@@ -0,0 +1,182 @@
1/* $OpenBSD: arc4random.c,v 1.10 2003/11/26 21:40:08 djm 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
47static int rs_initialized;
48static struct arc4_stream rs;
49static pid_t arc4_stir_pid;
50
51static inline u_int8_t arc4_getbyte(struct arc4_stream *);
52
53static inline void
54arc4_init(struct arc4_stream *as)
55{
56 int n;
57
58 for (n = 0; n < 256; n++)
59 as->s[n] = n;
60 as->i = 0;
61 as->j = 0;
62}
63
64static inline void
65arc4_addrandom(struct arc4_stream *as, u_char *dat, int datlen)
66{
67 int n;
68 u_int8_t si;
69
70 as->i--;
71 for (n = 0; n < 256; n++) {
72 as->i = (as->i + 1);
73 si = as->s[as->i];
74 as->j = (as->j + si + dat[n % datlen]);
75 as->s[as->i] = as->s[as->j];
76 as->s[as->j] = si;
77 }
78 as->j = as->i;
79}
80
81static void
82arc4_stir(struct arc4_stream *as)
83{
84 int i, mib[2];
85 size_t len;
86 struct {
87 struct timeval tv;
88 u_int rnd[(128 - sizeof(struct timeval)) / sizeof(u_int)];
89 } rdat;
90
91 gettimeofday(&rdat.tv, NULL);
92 mib[0] = CTL_KERN;
93 mib[1] = KERN_ARND;
94
95 for (i = 0; i < sizeof(rdat.rnd) / sizeof(u_int); i ++) {
96 len = sizeof(u_int);
97 if (sysctl(mib, 2, &rdat.rnd[i], &len, NULL, 0) == -1)
98 break;
99 }
100
101 arc4_stir_pid = getpid();
102 arc4_addrandom(as, (void *) &rdat, sizeof(rdat));
103
104 /*
105 * Discard early keystream, as per recommendations in:
106 * http://www.wisdom.weizmann.ac.il/~itsik/RC4/Papers/Rc4_ksa.ps
107 */
108 for (i = 0; i < 256; i++)
109 (void) arc4_getbyte(as);
110}
111
112static inline u_int8_t
113arc4_getbyte(struct arc4_stream *as)
114{
115 u_int8_t si, sj;
116
117 as->i = (as->i + 1);
118 si = as->s[as->i];
119 as->j = (as->j + si);
120 sj = as->s[as->j];
121 as->s[as->i] = sj;
122 as->s[as->j] = si;
123 return (as->s[(si + sj) & 0xff]);
124}
125
126static inline u_int32_t
127arc4_getword(struct arc4_stream *as)
128{
129 u_int32_t val;
130 val = arc4_getbyte(as) << 24;
131 val |= arc4_getbyte(as) << 16;
132 val |= arc4_getbyte(as) << 8;
133 val |= arc4_getbyte(as);
134 return val;
135}
136
137void
138arc4random_stir(void)
139{
140 if (!rs_initialized) {
141 arc4_init(&rs);
142 rs_initialized = 1;
143 }
144 arc4_stir(&rs);
145}
146
147void
148arc4random_addrandom(u_char *dat, int datlen)
149{
150 if (!rs_initialized)
151 arc4random_stir();
152 arc4_addrandom(&rs, dat, datlen);
153}
154
155u_int32_t
156arc4random(void)
157{
158 if (!rs_initialized || arc4_stir_pid != getpid())
159 arc4random_stir();
160 return arc4_getword(&rs);
161}
162
163#if 0
164/*-------- Test code for i386 --------*/
165#include <stdio.h>
166#include <machine/pctr.h>
167int
168main(int argc, char **argv)
169{
170 const int iter = 1000000;
171 int i;
172 pctrval v;
173
174 v = rdtsc();
175 for (i = 0; i < iter; i++)
176 arc4random();
177 v = rdtsc() - v;
178 v /= iter;
179
180 printf("%qd cycles\n", v);
181}
182#endif
diff --git a/src/lib/libc/crypt/bcrypt.c b/src/lib/libc/crypt/bcrypt.c
new file mode 100644
index 0000000000..95251db1cd
--- /dev/null
+++ b/src/lib/libc/crypt/bcrypt.c
@@ -0,0 +1,331 @@
1/* $OpenBSD: bcrypt.c,v 1.18 2003/08/07 00:28:45 deraadt 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 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
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, 0, 1, 54, 55,
88 56, 57, 58, 59, 60, 61, 62, 63, 255, 255,
89 255, 255, 255, 255, 255, 2, 3, 4, 5, 6,
90 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
91 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
92 255, 255, 255, 255, 255, 255, 28, 29, 30,
93 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
94 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
95 51, 52, 53, 255, 255, 255, 255, 255
96};
97#define CHAR64(c) ( (c) > 127 ? 255 : index_64[(c)])
98
99static void
100decode_base64(u_int8_t *buffer, u_int16_t len, u_int8_t *data)
101{
102 u_int8_t *bp = buffer;
103 u_int8_t *p = data;
104 u_int8_t c1, c2, c3, c4;
105 while (bp < buffer + len) {
106 c1 = CHAR64(*p);
107 c2 = CHAR64(*(p + 1));
108
109 /* Invalid data */
110 if (c1 == 255 || c2 == 255)
111 break;
112
113 *bp++ = (c1 << 2) | ((c2 & 0x30) >> 4);
114 if (bp >= buffer + len)
115 break;
116
117 c3 = CHAR64(*(p + 2));
118 if (c3 == 255)
119 break;
120
121 *bp++ = ((c2 & 0x0f) << 4) | ((c3 & 0x3c) >> 2);
122 if (bp >= buffer + len)
123 break;
124
125 c4 = CHAR64(*(p + 3));
126 if (c4 == 255)
127 break;
128 *bp++ = ((c3 & 0x03) << 6) | c4;
129
130 p += 4;
131 }
132}
133
134static void
135encode_salt(char *salt, u_int8_t *csalt, u_int16_t clen, u_int8_t logr)
136{
137 salt[0] = '$';
138 salt[1] = BCRYPT_VERSION;
139 salt[2] = 'a';
140 salt[3] = '$';
141
142 snprintf(salt + 4, 4, "%2.2u$", logr);
143
144 encode_base64((u_int8_t *) salt + 7, csalt, clen);
145}
146/* Generates a salt for this version of crypt.
147 Since versions may change. Keeping this here
148 seems sensible.
149 */
150
151char *
152bcrypt_gensalt(u_int8_t log_rounds)
153{
154 u_int8_t csalt[BCRYPT_MAXSALT];
155 u_int16_t i;
156 u_int32_t seed = 0;
157
158 for (i = 0; i < BCRYPT_MAXSALT; i++) {
159 if (i % 4 == 0)
160 seed = arc4random();
161 csalt[i] = seed & 0xff;
162 seed = seed >> 8;
163 }
164
165 if (log_rounds < 4)
166 log_rounds = 4;
167
168 encode_salt(gsalt, csalt, BCRYPT_MAXSALT, log_rounds);
169 return gsalt;
170}
171/* We handle $Vers$log2(NumRounds)$salt+passwd$
172 i.e. $2$04$iwouldntknowwhattosayetKdJ6iFtacBqJdKe6aW7ou */
173
174char *
175bcrypt(const char *key, const char *salt)
176{
177 blf_ctx state;
178 u_int32_t rounds, i, k;
179 u_int16_t j;
180 u_int8_t key_len, salt_len, logr, minor;
181 u_int8_t ciphertext[4 * BCRYPT_BLOCKS] = "OrpheanBeholderScryDoubt";
182 u_int8_t csalt[BCRYPT_MAXSALT];
183 u_int32_t cdata[BCRYPT_BLOCKS];
184
185 /* Discard "$" identifier */
186 salt++;
187
188 if (*salt > BCRYPT_VERSION) {
189 /* How do I handle errors ? Return ':' */
190 return error;
191 }
192
193 /* Check for minor versions */
194 if (salt[1] != '$') {
195 switch (salt[1]) {
196 case 'a':
197 /* 'ab' should not yield the same as 'abab' */
198 minor = salt[1];
199 salt++;
200 break;
201 default:
202 return error;
203 }
204 } else
205 minor = 0;
206
207 /* Discard version + "$" identifier */
208 salt += 2;
209
210 if (salt[2] != '$')
211 /* Out of sync with passwd entry */
212 return error;
213
214 /* Computer power doesn't increase linear, 2^x should be fine */
215 if ((rounds = (u_int32_t) 1 << (logr = atoi(salt))) < BCRYPT_MINROUNDS)
216 return error;
217
218 /* Discard num rounds + "$" identifier */
219 salt += 3;
220
221 if (strlen(salt) * 3 / 4 < BCRYPT_MAXSALT)
222 return error;
223
224 /* We dont want the base64 salt but the raw data */
225 decode_base64(csalt, BCRYPT_MAXSALT, (u_int8_t *) salt);
226 salt_len = BCRYPT_MAXSALT;
227 key_len = strlen(key) + (minor >= 'a' ? 1 : 0);
228
229 /* Setting up S-Boxes and Subkeys */
230 Blowfish_initstate(&state);
231 Blowfish_expandstate(&state, csalt, salt_len,
232 (u_int8_t *) key, key_len);
233 for (k = 0; k < rounds; k++) {
234 Blowfish_expand0state(&state, (u_int8_t *) key, key_len);
235 Blowfish_expand0state(&state, csalt, salt_len);
236 }
237
238 /* This can be precomputed later */
239 j = 0;
240 for (i = 0; i < BCRYPT_BLOCKS; i++)
241 cdata[i] = Blowfish_stream2word(ciphertext, 4 * BCRYPT_BLOCKS, &j);
242
243 /* Now do the encryption */
244 for (k = 0; k < 64; k++)
245 blf_enc(&state, cdata, BCRYPT_BLOCKS / 2);
246
247 for (i = 0; i < BCRYPT_BLOCKS; i++) {
248 ciphertext[4 * i + 3] = cdata[i] & 0xff;
249 cdata[i] = cdata[i] >> 8;
250 ciphertext[4 * i + 2] = cdata[i] & 0xff;
251 cdata[i] = cdata[i] >> 8;
252 ciphertext[4 * i + 1] = cdata[i] & 0xff;
253 cdata[i] = cdata[i] >> 8;
254 ciphertext[4 * i + 0] = cdata[i] & 0xff;
255 }
256
257
258 i = 0;
259 encrypted[i++] = '$';
260 encrypted[i++] = BCRYPT_VERSION;
261 if (minor)
262 encrypted[i++] = minor;
263 encrypted[i++] = '$';
264
265 snprintf(encrypted + i, 4, "%2.2u$", logr);
266
267 encode_base64((u_int8_t *) encrypted + i + 3, csalt, BCRYPT_MAXSALT);
268 encode_base64((u_int8_t *) encrypted + strlen(encrypted), ciphertext,
269 4 * BCRYPT_BLOCKS - 1);
270 return encrypted;
271}
272
273static void
274encode_base64(u_int8_t *buffer, u_int8_t *data, u_int16_t len)
275{
276 u_int8_t *bp = buffer;
277 u_int8_t *p = data;
278 u_int8_t c1, c2;
279 while (p < data + len) {
280 c1 = *p++;
281 *bp++ = Base64Code[(c1 >> 2)];
282 c1 = (c1 & 0x03) << 4;
283 if (p >= data + len) {
284 *bp++ = Base64Code[c1];
285 break;
286 }
287 c2 = *p++;
288 c1 |= (c2 >> 4) & 0x0f;
289 *bp++ = Base64Code[c1];
290 c1 = (c2 & 0x0f) << 2;
291 if (p >= data + len) {
292 *bp++ = Base64Code[c1];
293 break;
294 }
295 c2 = *p++;
296 c1 |= (c2 >> 6) & 0x03;
297 *bp++ = Base64Code[c1];
298 *bp++ = Base64Code[c2 & 0x3f];
299 }
300 *bp = '\0';
301}
302#if 0
303void
304main()
305{
306 char blubber[73];
307 char salt[100];
308 char *p;
309 salt[0] = '$';
310 salt[1] = BCRYPT_VERSION;
311 salt[2] = '$';
312
313 snprintf(salt + 3, 4, "%2.2u$", 5);
314
315 printf("24 bytes of salt: ");
316 fgets(salt + 6, 94, stdin);
317 salt[99] = 0;
318 printf("72 bytes of password: ");
319 fpurge(stdin);
320 fgets(blubber, 73, stdin);
321 blubber[72] = 0;
322
323 p = crypt(blubber, salt);
324 printf("Passwd entry: %s\n\n", p);
325
326 p = bcrypt_gensalt(5);
327 printf("Generated salt: %s\n", p);
328 p = crypt(blubber, p);
329 printf("Passwd entry: %s\n", p);
330}
331#endif
diff --git a/src/lib/libc/crypt/blowfish.3 b/src/lib/libc/crypt/blowfish.3
new file mode 100644
index 0000000000..44f7eb2bbf
--- /dev/null
+++ b/src/lib/libc/crypt/blowfish.3
@@ -0,0 +1,106 @@
1.\" $OpenBSD: blowfish.3,v 1.12 2003/08/28 12:35:00 jmc 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 maximum key size is 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
106.An Niels Provos Aq 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..12226b5215
--- /dev/null
+++ b/src/lib/libc/crypt/blowfish.c
@@ -0,0 +1,694 @@
1/* $OpenBSD: blowfish.c,v 1.17 2003/04/09 21:46:02 markus 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 static 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..9908750f07
--- /dev/null
+++ b/src/lib/libc/crypt/crypt.3
@@ -0,0 +1,321 @@
1.\" $OpenBSD: crypt.3,v 1.22 2004/04/06 11:00:32 djm 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 <pwd.h>
46.Fd #include <unistd.h>
47.Ft char *
48.Fn crypt "const char *key" "const char *setting"
49.Ft int
50.Fn setkey "char *key"
51.Ft int
52.Fn encrypt "char *block" "int flag"
53.Ft int
54.Fn des_setkey "const char *key"
55.Ft int
56.Fn des_cipher "const char *in" "char *out" "int32_t salt" "int count"
57.Ft char *
58.Fn bcrypt_gensalt "u_int8_t log_rounds"
59.Ft char *
60.Fn bcrypt "const char *key" "const char *salt"
61.Ft char *
62.Fn md5crypt "const char *key" "const char *salt"
63.Sh DESCRIPTION
64The
65.Fn crypt
66function performs password encryption based on the
67.Tn NBS
68Data Encryption Standard (DES).
69Additional code has been added to deter key search attempts and to use
70stronger hashing algorithms.
71.Pp
72The first argument to
73.Fn crypt
74is a
75.Dv null Ns -terminated
76string, typically a user's typed password.
77The second is in one of three forms:
78if it begins with an underscore
79.Pq Ql _
80then an extended format is used
81in interpreting both the key and the setting, as outlined below.
82If it begins
83with a string character
84.Pq Ql $
85and a number then a different algorithm is used depending on the number.
86At the moment a
87.Ql $1
88chooses MD5 hashing and a
89.Ql $2
90chooses Blowfish hashing; see below for more information.
91.Ss Extended crypt
92The
93.Ar key
94is divided into groups of 8 characters (the last group is null-padded)
95and the low-order 7 bits of each character (56 bits per group) are
96used to form the DES key as follows:
97the first group of 56 bits becomes the initial DES key.
98For each additional group, the XOR of the encryption of the current DES
99key with itself and the group bits becomes the next DES key.
100.Pp
101The setting is a 9-character array consisting of an underscore followed
102by 4 bytes of iteration count and 4 bytes of salt.
103These are encoded as printable characters, 6 bits per character,
104least significant character first.
105The values 0 to 63 are encoded as
106.Dq \&./0-9A-Za-z .
107This allows 24 bits for both
108.Fa count
109and
110.Fa salt .
111.Ss "MD5" crypt
112For
113.Tn MD5
114crypt the version number,
115.Fa salt
116and the hashed password are separated by the
117.Ql $
118character.
119The maximum length of a password is limited by
120the length counter of the MD5 context, which is about
1212**64.
122A valid MD5 password entry looks like this:
123.Pp
124.Dq $1$caeiHQwX$hsKqOjrFRRN6K32OWkCBf1 .
125.Pp
126The whole MD5 password string is passed as
127.Fa setting
128for interpretation.
129.Ss "Blowfish" crypt
130The
131.Tn Blowfish
132version of crypt has 128 bits of
133.Fa salt
134in order to make building dictionaries of common passwords space consuming.
135The initial state of the
136.Tn Blowfish
137cipher is expanded using the
138.Fa salt
139and the
140.Fa password
141repeating the process a variable number of rounds, which is encoded in
142the password string.
143The maximum password length is 72.
144The final Blowfish password entry is created by encrypting the string
145.Pp
146.Dq OrpheanBeholderScryDoubt
147.Pp
148with the
149.Tn Blowfish
150state 64 times.
151.Pp
152The version number, the logarithm of the number of rounds and
153the concatenation of salt and hashed password are separated by the
154.Ql $
155character.
156An encoded
157.Sq 8
158would specify 256 rounds.
159A valid Blowfish password looks like this:
160.Pp
161.Dq $2a$12$eIAq8PR8sIUnJ1HaohxX2O9x9Qlm2vK97LJ5dsXdmB.eXF42qjchC .
162.Pp
163The whole Blowfish password string is passed as
164.Fa setting
165for interpretation.
166.Ss "Traditional" crypt
167The first 8 bytes of the key are null-padded, and the low-order 7 bits of
168each character is used to form the 56-bit
169.Tn DES
170key.
171.Pp
172The setting is a 2-character array of the ASCII-encoded salt.
173Thus only 12 bits of
174.Fa salt
175are used.
176.Fa count
177is set to 25.
178.Ss DES Algorithm
179The
180.Fa salt
181introduces disorder in the
182.Tn DES
183algorithm in one of 16777216 or 4096 possible ways
184(i.e., with 24 or 12 bits: if bit
185.Em i
186of the
187.Ar salt
188is set, then bits
189.Em i
190and
191.Em i+24
192are swapped in the
193.Tn DES
194E-box output).
195.Pp
196The DES key is used to encrypt a 64-bit constant using
197.Ar count
198iterations of
199.Tn DES .
200The value returned is a
201.Dv null Ns -terminated
202string, 20 or 13 bytes (plus null) in length, consisting of the
203.Ar setting
204followed by the encoded 64-bit encryption.
205.Pp
206The functions
207.Fn encrypt ,
208.Fn setkey ,
209.Fn des_setkey ,
210and
211.Fn des_cipher
212provide access to the
213.Tn DES
214algorithm itself.
215.Fn setkey
216is passed a 64-byte array of binary values (numeric 0 or 1).
217A 56-bit key is extracted from this array by dividing the
218array into groups of 8, and ignoring the last bit in each group.
219That bit is reserved for a byte parity check by DES, but is ignored
220by these functions.
221.Pp
222The
223.Fa block
224argument to
225.Fn encrypt
226is also a 64-byte array of binary values.
227If the value of
228.Fa flag
229is 0,
230.Fa block
231is encrypted otherwise it is decrypted.
232The result is returned in the original array
233.Fa block
234after using the key specified by
235.Fn setkey
236to process it.
237.Pp
238The argument to
239.Fn des_setkey
240is a character array of length 8.
241The least significant bit (the parity bit) in each character is ignored,
242and the remaining bits are concatenated to form a 56-bit key.
243The function
244.Fn des_cipher
245encrypts (or decrypts if
246.Fa count
247is negative) the 64-bits stored in the 8 characters at
248.Fa in
249using
250.Xr abs 3
251of
252.Fa count
253iterations of
254.Tn DES
255and stores the 64-bit result in the 8 characters at
256.Fa out
257(which may be the same as
258.Fa in ) .
259The
260.Fa salt
261specifies perturbations to the
262.Tn DES
263E-box output as described above.
264.Pp
265The function
266.Fn crypt
267returns a pointer to the encrypted value on success, and
268.Dv NULL
269on failure.
270The functions
271.Fn setkey ,
272.Fn encrypt ,
273.Fn des_setkey ,
274and
275.Fn des_cipher
276return 0 on success and 1 on failure.
277.Pp
278The
279.Fn crypt ,
280.Fn setkey ,
281and
282.Fn des_setkey
283functions all manipulate the same key space.
284.Sh SEE ALSO
285.Xr login 1 ,
286.Xr passwd 1 ,
287.Xr blowfish 3 ,
288.Xr getpass 3 ,
289.Xr md5 3 ,
290.Xr passwd 5
291.Sh HISTORY
292A rotor-based
293.Fn crypt
294function appeared in
295.At v3 .
296The current style
297.Fn crypt
298first appeared in
299.At v7 .
300.Pp
301This library (FreeSec 1.0) was developed outside the United States of America
302as an unencumbered replacement for the U.S.-only libcrypt encryption
303library.
304Programs linked against the
305.Fn crypt
306interface may be exported from the U.S.A. only if they use
307.Fn crypt
308solely for authentication purposes and avoid use of
309the other programmer interfaces listed above.
310Special care has been taken
311in the library so that programs which only use the
312.Fn crypt
313interface do not pull in the other components.
314.Sh AUTHORS
315.An David Burren Aq davidb@werj.com.au
316.Sh BUGS
317The
318.Fn crypt
319function returns a pointer to static data, and subsequent calls to
320.Fn crypt
321will 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..e0f5e8364a
--- /dev/null
+++ b/src/lib/libc/crypt/crypt.c
@@ -0,0 +1,700 @@
1/* $OpenBSD: crypt.c,v 1.18 2003/08/12 01:22:17 deraadt 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
49#if defined(LIBC_SCCS) && !defined(lint)
50static char rcsid[] = "$OpenBSD: crypt.c,v 1.18 2003/08/12 01:22:17 deraadt Exp $";
51#endif /* LIBC_SCCS and not lint */
52
53#include <sys/types.h>
54#include <sys/param.h>
55#include <pwd.h>
56#include <unistd.h>
57#include <string.h>
58
59#ifdef DEBUG
60# include <stdio.h>
61#endif
62
63static const u_char IP[64] = {
64 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,
65 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,
66 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3,
67 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7
68};
69
70static u_char inv_key_perm[64];
71static u_char u_key_perm[56];
72static u_char const key_perm[56] = {
73 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18,
74 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36,
75 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22,
76 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4
77};
78
79static const u_char key_shifts[16] = {
80 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
81};
82
83static u_char inv_comp_perm[56];
84static const u_char comp_perm[48] = {
85 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10,
86 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2,
87 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,
88 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32
89};
90
91/*
92 * No E box is used, as it's replaced by some ANDs, shifts, and ORs.
93 */
94
95static u_char u_sbox[8][64];
96static const u_char sbox[8][64] = {
97 {
98 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
99 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
100 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
101 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13
102 },
103 {
104 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
105 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
106 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
107 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9
108 },
109 {
110 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
111 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
112 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
113 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12
114 },
115 {
116 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
117 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
118 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
119 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14
120 },
121 {
122 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
123 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
124 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
125 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3
126 },
127 {
128 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
129 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
130 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
131 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13
132 },
133 {
134 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
135 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
136 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
137 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12
138 },
139 {
140 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
141 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
142 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
143 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
144 }
145};
146
147static u_char un_pbox[32];
148static const u_char pbox[32] = {
149 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,
150 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25
151};
152
153const u_int32_t _des_bits32[32] =
154{
155 0x80000000, 0x40000000, 0x20000000, 0x10000000,
156 0x08000000, 0x04000000, 0x02000000, 0x01000000,
157 0x00800000, 0x00400000, 0x00200000, 0x00100000,
158 0x00080000, 0x00040000, 0x00020000, 0x00010000,
159 0x00008000, 0x00004000, 0x00002000, 0x00001000,
160 0x00000800, 0x00000400, 0x00000200, 0x00000100,
161 0x00000080, 0x00000040, 0x00000020, 0x00000010,
162 0x00000008, 0x00000004, 0x00000002, 0x00000001
163};
164
165const u_char _des_bits8[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
166
167static u_int32_t saltbits;
168static int32_t old_salt;
169static const u_int32_t *bits28, *bits24;
170static u_char init_perm[64], final_perm[64];
171static u_int32_t en_keysl[16], en_keysr[16];
172static u_int32_t de_keysl[16], de_keysr[16];
173int _des_initialised = 0;
174static u_char m_sbox[4][4096];
175static u_int32_t psbox[4][256];
176static u_int32_t ip_maskl[8][256], ip_maskr[8][256];
177static u_int32_t fp_maskl[8][256], fp_maskr[8][256];
178static u_int32_t key_perm_maskl[8][128], key_perm_maskr[8][128];
179static u_int32_t comp_maskl[8][128], comp_maskr[8][128];
180static u_int32_t old_rawkey0, old_rawkey1;
181
182static u_char ascii64[] =
183 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
184/* 0000000000111111111122222222223333333333444444444455555555556666 */
185/* 0123456789012345678901234567890123456789012345678901234567890123 */
186
187static __inline int
188ascii_to_bin(char ch)
189{
190 if (ch > 'z')
191 return(0);
192 if (ch >= 'a')
193 return(ch - 'a' + 38);
194 if (ch > 'Z')
195 return(0);
196 if (ch >= 'A')
197 return(ch - 'A' + 12);
198 if (ch > '9')
199 return(0);
200 if (ch >= '.')
201 return(ch - '.');
202 return(0);
203}
204
205void
206_des_init(void)
207{
208 int i, j, b, k, inbit, obit;
209 u_int32_t *p, *il, *ir, *fl, *fr;
210
211 old_rawkey0 = old_rawkey1 = 0;
212 saltbits = 0;
213 old_salt = 0;
214 bits24 = (bits28 = _des_bits32 + 4) + 4;
215
216 /*
217 * Invert the S-boxes, reordering the input bits.
218 */
219 for (i = 0; i < 8; i++)
220 for (j = 0; j < 64; j++) {
221 b = (j & 0x20) | ((j & 1) << 4) | ((j >> 1) & 0xf);
222 u_sbox[i][j] = sbox[i][b];
223 }
224
225 /*
226 * Convert the inverted S-boxes into 4 arrays of 8 bits.
227 * Each will handle 12 bits of the S-box input.
228 */
229 for (b = 0; b < 4; b++)
230 for (i = 0; i < 64; i++)
231 for (j = 0; j < 64; j++)
232 m_sbox[b][(i << 6) | j] =
233 (u_sbox[(b << 1)][i] << 4) |
234 u_sbox[(b << 1) + 1][j];
235
236 /*
237 * Set up the initial & final permutations into a useful form, and
238 * initialise the inverted key permutation.
239 */
240 for (i = 0; i < 64; i++) {
241 init_perm[final_perm[i] = IP[i] - 1] = i;
242 inv_key_perm[i] = 255;
243 }
244
245 /*
246 * Invert the key permutation and initialise the inverted key
247 * compression permutation.
248 */
249 for (i = 0; i < 56; i++) {
250 u_key_perm[i] = key_perm[i] - 1;
251 inv_key_perm[key_perm[i] - 1] = i;
252 inv_comp_perm[i] = 255;
253 }
254
255 /*
256 * Invert the key compression permutation.
257 */
258 for (i = 0; i < 48; i++) {
259 inv_comp_perm[comp_perm[i] - 1] = i;
260 }
261
262 /*
263 * Set up the OR-mask arrays for the initial and final permutations,
264 * and for the key initial and compression permutations.
265 */
266 for (k = 0; k < 8; k++) {
267 for (i = 0; i < 256; i++) {
268 *(il = &ip_maskl[k][i]) = 0;
269 *(ir = &ip_maskr[k][i]) = 0;
270 *(fl = &fp_maskl[k][i]) = 0;
271 *(fr = &fp_maskr[k][i]) = 0;
272 for (j = 0; j < 8; j++) {
273 inbit = 8 * k + j;
274 if (i & _des_bits8[j]) {
275 if ((obit = init_perm[inbit]) < 32)
276 *il |= _des_bits32[obit];
277 else
278 *ir |= _des_bits32[obit-32];
279 if ((obit = final_perm[inbit]) < 32)
280 *fl |= _des_bits32[obit];
281 else
282 *fr |= _des_bits32[obit - 32];
283 }
284 }
285 }
286 for (i = 0; i < 128; i++) {
287 *(il = &key_perm_maskl[k][i]) = 0;
288 *(ir = &key_perm_maskr[k][i]) = 0;
289 for (j = 0; j < 7; j++) {
290 inbit = 8 * k + j;
291 if (i & _des_bits8[j + 1]) {
292 if ((obit = inv_key_perm[inbit]) == 255)
293 continue;
294 if (obit < 28)
295 *il |= bits28[obit];
296 else
297 *ir |= bits28[obit - 28];
298 }
299 }
300 *(il = &comp_maskl[k][i]) = 0;
301 *(ir = &comp_maskr[k][i]) = 0;
302 for (j = 0; j < 7; j++) {
303 inbit = 7 * k + j;
304 if (i & _des_bits8[j + 1]) {
305 if ((obit=inv_comp_perm[inbit]) == 255)
306 continue;
307 if (obit < 24)
308 *il |= bits24[obit];
309 else
310 *ir |= bits24[obit - 24];
311 }
312 }
313 }
314 }
315
316 /*
317 * Invert the P-box permutation, and convert into OR-masks for
318 * handling the output of the S-box arrays setup above.
319 */
320 for (i = 0; i < 32; i++)
321 un_pbox[pbox[i] - 1] = i;
322
323 for (b = 0; b < 4; b++)
324 for (i = 0; i < 256; i++) {
325 *(p = &psbox[b][i]) = 0;
326 for (j = 0; j < 8; j++) {
327 if (i & _des_bits8[j])
328 *p |= _des_bits32[un_pbox[8 * b + j]];
329 }
330 }
331
332 _des_initialised = 1;
333}
334
335void
336_des_setup_salt(int32_t salt)
337{
338 u_int32_t obit, saltbit;
339 int i;
340
341 if (salt == old_salt)
342 return;
343 old_salt = salt;
344
345 saltbits = 0;
346 saltbit = 1;
347 obit = 0x800000;
348 for (i = 0; i < 24; i++) {
349 if (salt & saltbit)
350 saltbits |= obit;
351 saltbit <<= 1;
352 obit >>= 1;
353 }
354}
355
356int
357des_setkey(const char *key)
358{
359 u_int32_t k0, k1, rawkey0, rawkey1;
360 int shifts, round;
361
362 if (!_des_initialised)
363 _des_init();
364
365 rawkey0 = ntohl(*(u_int32_t *) key);
366 rawkey1 = ntohl(*(u_int32_t *) (key + 4));
367
368 if ((rawkey0 | rawkey1)
369 && rawkey0 == old_rawkey0
370 && rawkey1 == old_rawkey1) {
371 /*
372 * Already setup for this key.
373 * This optimisation fails on a zero key (which is weak and
374 * has bad parity anyway) in order to simplify the starting
375 * conditions.
376 */
377 return(0);
378 }
379 old_rawkey0 = rawkey0;
380 old_rawkey1 = rawkey1;
381
382 /*
383 * Do key permutation and split into two 28-bit subkeys.
384 */
385 k0 = key_perm_maskl[0][rawkey0 >> 25]
386 | key_perm_maskl[1][(rawkey0 >> 17) & 0x7f]
387 | key_perm_maskl[2][(rawkey0 >> 9) & 0x7f]
388 | key_perm_maskl[3][(rawkey0 >> 1) & 0x7f]
389 | key_perm_maskl[4][rawkey1 >> 25]
390 | key_perm_maskl[5][(rawkey1 >> 17) & 0x7f]
391 | key_perm_maskl[6][(rawkey1 >> 9) & 0x7f]
392 | key_perm_maskl[7][(rawkey1 >> 1) & 0x7f];
393 k1 = key_perm_maskr[0][rawkey0 >> 25]
394 | key_perm_maskr[1][(rawkey0 >> 17) & 0x7f]
395 | key_perm_maskr[2][(rawkey0 >> 9) & 0x7f]
396 | key_perm_maskr[3][(rawkey0 >> 1) & 0x7f]
397 | key_perm_maskr[4][rawkey1 >> 25]
398 | key_perm_maskr[5][(rawkey1 >> 17) & 0x7f]
399 | key_perm_maskr[6][(rawkey1 >> 9) & 0x7f]
400 | key_perm_maskr[7][(rawkey1 >> 1) & 0x7f];
401 /*
402 * Rotate subkeys and do compression permutation.
403 */
404 shifts = 0;
405 for (round = 0; round < 16; round++) {
406 u_int32_t t0, t1;
407
408 shifts += key_shifts[round];
409
410 t0 = (k0 << shifts) | (k0 >> (28 - shifts));
411 t1 = (k1 << shifts) | (k1 >> (28 - shifts));
412
413 de_keysl[15 - round] =
414 en_keysl[round] = comp_maskl[0][(t0 >> 21) & 0x7f]
415 | comp_maskl[1][(t0 >> 14) & 0x7f]
416 | comp_maskl[2][(t0 >> 7) & 0x7f]
417 | comp_maskl[3][t0 & 0x7f]
418 | comp_maskl[4][(t1 >> 21) & 0x7f]
419 | comp_maskl[5][(t1 >> 14) & 0x7f]
420 | comp_maskl[6][(t1 >> 7) & 0x7f]
421 | comp_maskl[7][t1 & 0x7f];
422
423 de_keysr[15 - round] =
424 en_keysr[round] = comp_maskr[0][(t0 >> 21) & 0x7f]
425 | comp_maskr[1][(t0 >> 14) & 0x7f]
426 | comp_maskr[2][(t0 >> 7) & 0x7f]
427 | comp_maskr[3][t0 & 0x7f]
428 | comp_maskr[4][(t1 >> 21) & 0x7f]
429 | comp_maskr[5][(t1 >> 14) & 0x7f]
430 | comp_maskr[6][(t1 >> 7) & 0x7f]
431 | comp_maskr[7][t1 & 0x7f];
432 }
433 return(0);
434}
435
436int
437_des_do_des(u_int32_t l_in, u_int32_t r_in, u_int32_t *l_out, u_int32_t *r_out,
438 int count)
439{
440 /*
441 * l_in, r_in, l_out, and r_out are in pseudo-"big-endian" format.
442 */
443 u_int32_t l, r, *kl, *kr, *kl1, *kr1;
444 u_int32_t f, r48l, r48r;
445 int round;
446
447 if (count == 0) {
448 return(1);
449 } else if (count > 0) {
450 /*
451 * Encrypting
452 */
453 kl1 = en_keysl;
454 kr1 = en_keysr;
455 } else {
456 /*
457 * Decrypting
458 */
459 count = -count;
460 kl1 = de_keysl;
461 kr1 = de_keysr;
462 }
463
464 /*
465 * Do initial permutation (IP).
466 */
467 l = ip_maskl[0][l_in >> 24]
468 | ip_maskl[1][(l_in >> 16) & 0xff]
469 | ip_maskl[2][(l_in >> 8) & 0xff]
470 | ip_maskl[3][l_in & 0xff]
471 | ip_maskl[4][r_in >> 24]
472 | ip_maskl[5][(r_in >> 16) & 0xff]
473 | ip_maskl[6][(r_in >> 8) & 0xff]
474 | ip_maskl[7][r_in & 0xff];
475 r = ip_maskr[0][l_in >> 24]
476 | ip_maskr[1][(l_in >> 16) & 0xff]
477 | ip_maskr[2][(l_in >> 8) & 0xff]
478 | ip_maskr[3][l_in & 0xff]
479 | ip_maskr[4][r_in >> 24]
480 | ip_maskr[5][(r_in >> 16) & 0xff]
481 | ip_maskr[6][(r_in >> 8) & 0xff]
482 | ip_maskr[7][r_in & 0xff];
483
484 while (count--) {
485 /*
486 * Do each round.
487 */
488 kl = kl1;
489 kr = kr1;
490 round = 16;
491 while (round--) {
492 /*
493 * Expand R to 48 bits (simulate the E-box).
494 */
495 r48l = ((r & 0x00000001) << 23)
496 | ((r & 0xf8000000) >> 9)
497 | ((r & 0x1f800000) >> 11)
498 | ((r & 0x01f80000) >> 13)
499 | ((r & 0x001f8000) >> 15);
500
501 r48r = ((r & 0x0001f800) << 7)
502 | ((r & 0x00001f80) << 5)
503 | ((r & 0x000001f8) << 3)
504 | ((r & 0x0000001f) << 1)
505 | ((r & 0x80000000) >> 31);
506 /*
507 * Do salting for crypt() and friends, and
508 * XOR with the permuted key.
509 */
510 f = (r48l ^ r48r) & saltbits;
511 r48l ^= f ^ *kl++;
512 r48r ^= f ^ *kr++;
513 /*
514 * Do sbox lookups (which shrink it back to 32 bits)
515 * and do the pbox permutation at the same time.
516 */
517 f = psbox[0][m_sbox[0][r48l >> 12]]
518 | psbox[1][m_sbox[1][r48l & 0xfff]]
519 | psbox[2][m_sbox[2][r48r >> 12]]
520 | psbox[3][m_sbox[3][r48r & 0xfff]];
521 /*
522 * Now that we've permuted things, complete f().
523 */
524 f ^= l;
525 l = r;
526 r = f;
527 }
528 r = l;
529 l = f;
530 }
531 /*
532 * Do final permutation (inverse of IP).
533 */
534 *l_out = fp_maskl[0][l >> 24]
535 | fp_maskl[1][(l >> 16) & 0xff]
536 | fp_maskl[2][(l >> 8) & 0xff]
537 | fp_maskl[3][l & 0xff]
538 | fp_maskl[4][r >> 24]
539 | fp_maskl[5][(r >> 16) & 0xff]
540 | fp_maskl[6][(r >> 8) & 0xff]
541 | fp_maskl[7][r & 0xff];
542 *r_out = fp_maskr[0][l >> 24]
543 | fp_maskr[1][(l >> 16) & 0xff]
544 | fp_maskr[2][(l >> 8) & 0xff]
545 | fp_maskr[3][l & 0xff]
546 | fp_maskr[4][r >> 24]
547 | fp_maskr[5][(r >> 16) & 0xff]
548 | fp_maskr[6][(r >> 8) & 0xff]
549 | fp_maskr[7][r & 0xff];
550 return(0);
551}
552
553int
554des_cipher(const char *in, char *out, int32_t salt, int count)
555{
556 u_int32_t l_out, r_out, rawl, rawr;
557 u_int32_t x[2];
558 int retval;
559
560 if (!_des_initialised)
561 _des_init();
562
563 _des_setup_salt(salt);
564
565 memcpy(x, in, sizeof x);
566 rawl = ntohl(x[0]);
567 rawr = ntohl(x[1]);
568 retval = _des_do_des(rawl, rawr, &l_out, &r_out, count);
569
570 x[0] = htonl(l_out);
571 x[1] = htonl(r_out);
572 memcpy(out, x, sizeof x);
573 return(retval);
574}
575
576char *
577crypt(const char *key, const char *setting)
578{
579 int i;
580 u_int32_t count, salt, l, r0, r1, keybuf[2];
581 u_char *p, *q;
582 static u_char output[21];
583 extern char *md5crypt(const char *, const char *);
584 extern char *bcrypt(const char *, const char *);
585
586 if (setting[0] == '$') {
587 switch (setting[1]) {
588 case '1':
589 return (md5crypt(key, setting));
590 default:
591 return bcrypt(key, setting);
592 }
593 }
594
595 if (!_des_initialised)
596 _des_init();
597
598 /*
599 * Copy the key, shifting each character up by one bit
600 * and padding with zeros.
601 */
602 q = (u_char *) keybuf;
603 while ((q - (u_char *) keybuf) < sizeof(keybuf)) {
604 if ((*q++ = *key << 1))
605 key++;
606 }
607 if (des_setkey((u_char *) keybuf))
608 return(NULL);
609
610 if (*setting == _PASSWORD_EFMT1) {
611 /*
612 * "new"-style:
613 * setting - underscore, 4 bytes of count, 4 bytes of salt
614 * key - unlimited characters
615 */
616 for (i = 1, count = 0; i < 5; i++)
617 count |= ascii_to_bin(setting[i]) << (i - 1) * 6;
618
619 for (i = 5, salt = 0; i < 9; i++)
620 salt |= ascii_to_bin(setting[i]) << (i - 5) * 6;
621
622 while (*key) {
623 /*
624 * Encrypt the key with itself.
625 */
626 if (des_cipher((u_char*)keybuf, (u_char*)keybuf, 0, 1))
627 return(NULL);
628 /*
629 * And XOR with the next 8 characters of the key.
630 */
631 q = (u_char *) keybuf;
632 while (((q - (u_char *) keybuf) < sizeof(keybuf)) &&
633 *key)
634 *q++ ^= *key++ << 1;
635
636 if (des_setkey((u_char *) keybuf))
637 return(NULL);
638 }
639 strlcpy((char *)output, setting, 10);
640
641 /*
642 * Double check that we weren't given a short setting.
643 * If we were, the above code will probably have created
644 * weird values for count and salt, but we don't really care.
645 * Just make sure the output string doesn't have an extra
646 * NUL in it.
647 */
648 p = output + strlen((const char *)output);
649 } else {
650 /*
651 * "old"-style:
652 * setting - 2 bytes of salt
653 * key - up to 8 characters
654 */
655 count = 25;
656
657 salt = (ascii_to_bin(setting[1]) << 6)
658 | ascii_to_bin(setting[0]);
659
660 output[0] = setting[0];
661 /*
662 * If the encrypted password that the salt was extracted from
663 * is only 1 character long, the salt will be corrupted. We
664 * need to ensure that the output string doesn't have an extra
665 * NUL in it!
666 */
667 output[1] = setting[1] ? setting[1] : output[0];
668
669 p = output + 2;
670 }
671 _des_setup_salt(salt);
672
673 /*
674 * Do it.
675 */
676 if (_des_do_des(0, 0, &r0, &r1, count))
677 return(NULL);
678 /*
679 * Now encode the result...
680 */
681 l = (r0 >> 8);
682 *p++ = ascii64[(l >> 18) & 0x3f];
683 *p++ = ascii64[(l >> 12) & 0x3f];
684 *p++ = ascii64[(l >> 6) & 0x3f];
685 *p++ = ascii64[l & 0x3f];
686
687 l = (r0 << 16) | ((r1 >> 16) & 0xffff);
688 *p++ = ascii64[(l >> 18) & 0x3f];
689 *p++ = ascii64[(l >> 12) & 0x3f];
690 *p++ = ascii64[(l >> 6) & 0x3f];
691 *p++ = ascii64[l & 0x3f];
692
693 l = r1 << 2;
694 *p++ = ascii64[(l >> 12) & 0x3f];
695 *p++ = ascii64[(l >> 6) & 0x3f];
696 *p++ = ascii64[l & 0x3f];
697 *p = 0;
698
699 return((char *)output);
700}
diff --git a/src/lib/libc/crypt/crypt2.c b/src/lib/libc/crypt/crypt2.c
new file mode 100644
index 0000000000..0c93c12044
--- /dev/null
+++ b/src/lib/libc/crypt/crypt2.c
@@ -0,0 +1,108 @@
1/* $OpenBSD: crypt2.c,v 1.1 2003/08/12 01:22:17 deraadt 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
49#if defined(LIBC_SCCS) && !defined(lint)
50static char rcsid[] = "$OpenBSD: crypt2.c,v 1.1 2003/08/12 01:22:17 deraadt Exp $";
51#endif /* LIBC_SCCS and not lint */
52
53#include <sys/types.h>
54#include <sys/param.h>
55#include <pwd.h>
56#include <unistd.h>
57#include <string.h>
58
59#ifdef DEBUG
60# include <stdio.h>
61#endif
62
63extern const u_char _des_bits8[8];
64extern const u_int32_t _des_bits32[32];
65extern int _des_initialised;
66
67int
68setkey(const char *key)
69{
70 int i, j;
71 u_int32_t packed_keys[2];
72 u_char *p;
73
74 p = (u_char *) packed_keys;
75
76 for (i = 0; i < 8; i++) {
77 p[i] = 0;
78 for (j = 0; j < 8; j++)
79 if (*key++ & 1)
80 p[i] |= _des_bits8[j];
81 }
82 return(des_setkey(p));
83}
84
85int
86encrypt(char *block, int flag)
87{
88 u_int32_t io[2];
89 u_char *p;
90 int i, j, retval;
91
92 if (!_des_initialised)
93 _des_init();
94
95 _des_setup_salt(0);
96 p = (u_char *)block;
97 for (i = 0; i < 2; i++) {
98 io[i] = 0L;
99 for (j = 0; j < 32; j++)
100 if (*p++ & 1)
101 io[i] |= _des_bits32[j];
102 }
103 retval = _des_do_des(io[0], io[1], io, io + 1, flag ? -1 : 1);
104 for (i = 0; i < 2; i++)
105 for (j = 0; j < 32; j++)
106 block[(i << 5) | j] = (io[i] & _des_bits32[j]) ? 1 : 0;
107 return(retval);
108}
diff --git a/src/lib/libc/crypt/md5crypt.c b/src/lib/libc/crypt/md5crypt.c
new file mode 100644
index 0000000000..97717e68d5
--- /dev/null
+++ b/src/lib/libc/crypt/md5crypt.c
@@ -0,0 +1,153 @@
1/* $OpenBSD: md5crypt.c,v 1.13 2003/08/07 00:30:21 deraadt 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.13 2003/08/07 00:30:21 deraadt 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(char *s, u_int32_t v, int n)
32{
33 while (--n >= 0) {
34 *s++ = itoa64[v&0x3f];
35 v >>= 6;
36 }
37}
38
39/*
40 * UNIX password
41 *
42 * Use MD5 for what it is best at...
43 */
44
45char *md5crypt(const char *pw, const char *salt);
46
47char *
48md5crypt(const char *pw, const char *salt)
49{
50 /*
51 * This string is magic for this algorithm. Having
52 * it this way, we can get get better later on
53 */
54 static unsigned char *magic = (unsigned char *)"$1$";
55
56 static char passwd[120], *p;
57 static const unsigned char *sp,*ep;
58 unsigned char final[16];
59 int sl,pl,i;
60 MD5_CTX ctx,ctx1;
61 u_int32_t l;
62
63 /* Refine the Salt first */
64 sp = (const unsigned char *)salt;
65
66 /* If it starts with the magic string, then skip that */
67 if(!strncmp((const char *)sp,(const char *)magic,strlen((const char *)magic)))
68 sp += strlen((const char *)magic);
69
70 /* It stops at the first '$', max 8 chars */
71 for(ep=sp;*ep && *ep != '$' && ep < (sp+8);ep++)
72 continue;
73
74 /* get the length of the true salt */
75 sl = ep - sp;
76
77 MD5Init(&ctx);
78
79 /* The password first, since that is what is most unknown */
80 MD5Update(&ctx,(const unsigned char *)pw,strlen(pw));
81
82 /* Then our magic string */
83 MD5Update(&ctx,magic,strlen((const char *)magic));
84
85 /* Then the raw salt */
86 MD5Update(&ctx,sp,sl);
87
88 /* Then just as many characters of the MD5(pw,salt,pw) */
89 MD5Init(&ctx1);
90 MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw));
91 MD5Update(&ctx1,sp,sl);
92 MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw));
93 MD5Final(final,&ctx1);
94 for(pl = strlen(pw); pl > 0; pl -= 16)
95 MD5Update(&ctx,final,pl>16 ? 16 : pl);
96
97 /* Don't leave anything around in vm they could use. */
98 memset(final,0,sizeof final);
99
100 /* Then something really weird... */
101 for (i = strlen(pw); i ; i >>= 1)
102 if(i&1)
103 MD5Update(&ctx, final, 1);
104 else
105 MD5Update(&ctx, (const unsigned char *)pw, 1);
106
107 /* Now make the output string */
108 snprintf(passwd, sizeof(passwd), "%s%.*s$", (char *)magic,
109 sl, (const char *)sp);
110
111 MD5Final(final,&ctx);
112
113 /*
114 * and now, just to make sure things don't run too fast
115 * On a 60 Mhz Pentium this takes 34 msec, so you would
116 * need 30 seconds to build a 1000 entry dictionary...
117 */
118 for(i=0;i<1000;i++) {
119 MD5Init(&ctx1);
120 if(i & 1)
121 MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw));
122 else
123 MD5Update(&ctx1,final,16);
124
125 if(i % 3)
126 MD5Update(&ctx1,sp,sl);
127
128 if(i % 7)
129 MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw));
130
131 if(i & 1)
132 MD5Update(&ctx1,final,16);
133 else
134 MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw));
135 MD5Final(final,&ctx1);
136 }
137
138 p = passwd + strlen(passwd);
139
140 l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; to64(p,l,4); p += 4;
141 l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; to64(p,l,4); p += 4;
142 l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; to64(p,l,4); p += 4;
143 l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; to64(p,l,4); p += 4;
144 l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; to64(p,l,4); p += 4;
145 l = final[11] ; to64(p,l,2); p += 2;
146 *p = '\0';
147
148 /* Don't leave anything around in vm they could use. */
149 memset(final, 0, sizeof final);
150
151 return passwd;
152}
153
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
index 803657e006..4a51f15ddf 100644
--- a/src/lib/libc/include/namespace.h
+++ b/src/lib/libc/include/namespace.h
@@ -1,4 +1,4 @@
1/* $NetBSD: namespace.h,v 1.2 1995/02/27 13:02:12 cgd Exp $ */ 1/* $OpenBSD: namespace.h,v 1.2 1996/08/19 08:28:08 tholo Exp $ */
2 2
3#define catclose _catclose 3#define catclose _catclose
4#define catgets _catgets 4#define catgets _catgets
diff --git a/src/lib/libc/include/thread_private.h b/src/lib/libc/include/thread_private.h
new file mode 100644
index 0000000000..4212e7dcb2
--- /dev/null
+++ b/src/lib/libc/include/thread_private.h
@@ -0,0 +1,134 @@
1/* $OpenBSD: thread_private.h,v 1.15 2003/01/28 04:58:00 marc 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#define WEAK_NAME(name) __CONCAT(_weak_,name)
23#define WEAK_ALIAS(name) __weak_alias(name, WEAK_NAME(name))
24#ifdef __GNUC__
25#define WEAK_PROTOTYPE(name) __typeof__(name) WEAK_NAME(name)
26#else
27#define WEAK_PROTOTYPE(name) /* typeof() only in gcc */
28#endif
29
30/*
31 * These macros help in making persistent storage thread-specific.
32 * Libc makes extensive use of private static data structures
33 * that hold state across function invocation, and these macros
34 * are no-ops when running single-threaded.
35 *
36 * Linking against the user-thread library causes these macros to
37 * allocate storage on a per-thread basis.
38 */
39
40#define __THREAD_MUTEX_NAME(name) __CONCAT(_libc_storage_mutex_,name)
41#define __THREAD_KEY_NAME(name) __CONCAT(_libc_storage_key_,name)
42
43struct _thread_private_key_struct {
44 pthread_once_t once;
45 void (*cleanfn)(void *);
46 pthread_key_t key;
47};
48
49void _libc_private_storage_lock(pthread_mutex_t *);
50void _libc_private_storage_unlock(pthread_mutex_t *);
51void * _libc_private_storage(volatile struct _thread_private_key_struct *,
52 void *, size_t, void *);
53
54/* Declare a module mutex. */
55#define _THREAD_PRIVATE_MUTEX(name) \
56 static pthread_mutex_t __THREAD_MUTEX_NAME(name) = \
57 PTHREAD_MUTEX_INITIALIZER
58
59/* Lock a module mutex against use by any other threads. */
60#define _THREAD_PRIVATE_MUTEX_LOCK(name) \
61 _libc_private_storage_lock(&__THREAD_MUTEX_NAME(name))
62
63/* Unlock a module mutex. */
64#define _THREAD_PRIVATE_MUTEX_UNLOCK(name) \
65 _libc_private_storage_unlock(&__THREAD_MUTEX_NAME(name))
66
67/* Declare a thread-private storage key. */
68#define _THREAD_PRIVATE_KEY(name) \
69 static volatile struct _thread_private_key_struct \
70 __THREAD_KEY_NAME(name) = { \
71 PTHREAD_ONCE_INIT, \
72 0 \
73 }
74
75/*
76 * In threaded mode, return a pointer to thread-private memory of
77 * the same size as, and (initially) with the same contents as 'storage'. If
78 * an error occurs, the 'error' parameter is returned.
79 * In single-threaded mode, no storage is allocated. Instead, a pointer
80 * to storage is always returned.
81 * The 'cleanfn' function of the key structure is called to free the storage.
82 * If 'cleanfn' is NULL, then free() is used. This hook can be useful for
83 * getting rid of memory leaks.
84 */
85#define _THREAD_PRIVATE(keyname, storage, error) \
86 _libc_private_storage(&__THREAD_KEY_NAME(keyname), \
87 &(storage), sizeof (storage), error)
88
89/*
90 * Keys used to access the per thread instances of resolver global data.
91 * These are not static as they are referenced in several places.
92 */
93extern volatile struct _thread_private_key_struct __THREAD_KEY_NAME(_res);
94#ifdef INET6
95extern volatile struct _thread_private_key_struct __THREAD_KEY_NAME(_res_ext);
96#endif
97
98/*
99 * File descriptor locking definitions.
100 */
101#define FD_READ 0x1
102#define FD_WRITE 0x2
103#define FD_RDWR (FD_READ | FD_WRITE)
104
105#define _FD_LOCK(_fd,_type,_ts) \
106 _thread_fd_lock(_fd, _type, _ts, __FILE__, __LINE__)
107#define _FD_UNLOCK(_fd,_type) \
108 _thread_fd_unlock(_fd, _type, __FILE__, __LINE__)
109
110int _thread_fd_lock(int, int, struct timespec *, const char *, int);
111void _thread_fd_unlock(int, int, const char *, int);
112
113/*
114 * malloc lock/unlock definitions
115 */
116# define _MALLOC_LOCK() do { \
117 if (__isthreaded) \
118 _thread_malloc_lock(); \
119 } while (0)
120# define _MALLOC_UNLOCK() do { \
121 if (__isthreaded) \
122 _thread_malloc_unlock();\
123 } while (0)
124# define _MALLOC_LOCK_INIT()do { \
125 if (__isthreaded) \
126 _thread_malloc_init();\
127 } while (0)
128
129
130void _thread_malloc_init(void);
131void _thread_malloc_lock(void);
132void _thread_malloc_unlock(void);
133
134#endif /* _THREAD_PRIVATE_H_ */
diff --git a/src/lib/libc/net/Makefile.inc b/src/lib/libc/net/Makefile.inc
index 2d220067e4..81348fa0ff 100644
--- a/src/lib/libc/net/Makefile.inc
+++ b/src/lib/libc/net/Makefile.inc
@@ -1,46 +1,87 @@
1# $NetBSD: Makefile.inc,v 1.23 1995/03/02 09:09:07 chopps Exp $ 1# $OpenBSD: Makefile.inc,v 1.32 2004/02/10 18:11:58 jmc Exp $
2# @(#)Makefile.inc 8.2 (Berkeley) 9/5/93
3 2
4# net sources 3# net sources
5.PATH: ${.CURDIR}/arch/${MACHINE_ARCH}/net ${.CURDIR}/net 4.PATH: ${LIBCSRCDIR}/arch/${MACHINE_ARCH}/net ${LIBCSRCDIR}/net
6 5
7SRCS+= gethostnamadr.c getnetbyaddr.c getnetbyname.c getnetent.c \ 6CFLAGS+=-DRESOLVSORT
8 getproto.c getprotoent.c getprotoname.c getservbyname.c \ 7
9 getservbyport.c getservent.c herror.c inet_addr.c inet_lnaof.c \ 8SRCS+= base64.c freeaddrinfo.c gai_strerror.c getaddrinfo.c gethostnamadr.c \
10 inet_makeaddr.c inet_netof.c inet_network.c inet_ntoa.c \ 9 getifaddrs.c getnameinfo.c getnetbyaddr.c getnetbyname.c getnetent.c \
11 iso_addr.c linkaddr.c ns_addr.c ns_ntoa.c rcmd.c recv.c res_comp.c \ 10 getnetnamadr.c getproto.c getprotoent.c getprotoname.c \
12 res_debug.c res_init.c res_mkquery.c res_query.c res_send.c \ 11 getservbyname.c getservbyport.c getservent.c getrrsetbyname.c \
13 send.c sethostent.c ethers.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
14 24
15# machine-dependent net sources 25# machine-dependent net sources
16# m-d Makefile.inc must include sources for: 26# m-d Makefile.inc must include sources for:
17# htonl() htons() ntohl() ntohs() 27# htonl() htons() ntohl() ntohs()
18 28
19.include "${.CURDIR}/arch/${MACHINE_ARCH}/net/Makefile.inc" 29.include "${LIBCSRCDIR}/arch/${MACHINE_ARCH}/net/Makefile.inc"
20 30
21MAN+= byteorder.3 gethostbyname.3 getnetent.3 getprotoent.3 getservent.3 \ 31MAN+= byteorder.3 ethers.3 getaddrinfo.3 gethostbyname.3 getifaddrs.3 \
22 inet.3 linkaddr.3 ns.3 rcmd.3 resolver.3 ethers.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
23 37
24MLINKS+=byteorder.3 htonl.3 byteorder.3 htons.3 byteorder.3 ntohl.3 \ 38MLINKS+=byteorder.3 htonl.3 byteorder.3 htons.3 byteorder.3 ntohl.3 \
25 byteorder.3 ntohs.3 39 byteorder.3 ntohs.3 byteorder.3 htobe16.3 byteorder.3 htobe32.3 \
40 byteorder.3 htobe64.3 byteorder.3 betoh16.3 byteorder.3 betoh32.3 \
41 byteorder.3 betoh64.3 byteorder.3 htole16.3 byteorder.3 htole32.3 \
42 byteorder.3 htole64.3 byteorder.3 letoh16.3 byteorder.3 letoh32.3 \
43 byteorder.3 letoh64.3 byteorder.3 swap16.3 byteorder.3 swap32.3 \
44 byteorder.3 swap64.3
26MLINKS+=ethers.3 ether_aton.3 ethers.3 ether_hostton.3 ethers.3 ether_line.3 \ 45MLINKS+=ethers.3 ether_aton.3 ethers.3 ether_hostton.3 ethers.3 ether_line.3 \
27 ethers.3 ether_ntoa.3 ethers.3 ether_ntohost.3 46 ethers.3 ether_ntoa.3 ethers.3 ether_ntohost.3 ethers.3 ether_addr.3
47MLINKS+= getaddrinfo.3 freeaddrinfo.3 getaddrinfo.3 gai_strerror.3
28MLINKS+=gethostbyname.3 endhostent.3 gethostbyname.3 gethostbyaddr.3 \ 48MLINKS+=gethostbyname.3 endhostent.3 gethostbyname.3 gethostbyaddr.3 \
29 gethostbyname.3 sethostent.3 gethostbyname.3 gethostent.3 \ 49 gethostbyname.3 sethostent.3 gethostbyname.3 gethostent.3 \
30 gethostbyname.3 herror.3 50 gethostbyname.3 herror.3 gethostbyname.3 gethostbyname2.3 \
51 gethostbyname.3 hstrerror.3
52MLINKS+=getifaddrs.3 freeifaddrs.3
31MLINKS+=getnetent.3 endnetent.3 getnetent.3 getnetbyaddr.3 \ 53MLINKS+=getnetent.3 endnetent.3 getnetent.3 getnetbyaddr.3 \
32 getnetent.3 getnetbyname.3 getnetent.3 setnetent.3 54 getnetent.3 getnetbyname.3 getnetent.3 setnetent.3
33MLINKS+=getprotoent.3 endprotoent.3 getprotoent.3 getprotobyname.3 \ 55MLINKS+=getprotoent.3 endprotoent.3 getprotoent.3 getprotobyname.3 \
34 getprotoent.3 getprotobynumber.3 getprotoent.3 setprotoent.3 56 getprotoent.3 getprotobynumber.3 getprotoent.3 setprotoent.3
35MLINKS+=getservent.3 endservent.3 getservent.3 getservbyname.3 \ 57MLINKS+=getservent.3 endservent.3 getservent.3 getservbyname.3 \
36 getservent.3 getservbyport.3 getservent.3 setservent.3 58 getservent.3 getservbyport.3 getservent.3 setservent.3
59MLINKS+= if_indextoname.3 if_nametoindex.3 if_indextoname.3 if_nameindex.3 \
60 if_indextoname.3 if_freenameindex.3
37MLINKS+=inet.3 addr.3 inet.3 inet_addr.3 inet.3 inet_aton.3 \ 61MLINKS+=inet.3 addr.3 inet.3 inet_addr.3 inet.3 inet_aton.3 \
38 inet.3 inet_lnaof.3 inet.3 inet_makeaddr.3 inet.3 inet_netof.3 \ 62 inet.3 inet_lnaof.3 inet.3 inet_makeaddr.3 inet.3 inet_netof.3 \
39 inet.3 inet_network.3 inet.3 inet_ntoa.3 inet.3 network.3 \ 63 inet.3 inet_network.3 inet.3 inet_ntoa.3 inet.3 network.3 \
40 inet.3 ntoa.3 64 inet.3 ntoa.3 inet.3 inet_ntop.3 inet.3 inet_pton.3
41MLINKS+=linkaddr.3 linkntoa.3 65MLINKS+=inet_net.3 inet_net_ntop.3 inet_net.3 inet_net_pton.3
66MLINKS+=iso_addr.3 iso_ntoa.3
67MLINKS+=link_addr.3 link_ntoa.3
68MLINKS+=ipx.3 ipx_addr.3 ipx.3 ipx_ntoa.3
42MLINKS+=ns.3 ns_addr.3 ns.3 ns_ntoa.3 69MLINKS+=ns.3 ns_addr.3 ns.3 ns_ntoa.3
43MLINKS+=rcmd.3 iruserok.3 rcmd.3 rresvport.3 rcmd.3 ruserok.3 70MLINKS+=rcmd.3 iruserok.3 rcmd.3 rresvport.3 rcmd.3 ruserok.3 \
71 rcmd.3 rresvport_af.3 rcmd.3 rcmd_af.3 rcmd.3 iruserok_sa.3
44MLINKS+=resolver.3 dn_comp.3 resolver.3 dn_expand.3 resolver.3 res_init.3 \ 72MLINKS+=resolver.3 dn_comp.3 resolver.3 dn_expand.3 resolver.3 res_init.3 \
45 resolver.3 res_mkquery.3 resolver.3 res_send.3 resolver.3 res_query.3 \ 73 resolver.3 res_mkquery.3 resolver.3 res_send.3 resolver.3 res_query.3 \
46 resolver.3 res_search.3 74 resolver.3 res_search.3
75MLINKS+=inet6_option_space.3 inet6_option_init.3 \
76 inet6_option_space.3 inet6_option_append.3 \
77 inet6_option_space.3 inet6_option_alloc.3 \
78 inet6_option_space.3 inet6_option_next.3 \
79 inet6_option_space.3 inet6_option_find.3
80MLINKS+=inet6_rthdr_space.3 inet6_rthdr_init.3 \
81 inet6_rthdr_space.3 inet6_rthdr_add.3 \
82 inet6_rthdr_space.3 inet6_rthdr_lasthop.3 \
83 inet6_rthdr_space.3 inet6_rthdr_reverse.3 \
84 inet6_rthdr_space.3 inet6_rthdr_segments.3 \
85 inet6_rthdr_space.3 inet6_rthdr_getaddr.3 \
86 inet6_rthdr_space.3 inet6_rthdr_getflags.3
87MLINKS+=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
index 701a69f688..54123455c6 100644
--- a/src/lib/libc/net/byteorder.3
+++ b/src/lib/libc/net/byteorder.3
@@ -1,4 +1,4 @@
1.\" $NetBSD: byteorder.3,v 1.3 1995/02/25 06:20:27 cgd Exp $ 1.\" $OpenBSD: byteorder.3,v 1.13 2003/09/26 17:06:50 fgsch Exp $
2.\" 2.\"
3.\" Copyright (c) 1983, 1991, 1993 3.\" Copyright (c) 1983, 1991, 1993
4.\" The Regents of the University of California. All rights reserved. 4.\" The Regents of the University of California. All rights reserved.
@@ -11,11 +11,7 @@
11.\" 2. Redistributions in binary form must reproduce the above copyright 11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the 12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution. 13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software 14.\" 3. Neither the name of the University nor the names of its contributors
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 15.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission. 16.\" without specific prior written permission.
21.\" 17.\"
@@ -31,48 +27,180 @@
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE. 28.\" SUCH DAMAGE.
33.\" 29.\"
34.\" @(#)byteorder.3 8.1 (Berkeley) 6/4/93
35.\"
36.Dd June 4, 1993 30.Dd June 4, 1993
37.Dt BYTEORDER 3 31.Dt BYTEORDER 3
38.Os BSD 4.2 32.Os
39.Sh NAME 33.Sh NAME
40.Nm htonl , 34.Nm htonl ,
41.Nm htons , 35.Nm htons ,
42.Nm ntohl , 36.Nm ntohl ,
43.Nm ntohs 37.Nm ntohs ,
44.Nd convert values between host and network byte order 38.Nm htobe64 ,
39.Nm htobe32 ,
40.Nm htobe16 ,
41.Nm betoh64 ,
42.Nm betoh32 ,
43.Nm betoh16 ,
44.Nm htole64 ,
45.Nm htole32 ,
46.Nm htole16 ,
47.Nm letoh64 ,
48.Nm letoh32 ,
49.Nm letoh16 ,
50.Nm swap64 ,
51.Nm swap32 ,
52.Nm swap16
53.Nd convert values between different byte orderings
45.Sh SYNOPSIS 54.Sh SYNOPSIS
46.Fd #include <sys/param.h> 55.Fd #include <sys/types.h>
47.Ft u_long 56.Ft u_int32_t
48.Fn htonl "u_long hostlong" 57.Fn htonl "u_int32_t host32"
49.Ft u_short 58.Ft u_int16_t
50.Fn htons "u_short hostshort" 59.Fn htons "u_int16_t host16"
51.Ft u_long 60.Ft u_int32_t
52.Fn ntohl "u_long netlong" 61.Fn ntohl "u_int32_t net32"
53.Ft u_short 62.Ft u_int16_t
54.Fn ntohs "u_short netshort" 63.Fn ntohs "u_int16_t net16"
64.Ft u_int64_t
65.Fn htobe64 "u_int64_t host64"
66.Ft u_int32_t
67.Fn htobe32 "u_int32_t host32"
68.Ft u_int16_t
69.Fn htobe16 "u_int16_t host16"
70.Ft u_int64_t
71.Fn betoh64 "u_int64_t big64"
72.Ft u_int32_t
73.Fn betoh32 "u_int32_t big32"
74.Ft u_int16_t
75.Fn betoh16 "u_int16_t big16"
76.Ft u_int64_t
77.Fn htole64 "u_int64_t host64"
78.Ft u_int32_t
79.Fn htole32 "u_int32_t host32"
80.Ft u_int16_t
81.Fn htole16 "u_int16_t host16"
82.Ft u_int64_t
83.Fn letoh64 "u_int64_t little64"
84.Ft u_int32_t
85.Fn letoh32 "u_int32_t little32"
86.Ft u_int16_t
87.Fn letoh16 "u_int16_t little16"
88.Ft u_int64_t
89.Fn swap64 "u_int32_t val64"
90.Ft u_int32_t
91.Fn swap32 "u_int32_t val32"
92.Ft u_int16_t
93.Fn swap16 "u_int16_t val16"
55.Sh DESCRIPTION 94.Sh DESCRIPTION
56These routines convert 16 and 32 bit quantities between network 95These routines convert 16, 32 and 64-bit quantities between different
96byte orderings.
97The
98.Dq swap
99functions reverse the byte ordering of
100the given quantity, the others converts either from/to the native
101byte order used by the host to/from either little- or big-endian (a.k.a
102network) order.
103.Pp
104Apart from the swap functions, the names can be described by this form:
105{src-order}to{dst-order}{size}.
106Both {src-order} and {dst-order} can take the following forms:
107.Pp
108.Bl -tag -width "be " -offset indent -compact
109.It h
110Host order.
111.It n
112Network order (big-endian).
113.It be
114Big-endian (most significant byte first).
115.It le
116Little-endian (least significant byte first).
117.El
118.Pp
119One of the specified orderings must be
120.Sq h .
121{size} will take these forms:
122.Pp
123.Bl -tag -width "32 " -offset indent -compact
124.It l
125Long (32-bit, used in conjunction with forms involving
126.Sq n ) .
127.It s
128Short (16-bit, used in conjunction with forms involving
129.Sq n ) .
130.It 16
13116-bit.
132.It 32
13332-bit.
134.It 64
13564-bit.
136.El
137.Pp
138The swap functions are of the form: swap{size}.
139.Pp
140Names involving
141.Sq n
142convert quantities between network
57byte order and host byte order. 143byte order and host byte order.
144The last letter
145.Pf ( Sq s
146or
147.Sq l )
148is a mnemonic
149for the traditional names for such quantities,
150.Li short
151and
152.Li long ,
153respectively.
154Today, the C concept of
155.Li short
156and
157.Li long
158integers need not coincide with this traditional misunderstanding.
58On machines which have a byte order which is the same as the network 159On machines which have a byte order which is the same as the network
59order, routines are defined as null macros. 160order, routines are defined as null macros.
60.Pp 161.Pp
61These routines are most often used in conjunction with Internet 162The functions involving either
62addresses and ports as returned by 163.Dq be ,
164.Dq le ,
165or
166.Dq swap
167use the numbers
16816, 32 and 64 for specifying the bitwidth of the quantities they operate on.
169Currently all supported architectures are either big- or little-endian
170so either the
171.Dq be
172or
173.Dq le
174variants are implemented as null macros.
175.Pp
176The routines mentioned above which have either {src-order} or {dst-order}
177set to
178.Sq n
179are most often used in
180conjunction with Internet addresses and ports as returned by
63.Xr gethostbyname 3 181.Xr gethostbyname 3
64and 182and
65.Xr getservent 3 . 183.Xr getservent 3 .
66.Sh SEE ALSO 184.Sh SEE ALSO
67.Xr gethostbyname 3 , 185.Xr gethostbyname 3 ,
68.Xr getservent 3 186.Xr getservent 3
187.Sh STANDARDS
188The
189.Fn htonl ,
190.Fn htons ,
191.Fn ntohl ,
192and
193.Fn ntohs
194functions conform to
195.St -p1003.1 .
196The other functions are extensions that should not be used when portability
197is required.
69.Sh HISTORY 198.Sh HISTORY
70The 199The
71.Nm byteorder 200.Nm byteorder
72functions appeared in 201functions appeared in
73.Bx 4.2 . 202.Bx 4.2 .
74.Sh BUGS 203.Sh BUGS
75On the 204On the vax, alpha, i386, and some mips architectures,
76.Tn VAX 205bytes are handled backwards from most everyone else in the world.
77bytes are handled backwards from most everyone else in 206This is not expected to be fixed in the near future.
78the world. This 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
index 81e6c65935..0509c121b8 100644
--- a/src/lib/libc/net/ethers.3
+++ b/src/lib/libc/net/ethers.3
@@ -1,15 +1,17 @@
1.\" $OpenBSD: ethers.3,v 1.14 2001/08/06 10:42:26 mpech Exp $
1.\" 2.\"
2.\" Written by roland@frob.com. Public domain. 3.\" Written by roland@frob.com. Public domain.
3.\" 4.\"
4.Dd December 16, 1993 5.Dd December 16, 1993
5.Dt ETHERS 3 6.Dt ETHERS 3
6.Os NetBSD 7.Os
7.Sh NAME 8.Sh NAME
9.Nm ether_aton ,
8.Nm ether_ntoa , 10.Nm ether_ntoa ,
9.Nm ether_addr , 11.Nm ether_addr ,
10.Nm ether_ntohost , 12.Nm ether_ntohost ,
11.Nm ether_hostton , 13.Nm ether_hostton ,
12.Nm ether_line , 14.Nm ether_line
13.Nd get ethers entry 15.Nd get ethers entry
14.Sh SYNOPSIS 16.Sh SYNOPSIS
15.Fd #include <netinet/if_ether.h> 17.Fd #include <netinet/if_ether.h>
@@ -17,49 +19,64 @@
17.Fn ether_ntoa "struct ether_addr *e" 19.Fn ether_ntoa "struct ether_addr *e"
18.Ft struct ether_addr * 20.Ft struct ether_addr *
19.Fn ether_aton "char *s" 21.Fn ether_aton "char *s"
22.Ft int
20.Fn ether_ntohost "char *hostname" "struct ether_addr *e" 23.Fn ether_ntohost "char *hostname" "struct ether_addr *e"
24.Ft int
21.Fn ether_hostton "char *hostname" "struct ether_addr *e" 25.Fn ether_hostton "char *hostname" "struct ether_addr *e"
26.Ft int
22.Fn ether_line "char *l" "struct ether_addr *e" "char *hostname" 27.Fn ether_line "char *l" "struct ether_addr *e" "char *hostname"
23.Sh DESCRIPTION 28.Sh DESCRIPTION
24Ethernet addresses are represented by the 29Ethernet addresses are represented by the
25following structure: 30following structure:
26.Bd -literal -offset indent 31.Bd -literal -offset indent
27struct ether_addr { 32struct ether_addr {
28 u_char ether_addr_octet[6]; 33 u_int8_t ether_addr_octet[6];
29}; 34};
30.Ed 35.Ed
31.Pp 36.Pp
32The 37The
33.Fn ether_ntoa 38.Fn ether_ntoa
34function converts this structure into an ASCII string of the form 39function converts this structure into an
35``xx:xx:xx:xx:xx:xx'', consisting of 6 hexadecimal numbers separated 40.Tn ASCII
36by colons. It returns a pointer to a static buffer that is reused for 41string of the form
37each call. 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.
38The 46The
39.Fn ether_aton 47.Fn ether_aton
40converts an ASCII string of the same form and to a structure 48converts an
41containing the 6 octets of the address. It returns a pointer to a 49.Tn ASCII
42static structure that is reused for each call. 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.
43.Pp 53.Pp
44The 54The
45.Fn ether_ntohost 55.Fn ether_ntohost
46and 56and
47.Fn ether_hostton 57.Fn ether_hostton
48functions interrogate the data base mapping host names to Ethernet 58functions interrogate the database mapping host names to Ethernet
49addresses, 59addresses,
50.Pa /etc/ethers . 60.Pa /etc/ethers .
51The 61The
52.Fn ether_ntohost 62.Fn ether_ntohost
53function looks up the given Ethernet address and writes the associated 63function looks up the given Ethernet address and writes the associated
54host name into the character buffer passed. 64host name into the character buffer passed.
65This buffer should be
66.Dv MAXHOSTNAMELEN
67characters in size.
55The 68The
56.Fn ether_hostton 69.Fn ether_hostton
57function looks up the given host name and writes the associated 70function looks up the given host name and writes the associated
58Ethernet address into the structure passed. Both functions return 71Ethernet address into the structure passed.
59zero if they find the requested host name or address, and -1 if not. 72Both functions return
73zero if they find the requested host name or address, and \-1 if not.
74.Pp
60Each call reads 75Each call reads
61.Pa /etc/ethers 76.Pa /etc/ethers
62from the beginning; if a + appears alone on a line in the file, then 77from the beginning; if a
78.Ql +
79appears alone on a line in the file, then
63.Fn ether_hostton 80.Fn ether_hostton
64will consult the 81will consult the
65.Pa ethers.byname 82.Pa ethers.byname
@@ -73,9 +90,13 @@ The
73.Fn ether_line 90.Fn ether_line
74function parses a line from the 91function parses a line from the
75.Pa /etc/ethers 92.Pa /etc/ethers
76file and fills in the passed ``struct ether_addr'' and character 93file and fills in the passed
77buffer with the Ethernet address and host name on the line. It 94.Li struct ether_addr
78returns zero if the line was successfully parsed and -1 if not. 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.
79.Sh FILES 100.Sh FILES
80.Bl -tag -width /etc/ethers -compact 101.Bl -tag -width /etc/ethers -compact
81.It Pa /etc/ethers 102.It Pa /etc/ethers
@@ -91,12 +112,8 @@ The
91and 112and
92.Fn ether_line 113.Fn ether_line
93functions were adopted from SunOS and appeared in 114functions were adopted from SunOS and appeared in
94NetBSD 0.9b. 115.Nx 0.9 b.
95.Sh BUGS 116.Sh BUGS
96The data space used by these functions is static; if future use 117The data space used by these functions is static; if future use
97requires the data, it should be copied before any subsequent calls to 118requires the data, it should be copied before any subsequent calls to
98these functions overwrite it. There is no way to restrict how many 119these functions overwrite it.
99character will be written into the host name buffer passed. A very
100long line in
101.Pa /etc/ethers
102could overflow your buffer.
diff --git a/src/lib/libc/net/ethers.c b/src/lib/libc/net/ethers.c
index 0f32b9b71b..2c1e562245 100644
--- a/src/lib/libc/net/ethers.c
+++ b/src/lib/libc/net/ethers.c
@@ -1,12 +1,31 @@
1/* $NetBSD: ethers.c,v 1.5 1995/02/25 06:20:28 cgd Exp $ */ 1/* $OpenBSD: ethers.c,v 1.17 2004/02/16 19:41:12 otto Exp $ */
2 2
3/* 3/*
4 * ethers(3N) a la Sun. 4 * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
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.
5 * 9 *
6 * Written by Roland McGrath <roland@frob.com> 10/14/93. 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
7 * Public domain. 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
8 */ 17 */
9 18
19/*
20 * ethers(3) a la Sun.
21 * Originally Written by Roland McGrath <roland@frob.com> 10/14/93.
22 * Substantially modified by Todd C. Miller <Todd.Miller@courtesan.com>
23 */
24
25#if defined(LIBC_SCCS) && !defined(lint)
26static char rcsid[] = "$OpenBSD: ethers.c,v 1.17 2004/02/16 19:41:12 otto Exp $";
27#endif /* LIBC_SCCS and not lint */
28
10#include <sys/types.h> 29#include <sys/types.h>
11#include <sys/socket.h> 30#include <sys/socket.h>
12#include <net/if.h> 31#include <net/if.h>
@@ -18,22 +37,56 @@
18#include <stdio.h> 37#include <stdio.h>
19#include <stdlib.h> 38#include <stdlib.h>
20#include <string.h> 39#include <string.h>
40#include <ctype.h>
41#ifdef YP
42#include <rpcsvc/ypclnt.h>
43#endif
21 44
22#ifndef _PATH_ETHERS 45#ifndef _PATH_ETHERS
23#define _PATH_ETHERS "/etc/ethers" 46#define _PATH_ETHERS "/etc/ethers"
24#endif 47#endif
25 48
49static char * _ether_aton(char *, struct ether_addr *);
50
26char * 51char *
27ether_ntoa(e) 52ether_ntoa(e)
28 struct ether_addr *e; 53 struct ether_addr *e;
29{ 54{
30 static char a[] = "xx:xx:xx:xx:xx:xx"; 55 static char a[] = "xx:xx:xx:xx:xx:xx";
31 56
32 sprintf(a, "%02x:%02x:%02x:%02x:%02x:%02x", 57 (void)snprintf(a, sizeof a, "%02x:%02x:%02x:%02x:%02x:%02x",
33 e->ether_addr_octet[0], e->ether_addr_octet[1], 58 e->ether_addr_octet[0], e->ether_addr_octet[1],
34 e->ether_addr_octet[2], e->ether_addr_octet[3], 59 e->ether_addr_octet[2], e->ether_addr_octet[3],
35 e->ether_addr_octet[4], e->ether_addr_octet[5]); 60 e->ether_addr_octet[4], e->ether_addr_octet[5]);
36 return a; 61
62 return (a);
63}
64
65static char *
66_ether_aton(s, e)
67 char *s;
68 struct ether_addr *e;
69{
70 int i;
71 long l;
72 char *pp;
73
74 while (isspace(*s))
75 s++;
76
77 /* expect 6 hex octets separated by ':' or space/NUL if last octet */
78 for (i = 0; i < 6; i++) {
79 l = strtol(s, &pp, 16);
80 if (pp == s || l > 0xFF || l < 0)
81 return (NULL);
82 if (!(*pp == ':' || (i == 5 && (isspace(*pp) || *pp == '\0'))))
83 return (NULL);
84 e->ether_addr_octet[i] = (u_char)l;
85 s = pp + 1;
86 }
87
88 /* return character after the octets ala strtol(3) */
89 return (pp);
37} 90}
38 91
39struct ether_addr * 92struct ether_addr *
@@ -41,34 +94,26 @@ ether_aton(s)
41 char *s; 94 char *s;
42{ 95{
43 static struct ether_addr n; 96 static struct ether_addr n;
44 u_int i[6]; 97
45 98 return (_ether_aton(s, &n) ? &n : NULL);
46 if (sscanf(s, " %x:%x:%x:%x:%x:%x ", &i[0], &i[1],
47 &i[2], &i[3], &i[4], &i[5]) == 6) {
48 n.ether_addr_octet[0] = (u_char)i[0];
49 n.ether_addr_octet[1] = (u_char)i[1];
50 n.ether_addr_octet[2] = (u_char)i[2];
51 n.ether_addr_octet[3] = (u_char)i[3];
52 n.ether_addr_octet[4] = (u_char)i[4];
53 n.ether_addr_octet[5] = (u_char)i[5];
54 return &n;
55 }
56 return NULL;
57} 99}
58 100
101int
59ether_ntohost(hostname, e) 102ether_ntohost(hostname, e)
60 char *hostname; 103 char *hostname;
61 struct ether_addr *e; 104 struct ether_addr *e;
62{ 105{
63 FILE *f; 106 FILE *f;
64 char buf[BUFSIZ]; 107 char buf[BUFSIZ+1], *p;
108 size_t len;
65 struct ether_addr try; 109 struct ether_addr try;
66
67#ifdef YP 110#ifdef YP
68 char trybuf[sizeof "xx:xx:xx:xx:xx:xx"]; 111 char trybuf[sizeof("xx:xx:xx:xx:xx:xx")];
69 int trylen; 112 int trylen;
113#endif
70 114
71 sprintf(trybuf, "%x:%x:%x:%x:%x:%x", 115#ifdef YP
116 snprintf(trybuf, sizeof trybuf, "%x:%x:%x:%x:%x:%x",
72 e->ether_addr_octet[0], e->ether_addr_octet[1], 117 e->ether_addr_octet[0], e->ether_addr_octet[1],
73 e->ether_addr_octet[2], e->ether_addr_octet[3], 118 e->ether_addr_octet[2], e->ether_addr_octet[3],
74 e->ether_addr_octet[4], e->ether_addr_octet[5]); 119 e->ether_addr_octet[4], e->ether_addr_octet[5]);
@@ -76,12 +121,19 @@ ether_ntohost(hostname, e)
76#endif 121#endif
77 122
78 f = fopen(_PATH_ETHERS, "r"); 123 f = fopen(_PATH_ETHERS, "r");
79 if (f==NULL) 124 if (f == NULL)
80 return -1; 125 return (-1);
81 while (fgets(buf, sizeof buf, f)) { 126 while ((p = fgetln(f, &len)) != NULL) {
127 if (p[len-1] == '\n')
128 len--;
129 if (len > sizeof(buf) - 2)
130 continue;
131 (void)memcpy(buf, p, len);
132 buf[len] = '\n'; /* code assumes newlines later on */
133 buf[len+1] = '\0';
82#ifdef YP 134#ifdef YP
83 /* A + in the file means try YP now. */ 135 /* A + in the file means try YP now. */
84 if (!strncmp(buf, "+\n", sizeof buf)) { 136 if (!strncmp(buf, "+\n", sizeof(buf))) {
85 char *ypbuf, *ypdom; 137 char *ypbuf, *ypdom;
86 int ypbuflen; 138 int ypbuflen;
87 139
@@ -93,42 +145,51 @@ ether_ntohost(hostname, e)
93 if (ether_line(ypbuf, &try, hostname) == 0) { 145 if (ether_line(ypbuf, &try, hostname) == 0) {
94 free(ypbuf); 146 free(ypbuf);
95 (void)fclose(f); 147 (void)fclose(f);
96 return 0; 148 return (0);
97 } 149 }
98 free(ypbuf); 150 free(ypbuf);
99 continue; 151 continue;
100 } 152 }
101#endif 153#endif
102 if (ether_line(buf, &try, hostname) == 0 && 154 if (ether_line(buf, &try, hostname) == 0 &&
103 bcmp((char *)&try, (char *)e, sizeof try) == 0) { 155 memcmp((void *)&try, (void *)e, sizeof(try)) == 0) {
104 (void)fclose(f); 156 (void)fclose(f);
105 return 0; 157 return (0);
106 } 158 }
107 } 159 }
108 (void)fclose(f); 160 (void)fclose(f);
109 errno = ENOENT; 161 errno = ENOENT;
110 return -1; 162 return (-1);
111} 163}
112 164
165int
113ether_hostton(hostname, e) 166ether_hostton(hostname, e)
114 char *hostname; 167 char *hostname;
115 struct ether_addr *e; 168 struct ether_addr *e;
116{ 169{
117 FILE *f; 170 FILE *f;
118 char buf[BUFSIZ]; 171 char buf[BUFSIZ+1], *p;
119 char try[MAXHOSTNAMELEN]; 172 char try[MAXHOSTNAMELEN];
173 size_t len;
120#ifdef YP 174#ifdef YP
121 int hostlen = strlen(hostname); 175 int hostlen = strlen(hostname);
122#endif 176#endif
123 177
124 f = fopen(_PATH_ETHERS, "r"); 178 f = fopen(_PATH_ETHERS, "r");
125 if (f==NULL) 179 if (f==NULL)
126 return -1; 180 return (-1);
127 181
128 while (fgets(buf, sizeof buf, f)) { 182 while ((p = fgetln(f, &len)) != NULL) {
183 if (p[len-1] == '\n')
184 len--;
185 if (len > sizeof(buf) - 2)
186 continue;
187 memcpy(buf, p, len);
188 buf[len] = '\n'; /* code assumes newlines later on */
189 buf[len+1] = '\0';
129#ifdef YP 190#ifdef YP
130 /* A + in the file means try YP now. */ 191 /* A + in the file means try YP now. */
131 if (!strncmp(buf, "+\n", sizeof buf)) { 192 if (!strncmp(buf, "+\n", sizeof(buf))) {
132 char *ypbuf, *ypdom; 193 char *ypbuf, *ypdom;
133 int ypbuflen; 194 int ypbuflen;
134 195
@@ -140,7 +201,7 @@ ether_hostton(hostname, e)
140 if (ether_line(ypbuf, e, try) == 0) { 201 if (ether_line(ypbuf, e, try) == 0) {
141 free(ypbuf); 202 free(ypbuf);
142 (void)fclose(f); 203 (void)fclose(f);
143 return 0; 204 return (0);
144 } 205 }
145 free(ypbuf); 206 free(ypbuf);
146 continue; 207 continue;
@@ -148,31 +209,39 @@ ether_hostton(hostname, e)
148#endif 209#endif
149 if (ether_line(buf, e, try) == 0 && strcmp(hostname, try) == 0) { 210 if (ether_line(buf, e, try) == 0 && strcmp(hostname, try) == 0) {
150 (void)fclose(f); 211 (void)fclose(f);
151 return 0; 212 return (0);
152 } 213 }
153 } 214 }
154 (void)fclose(f); 215 (void)fclose(f);
155 errno = ENOENT; 216 errno = ENOENT;
156 return -1; 217 return (-1);
157} 218}
158 219
159ether_line(l, e, hostname) 220int
160 char *l; 221ether_line(line, e, hostname)
222 char *line;
161 struct ether_addr *e; 223 struct ether_addr *e;
162 char *hostname; 224 char *hostname;
163{ 225{
164 u_int i[6]; 226 char *p;
165 227 size_t n;
166 if (sscanf(l, " %x:%x:%x:%x:%x:%x %s\n", &i[0], &i[1], 228
167 &i[2], &i[3], &i[4], &i[5], hostname) == 7) { 229 /* Parse "xx:xx:xx:xx:xx:xx" */
168 e->ether_addr_octet[0] = (u_char)i[0]; 230 if ((p = _ether_aton(line, e)) == NULL || (*p != ' ' && *p != '\t'))
169 e->ether_addr_octet[1] = (u_char)i[1]; 231 goto bad;
170 e->ether_addr_octet[2] = (u_char)i[2]; 232
171 e->ether_addr_octet[3] = (u_char)i[3]; 233 /* Now get the hostname */
172 e->ether_addr_octet[4] = (u_char)i[4]; 234 while (isspace(*p))
173 e->ether_addr_octet[5] = (u_char)i[5]; 235 p++;
174 return 0; 236 if (*p == '\0')
175 } 237 goto bad;
238 n = strcspn(p, " \t\n");
239 if (n >= MAXHOSTNAMELEN)
240 goto bad;
241 strlcpy(hostname, p, n + 1);
242 return (0);
243
244bad:
176 errno = EINVAL; 245 errno = EINVAL;
177 return -1; 246 return (-1);
178} 247}
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..8c86748990
--- /dev/null
+++ b/src/lib/libc/net/getaddrinfo.3
@@ -0,0 +1,577 @@
1.\" $OpenBSD: getaddrinfo.3,v 1.26 2004/03/01 20:25:44 deraadt 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. Neither the name of the University 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 REGENTS 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 REGENTS 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.\" From: @(#)gethostbyname.3 8.4 (Berkeley) 5/25/95
32.\"
33.Dd May 25, 1995
34.Dt GETADDRINFO 3
35.Os
36.\"
37.Sh NAME
38.Nm getaddrinfo ,
39.Nm freeaddrinfo ,
40.Nm gai_strerror
41.Nd nodename-to-address translation in protocol-independent manner
42.\"
43.Sh SYNOPSIS
44.Fd #include <sys/types.h>
45.Fd #include <sys/socket.h>
46.Fd #include <netdb.h>
47.Ft int
48.Fn getaddrinfo "const char *nodename" "const char *servname" \
49"const struct addrinfo *hints" "struct addrinfo **res"
50.Ft void
51.Fn freeaddrinfo "struct addrinfo *ai"
52.Ft "char *"
53.Fn gai_strerror "int ecode"
54.\"
55.Sh DESCRIPTION
56The
57.Fn getaddrinfo
58function is defined for protocol-independent nodename-to-address translation.
59It performs the functionality of
60.Xr gethostbyname 3
61and
62.Xr getservbyname 3 ,
63but in a more sophisticated manner.
64.Pp
65The
66.Li addrinfo
67structure is defined as a result of including the
68.Aq Pa netdb.h
69header:
70.Bd -literal
71struct addrinfo {
72 int ai_flags; /* input flags */
73 int ai_family; /* protocol family for socket */
74 int ai_socktype; /* socket type */
75 int ai_protocol; /* protocol for socket */
76 socklen_t ai_addrlen; /* length of socket-address */
77 struct sockaddr *ai_addr; /* socket-address for socket */
78 char *ai_canonname; /* canonical name for service location */
79 struct addrinfo *ai_next; /* pointer to next in list */
80};
81.Ed
82.Pp
83The
84.Fa nodename
85and
86.Fa servname
87arguments are pointers to NUL-terminated strings or
88.Dv NULL .
89One or both of these two arguments must be a non-null pointer.
90In the normal client scenario, both the
91.Fa nodename
92and
93.Fa servname
94are specified.
95In the normal server scenario, only the
96.Fa servname
97is specified.
98A non-null
99.Fa nodename
100string can be either a node name or a numeric host address string
101(i.e., a dotted-decimal IPv4 address or an IPv6 hex address).
102A non-null
103.Fa servname
104string can be either a service name or a decimal port number.
105.Pp
106The caller can optionally pass an
107.Li addrinfo
108structure, pointed to by the third argument,
109to provide hints concerning the type of socket that the caller supports.
110In this
111.Fa hints
112structure all members other than
113.Fa ai_flags ,
114.Fa ai_family ,
115.Fa ai_socktype ,
116and
117.Fa ai_protocol
118must be zero or a null pointer.
119A value of
120.Dv PF_UNSPEC
121for
122.Fa ai_family
123means the caller will accept any protocol family.
124A value of 0 for
125.Fa ai_socktype
126means the caller will accept any socket type.
127A value of 0 for
128.Fa ai_protocol
129means the caller will accept any protocol.
130For example, if the caller handles only TCP and not UDP, then the
131.Fa ai_socktype
132member of the hints structure should be set to
133.Dv SOCK_STREAM
134when
135.Fn getaddrinfo
136is called.
137If the caller handles only IPv4 and not IPv6, then the
138.Fa ai_family
139member of the
140.Fa hints
141structure should be set to
142.Dv PF_INET
143when
144.Fn getaddrinfo
145is called.
146If the third argument to
147.Fn getaddrinfo
148is a null pointer, this is the same as if the caller had filled in an
149.Li addrinfo
150structure initialized to zero with
151.Fa ai_family
152set to
153.Dv PF_UNSPEC .
154.Pp
155Upon successful return a pointer to a linked list of one or more
156.Li addrinfo
157structures is returned through the final argument.
158The caller can process each
159.Li addrinfo
160structure in this list by following the
161.Fa ai_next
162pointer, until a null pointer is encountered.
163In each returned
164.Li addrinfo
165structure the three members
166.Fa ai_family ,
167.Fa ai_socktype ,
168and
169.Fa ai_protocol
170are the corresponding arguments for a call to the
171.Fn socket
172function.
173In each
174.Li addrinfo
175structure the
176.Fa ai_addr
177member points to a filled-in socket address structure whose length is
178specified by the
179.Fa ai_addrlen
180member.
181.Pp
182If the
183.Dv AI_PASSIVE
184bit is set in the
185.Fa ai_flags
186member of the
187.Fa hints
188structure, then the caller plans to use the returned socket address
189structure in a call to
190.Fn bind .
191In this case, if the
192.Fa nodename
193argument is a null pointer, then the IP address portion of the socket
194address structure will be set to
195.Dv INADDR_ANY
196for an IPv4 address or
197.Dv IN6ADDR_ANY_INIT
198for an IPv6 address.
199.Pp
200If the
201.Dv AI_PASSIVE
202bit is not set in the
203.Fa ai_flags
204member of the
205.Fa hints
206structure, then the returned socket address structure will be ready for a
207call to
208.Fn connect
209.Pq for a connection-oriented protocol
210or either
211.Fn connect ,
212.Fn sendto ,
213or
214.Fn sendmsg
215.Pq for a connectionless protocol .
216In this case, if the
217.Fa nodename
218argument is a null pointer, then the IP address portion of the
219socket address structure will be set to the loopback address.
220.Pp
221If the
222.Dv AI_CANONNAME
223bit is set in the
224.Fa ai_flags
225member of the
226.Fa hints
227structure, then upon successful return the
228.Fa ai_canonname
229member of the first
230.Li addrinfo
231structure in the linked list will point to a NUL-terminated string
232containing the canonical name of the specified
233.Fa nodename .
234.Pp
235If the
236.Dv AI_NUMERICHOST
237bit is set in the
238.Fa ai_flags
239member of the
240.Fa hints
241structure, then a non-null
242.Fa nodename
243string must be a numeric host address string.
244Otherwise an error of
245.Dv EAI_NONAME
246is returned.
247This flag prevents any type of name resolution service (e.g., the DNS)
248from being called.
249.Pp
250The arguments to
251.Fn getaddrinfo
252must sufficiently be consistent and unambiguous.
253Here are pitfall cases you may encounter:
254.Bl -bullet
255.It
256.Fn getaddrinfo
257will raise an error if members of the
258.Fa hints
259structure are not consistent.
260For example, for internet address families,
261.Fn getaddrinfo
262will raise an error if you specify
263.Dv SOCK_STREAM
264to
265.Fa ai_socktype
266while you specify
267.Dv IPPROTO_UDP
268to
269.Fa ai_protocol .
270.It
271If you specify a
272.Fa servname
273which is defined only for certain
274.Fa ai_socktype ,
275.Fn getaddrinfo
276will raise an error because the arguments are not consistent.
277For example,
278.Fn getaddrinfo
279will raise an error if you ask for
280.Dq Li tftp
281service on
282.Dv SOCK_STREAM .
283.It
284For internet address families, if you specify
285.Fa servname
286while you set
287.Fa ai_socktype
288to
289.Dv SOCK_RAW ,
290.Fn getaddrinfo
291will raise an error, because service names are not defined for the internet
292.Dv SOCK_RAW
293space.
294.It
295If you specify a numeric
296.Fa servname ,
297while leaving
298.Fa ai_socktype
299and
300.Fa ai_protocol
301unspecified,
302.Fn getaddrinfo
303will raise an error.
304This is because the numeric
305.Fa servname
306does not identify any socket type, and
307.Fn getaddrinfo
308is not allowed to glob the argument in such case.
309.El
310.Pp
311All of the information returned by
312.Fn getaddrinfo
313is dynamically allocated:
314the
315.Li addrinfo
316structures, the socket address structures, and canonical node name
317strings pointed to by the addrinfo structures.
318To return this information to the system the function
319.Fn freeaddrinfo
320is called.
321The
322.Fa addrinfo
323structure pointed to by the
324.Fa ai argument
325is freed, along with any dynamic storage pointed to by the structure.
326This operation is repeated until a
327.Dv NULL
328.Fa ai_next
329pointer is encountered.
330.Pp
331To aid applications in printing error messages based on the
332.Dv EAI_xxx
333codes returned by
334.Fn getaddrinfo ,
335.Fn gai_strerror
336is defined.
337The argument is one of the
338.Dv EAI_xxx
339values defined earlier and the return value points to a string describing
340the error.
341If the argument is not one of the
342.Dv EAI_xxx
343values, the function still returns a pointer to a string whose contents
344indicate an unknown error.
345.\"
346.Ss Extension for scoped IPv6 address
347The implementation allows experimental numeric IPv6 address notation with
348scope identifier.
349By appending the percent character and scope identifier to addresses,
350you can fill the
351.Li sin6_scope_id
352field for addresses.
353This would make management of scoped address easier,
354and allows cut-and-paste input of scoped address.
355.Pp
356At this moment the code supports only link-local addresses with the format.
357Scope identifier is hardcoded to the name of the hardware interface associated
358with the link.
359.Po
360such as
361.Li ne0
362.Pc .
363An example is
364.Dq Li fe80::1%ne0 ,
365which means
366.Do
367.Li fe80::1
368on the link associated with the
369.Li ne0
370interface
371.Dc .
372.Pp
373The implementation is still very experimental and non-standard.
374The current implementation assumes a one-to-one relationship between
375the interface and link, which is not necessarily true from the specification.
376.\"
377.Sh EXAMPLES
378The following code tries to connect to
379.Dq Li www.kame.net
380service
381.Dq Li http .
382via stream socket.
383It loops through all the addresses available, regardless of address family.
384If the destination resolves to an IPv4 address, it will use
385.Dv AF_INET
386socket.
387Similarly, if it resolves to IPv6,
388.Dv AF_INET6
389socket is used.
390Observe that there is no hardcoded reference to a particular address family.
391The code works even if
392.Nm getaddrinfo
393returns addresses that are not IPv4/v6.
394.Bd -literal -offset indent
395struct addrinfo hints, *res, *res0;
396int error;
397int s;
398const char *cause = NULL;
399
400memset(&hints, 0, sizeof(hints));
401hints.ai_family = PF_UNSPEC;
402hints.ai_socktype = SOCK_STREAM;
403error = getaddrinfo("www.kame.net", "http", &hints, &res0);
404if (error) {
405 errx(1, "%s", gai_strerror(error));
406 /*NOTREACHED*/
407}
408s = -1;
409for (res = res0; res; res = res->ai_next) {
410 s = socket(res->ai_family, res->ai_socktype,
411 res->ai_protocol);
412 if (s < 0) {
413 cause = "socket";
414 continue;
415 }
416
417 if (connect(s, res->ai_addr, res->ai_addrlen) < 0) {
418 cause = "connect";
419 close(s);
420 s = -1;
421 continue;
422 }
423
424 break; /* okay we got one */
425}
426if (s < 0) {
427 err(1, "%s", cause);
428 /*NOTREACHED*/
429}
430freeaddrinfo(res0);
431.Ed
432.Pp
433The following example tries to open a wildcard listening socket onto service
434.Dq Li http ,
435for all the address families available.
436.Bd -literal -offset indent
437struct addrinfo hints, *res, *res0;
438int error;
439int s[MAXSOCK];
440int nsock;
441const char *cause = NULL;
442
443memset(&hints, 0, sizeof(hints));
444hints.ai_family = PF_UNSPEC;
445hints.ai_socktype = SOCK_STREAM;
446hints.ai_flags = AI_PASSIVE;
447error = getaddrinfo(NULL, "http", &hints, &res0);
448if (error) {
449 errx(1, "%s", gai_strerror(error));
450 /*NOTREACHED*/
451}
452nsock = 0;
453for (res = res0; res && nsock < MAXSOCK; res = res->ai_next) {
454 s[nsock] = socket(res->ai_family, res->ai_socktype,
455 res->ai_protocol);
456 if (s[nsock] < 0) {
457 cause = "socket";
458 continue;
459 }
460
461 if (bind(s[nsock], res->ai_addr, res->ai_addrlen) < 0) {
462 cause = "bind";
463 close(s[nsock]);
464 continue;
465 }
466 (void) listen(s[nsock], 5);
467
468 nsock++;
469}
470if (nsock == 0) {
471 err(1, "%s", cause);
472 /*NOTREACHED*/
473}
474freeaddrinfo(res0);
475.Ed
476.\"
477.Sh DIAGNOSTICS
478Error return status from
479.Fn getaddrinfo
480is zero on success and non-zero on errors.
481Non-zero error codes are defined in
482.Aq Pa netdb.h ,
483and as follows:
484.Pp
485.Bl -tag -width EAI_ADDRFAMILY -compact
486.It Dv EAI_ADDRFAMILY
487Address family for
488.Fa nodename
489not supported.
490.It Dv EAI_AGAIN
491Temporary failure in name resolution.
492.It Dv EAI_BADFLAGS
493Invalid value for
494.Fa ai_flags .
495.It Dv EAI_FAIL
496Non-recoverable failure in name resolution.
497.It Dv EAI_FAMILY
498.Fa ai_family
499not supported.
500.It Dv EAI_MEMORY
501Memory allocation failure.
502.It Dv EAI_NODATA
503No address associated with
504.Fa nodename .
505.It Dv EAI_NONAME
506.Fa nodename
507nor
508.Fa servname
509provided, or not known.
510.It Dv EAI_SERVICE
511.Fa servname
512not supported for
513.Fa ai_socktype .
514.It Dv EAI_SOCKTYPE
515.Fa ai_socktype
516not supported.
517.It Dv EAI_SYSTEM
518System error returned in
519.Va errno .
520.El
521.Pp
522If called with proper argument,
523.Fn gai_strerror
524returns a pointer to a string describing the given error code.
525If the argument is not one of the
526.Dv EAI_xxx
527values, the function still returns a pointer to a string whose contents
528indicate an unknown error.
529.\"
530.Sh SEE ALSO
531.Xr gethostbyname 3 ,
532.Xr getnameinfo 3 ,
533.Xr getservbyname 3 ,
534.Xr hosts 5 ,
535.Xr resolv.conf 5 ,
536.Xr services 5 ,
537.Xr hostname 7 ,
538.Xr named 8
539.Rs
540.%A R. Gilligan
541.%A S. Thomson
542.%A J. Bound
543.%A W. Stevens
544.%T Basic Socket Interface Extensions for IPv6
545.%R RFC 2553
546.%D March 1999
547.Re
548.Rs
549.%A Tatsuya Jinmei
550.%A Atsushi Onoe
551.%T "An Extension of Format for IPv6 Scoped Addresses"
552.%R internet draft
553.%N draft-ietf-ipngwg-scopedaddr-format-02.txt
554.%O work in progress material
555.Re
556.Rs
557.%A Craig Metz
558.%T Protocol Independence Using the Sockets API
559.%B "Proceedings of the freenix track: 2000 USENIX annual technical conference"
560.%D June 2000
561.Re
562.\"
563.Sh STANDARDS
564The
565.Fn getaddrinfo
566function is defined in IEEE POSIX 1003.1g draft specification,
567and documented in
568.Dq Basic Socket Interface Extensions for IPv6
569.Pq RFC 2553 .
570.\"
571.Sh HISTORY
572The implementation first appeared in WIDE Hydrangea IPv6 protocol stack kit.
573.\"
574.Sh BUGS
575The current implementation is not thread-safe.
576.Pp
577The text was shamelessly copied from RFC 2553.
diff --git a/src/lib/libc/net/getaddrinfo.c b/src/lib/libc/net/getaddrinfo.c
new file mode 100644
index 0000000000..eb7bd7b3b1
--- /dev/null
+++ b/src/lib/libc/net/getaddrinfo.c
@@ -0,0 +1,1885 @@
1/* $OpenBSD: getaddrinfo.c,v 1.48 2003/07/21 23:17:53 marc 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 **, const char *);
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,
422 &cur->ai_next);
423
424 if (error)
425 goto free;
426
427 while (cur && cur->ai_next)
428 cur = cur->ai_next;
429 }
430
431 /*
432 * XXX
433 * If numreic representation of AF1 can be interpreted as FQDN
434 * representation of AF2, we need to think again about the code below.
435 */
436 if (sentinel.ai_next)
437 goto good;
438
439 if (hostname == NULL)
440 ERR(EAI_NODATA);
441 if (pai->ai_flags & AI_NUMERICHOST)
442 ERR(EAI_NONAME);
443
444 /*
445 * hostname as alphabetical name.
446 * we would like to prefer AF_INET6 than AF_INET, so we'll make a
447 * outer loop by AFs.
448 */
449 for (ex = explore; ex->e_af >= 0; ex++) {
450 *pai = ai0;
451
452 /* require exact match for family field */
453 if (pai->ai_family != ex->e_af)
454 continue;
455
456 if (!MATCH(pai->ai_socktype, ex->e_socktype,
457 WILD_SOCKTYPE(ex))) {
458 continue;
459 }
460 if (!MATCH(pai->ai_protocol, ex->e_protocol,
461 WILD_PROTOCOL(ex))) {
462 continue;
463 }
464
465 if (pai->ai_socktype == ANY && ex->e_socktype != ANY)
466 pai->ai_socktype = ex->e_socktype;
467 if (pai->ai_protocol == ANY && ex->e_protocol != ANY)
468 pai->ai_protocol = ex->e_protocol;
469
470 error = explore_fqdn(pai, hostname, servname,
471 &cur->ai_next);
472
473 while (cur && cur->ai_next)
474 cur = cur->ai_next;
475 }
476
477 /* XXX */
478 if (sentinel.ai_next)
479 error = 0;
480
481 if (error)
482 goto free;
483 if (error == 0) {
484 if (sentinel.ai_next) {
485 good:
486 *res = sentinel.ai_next;
487 return SUCCESS;
488 } else
489 error = EAI_FAIL;
490 }
491 free:
492 bad:
493 if (sentinel.ai_next)
494 freeaddrinfo(sentinel.ai_next);
495 *res = NULL;
496 return error;
497}
498
499/*
500 * FQDN hostname, DNS lookup
501 */
502
503static int
504explore_fqdn(pai, hostname, servname, res)
505 const struct addrinfo *pai;
506 const char *hostname;
507 const char *servname;
508 struct addrinfo **res;
509{
510 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
511 struct addrinfo *result;
512 struct addrinfo *cur;
513 int error = 0;
514 char lookups[MAXDNSLUS];
515 int i;
516 _THREAD_PRIVATE_MUTEX(_explore_mutex);
517
518 result = NULL;
519
520#if 0
521 /*
522 * If AI_ADDRCONFIG is specified, check if we are expected to
523 * return the address family or not.
524 * XXX does not handle PF_UNSPEC case, should filter final result
525 */
526 if ((pai->ai_flags & AI_ADDRCONFIG) != 0 && !addrconfig(pai)) {
527 return 0;
528 }
529#endif
530
531 /*
532 * if the servname does not match socktype/protocol, ignore it.
533 */
534 if (get_portmatch(pai, servname) != 0) {
535 return 0;
536 }
537
538 if ((_resp->options & RES_INIT) == 0 && res_init() == -1)
539 strlcpy(lookups, "f", sizeof lookups);
540 else {
541 bcopy(_resp->lookups, lookups, sizeof lookups);
542 if (lookups[0] == '\0')
543 strlcpy(lookups, "bf", sizeof lookups);
544 }
545
546 /*
547 * The yp/dns/files getaddrinfo functions are not thread safe.
548 * Protect them with a mutex.
549 */
550 _THREAD_PRIVATE_MUTEX_LOCK(_explore_mutex);
551 for (i = 0; i < MAXDNSLUS && result == NULL && lookups[i]; i++) {
552 switch (lookups[i]) {
553#ifdef YP
554 case 'y':
555 result = _yp_getaddrinfo(hostname, pai);
556 break;
557#endif
558 case 'b':
559 result = _dns_getaddrinfo(hostname, pai);
560 break;
561 case 'f':
562 result = _files_getaddrinfo(hostname, pai);
563 break;
564 }
565 }
566 _THREAD_PRIVATE_MUTEX_UNLOCK(_explore_mutex);
567 if (result) {
568 for (cur = result; cur; cur = cur->ai_next) {
569 GET_PORT(cur, servname);
570 /* canonname should be filled already */
571 }
572 *res = result;
573 return 0;
574 } else {
575 /* translate error code */
576 switch (h_errno) {
577 case NETDB_SUCCESS:
578 error = EAI_FAIL; /*XXX strange */
579 break;
580 case HOST_NOT_FOUND:
581 error = EAI_NODATA;
582 break;
583 case TRY_AGAIN:
584 error = EAI_AGAIN;
585 break;
586 case NO_RECOVERY:
587 error = EAI_FAIL;
588 break;
589 case NO_DATA:
590#if NO_ADDRESS != NO_DATA
591 case NO_ADDRESS:
592#endif
593 error = EAI_NODATA;
594 break;
595 default: /* unknown ones */
596 error = EAI_FAIL;
597 break;
598 }
599 }
600
601free:
602 if (result)
603 freeaddrinfo(result);
604 return error;
605}
606
607/*
608 * hostname == NULL.
609 * passive socket -> anyaddr (0.0.0.0 or ::)
610 * non-passive socket -> localhost (127.0.0.1 or ::1)
611 */
612static int
613explore_null(pai, servname, res)
614 const struct addrinfo *pai;
615 const char *servname;
616 struct addrinfo **res;
617{
618 int s;
619 const struct afd *afd;
620 struct addrinfo *cur;
621 struct addrinfo sentinel;
622 int error;
623
624 *res = NULL;
625 sentinel.ai_next = NULL;
626 cur = &sentinel;
627
628 /*
629 * filter out AFs that are not supported by the kernel
630 * XXX errno?
631 */
632 s = socket(pai->ai_family, SOCK_DGRAM, 0);
633 if (s < 0) {
634 if (errno != EMFILE)
635 return 0;
636 } else
637 close(s);
638
639 /*
640 * if the servname does not match socktype/protocol, ignore it.
641 */
642 if (get_portmatch(pai, servname) != 0)
643 return 0;
644
645 afd = find_afd(pai->ai_family);
646 if (afd == NULL)
647 return 0;
648
649 if (pai->ai_flags & AI_PASSIVE) {
650 GET_AI(cur->ai_next, afd, afd->a_addrany);
651 /* xxx meaningless?
652 * GET_CANONNAME(cur->ai_next, "anyaddr");
653 */
654 GET_PORT(cur->ai_next, servname);
655 } else {
656 GET_AI(cur->ai_next, afd, afd->a_loopback);
657 /* xxx meaningless?
658 * GET_CANONNAME(cur->ai_next, "localhost");
659 */
660 GET_PORT(cur->ai_next, servname);
661 }
662 cur = cur->ai_next;
663
664 *res = sentinel.ai_next;
665 return 0;
666
667free:
668 if (sentinel.ai_next)
669 freeaddrinfo(sentinel.ai_next);
670 return error;
671}
672
673/*
674 * numeric hostname
675 */
676static int
677explore_numeric(pai, hostname, servname, res, canonname)
678 const struct addrinfo *pai;
679 const char *hostname;
680 const char *servname;
681 struct addrinfo **res;
682 const char *canonname;
683{
684 const struct afd *afd;
685 struct addrinfo *cur;
686 struct addrinfo sentinel;
687 int error;
688 char pton[PTON_MAX];
689
690 *res = NULL;
691 sentinel.ai_next = NULL;
692 cur = &sentinel;
693
694 /*
695 * if the servname does not match socktype/protocol, ignore it.
696 */
697 if (get_portmatch(pai, servname) != 0)
698 return 0;
699
700 afd = find_afd(pai->ai_family);
701 if (afd == NULL)
702 return 0;
703
704 switch (afd->a_af) {
705#if 0 /*X/Open spec*/
706 case AF_INET:
707 if (inet_aton(hostname, (struct in_addr *)pton) == 1) {
708 if (pai->ai_family == afd->a_af ||
709 pai->ai_family == PF_UNSPEC /*?*/) {
710 GET_AI(cur->ai_next, afd, pton);
711 GET_PORT(cur->ai_next, servname);
712 if ((pai->ai_flags & AI_CANONNAME)) {
713 /*
714 * Set the numeric address itself as
715 * the canonical name, based on a
716 * clarification in rfc2553bis-03.
717 */
718 GET_CANONNAME(cur->ai_next, canonname);
719 }
720 while (cur && cur->ai_next)
721 cur = cur->ai_next;
722 } else
723 ERR(EAI_FAMILY); /*xxx*/
724 }
725 break;
726#endif
727 default:
728 if (inet_pton(afd->a_af, hostname, pton) == 1) {
729 if (pai->ai_family == afd->a_af ||
730 pai->ai_family == PF_UNSPEC /*?*/) {
731 GET_AI(cur->ai_next, afd, pton);
732 GET_PORT(cur->ai_next, servname);
733 if ((pai->ai_flags & AI_CANONNAME)) {
734 /*
735 * Set the numeric address itself as
736 * the canonical name, based on a
737 * clarification in rfc2553bis-03.
738 */
739 GET_CANONNAME(cur->ai_next, canonname);
740 }
741 while (cur && cur->ai_next)
742 cur = cur->ai_next;
743 } else
744 ERR(EAI_FAMILY); /*xxx*/
745 }
746 break;
747 }
748
749 *res = sentinel.ai_next;
750 return 0;
751
752free:
753bad:
754 if (sentinel.ai_next)
755 freeaddrinfo(sentinel.ai_next);
756 return error;
757}
758
759/*
760 * numeric hostname with scope
761 */
762static int
763explore_numeric_scope(pai, hostname, servname, res)
764 const struct addrinfo *pai;
765 const char *hostname;
766 const char *servname;
767 struct addrinfo **res;
768{
769#if !defined(SCOPE_DELIMITER) || !defined(INET6)
770 return explore_numeric(pai, hostname, servname, res, hostname);
771#else
772 const struct afd *afd;
773 struct addrinfo *cur;
774 int error;
775 char *cp, *hostname2 = NULL, *scope, *addr;
776 struct sockaddr_in6 *sin6;
777
778 /*
779 * if the servname does not match socktype/protocol, ignore it.
780 */
781 if (get_portmatch(pai, servname) != 0)
782 return 0;
783
784 afd = find_afd(pai->ai_family);
785 if (afd == NULL)
786 return 0;
787
788 if (!afd->a_scoped)
789 return explore_numeric(pai, hostname, servname, res, hostname);
790
791 cp = strchr(hostname, SCOPE_DELIMITER);
792 if (cp == NULL)
793 return explore_numeric(pai, hostname, servname, res, hostname);
794
795 /*
796 * Handle special case of <scoped_address><delimiter><scope id>
797 */
798 hostname2 = strdup(hostname);
799 if (hostname2 == NULL)
800 return EAI_MEMORY;
801 /* terminate at the delimiter */
802 hostname2[cp - hostname] = '\0';
803 addr = hostname2;
804 scope = cp + 1;
805
806 error = explore_numeric(pai, addr, servname, res, hostname);
807 if (error == 0) {
808 u_int32_t scopeid;
809
810 for (cur = *res; cur; cur = cur->ai_next) {
811 if (cur->ai_family != AF_INET6)
812 continue;
813 sin6 = (struct sockaddr_in6 *)(void *)cur->ai_addr;
814 if (ip6_str2scopeid(scope, sin6, &scopeid) == -1) {
815 free(hostname2);
816 return(EAI_NODATA); /* XXX: is return OK? */
817 }
818 sin6->sin6_scope_id = scopeid;
819 }
820 }
821
822 free(hostname2);
823
824 return error;
825#endif
826}
827
828static int
829get_canonname(pai, ai, str)
830 const struct addrinfo *pai;
831 struct addrinfo *ai;
832 const char *str;
833{
834 if ((pai->ai_flags & AI_CANONNAME) != 0) {
835 ai->ai_canonname = strdup(str);
836 if (ai->ai_canonname == NULL)
837 return EAI_MEMORY;
838 }
839 return 0;
840}
841
842static struct addrinfo *
843get_ai(pai, afd, addr)
844 const struct addrinfo *pai;
845 const struct afd *afd;
846 const char *addr;
847{
848 char *p;
849 struct addrinfo *ai;
850
851 ai = (struct addrinfo *)malloc(sizeof(struct addrinfo)
852 + (afd->a_socklen));
853 if (ai == NULL)
854 return NULL;
855
856 memcpy(ai, pai, sizeof(struct addrinfo));
857 ai->ai_addr = (struct sockaddr *)(void *)(ai + 1);
858 memset(ai->ai_addr, 0, (size_t)afd->a_socklen);
859 ai->ai_addr->sa_len = afd->a_socklen;
860 ai->ai_addrlen = afd->a_socklen;
861 ai->ai_addr->sa_family = ai->ai_family = afd->a_af;
862 p = (char *)(void *)(ai->ai_addr);
863 memcpy(p + afd->a_off, addr, (size_t)afd->a_addrlen);
864 return ai;
865}
866
867static int
868get_portmatch(ai, servname)
869 const struct addrinfo *ai;
870 const char *servname;
871{
872
873 /* get_port does not touch first argument. when matchonly == 1. */
874 /* LINTED const cast */
875 return get_port((struct addrinfo *)ai, servname, 1);
876}
877
878static int
879get_port(ai, servname, matchonly)
880 struct addrinfo *ai;
881 const char *servname;
882 int matchonly;
883{
884 const char *proto;
885 struct servent *sp;
886 int port;
887 int allownumeric;
888 /* mutex is defined in getnameinfo.c */
889 extern pthread_mutex_t __THREAD_MUTEX_NAME(serv_mutex);
890
891 if (servname == NULL)
892 return 0;
893 switch (ai->ai_family) {
894 case AF_INET:
895#ifdef AF_INET6
896 case AF_INET6:
897#endif
898 break;
899 default:
900 return 0;
901 }
902
903 switch (ai->ai_socktype) {
904 case SOCK_RAW:
905 return EAI_SERVICE;
906 case SOCK_DGRAM:
907 case SOCK_STREAM:
908 allownumeric = 1;
909 break;
910 case ANY:
911 allownumeric = 0;
912 break;
913 default:
914 return EAI_SOCKTYPE;
915 }
916
917 if (str_isnumber(servname)) {
918 if (!allownumeric)
919 return EAI_SERVICE;
920 port = atoi(servname);
921 if (port < 0 || port > 65535)
922 return EAI_SERVICE;
923 port = htons(port);
924 } else {
925 switch (ai->ai_socktype) {
926 case SOCK_DGRAM:
927 proto = "udp";
928 break;
929 case SOCK_STREAM:
930 proto = "tcp";
931 break;
932 default:
933 proto = NULL;
934 break;
935 }
936
937 _THREAD_PRIVATE_MUTEX_LOCK(serv_mutex);
938 sp = getservbyname(servname, proto);
939 _THREAD_PRIVATE_MUTEX_UNLOCK(serv_mutex);
940 if (sp == NULL)
941 return EAI_SERVICE;
942 port = sp->s_port;
943 }
944
945 if (!matchonly) {
946 switch (ai->ai_family) {
947 case AF_INET:
948 ((struct sockaddr_in *)(void *)
949 ai->ai_addr)->sin_port = port;
950 break;
951#ifdef INET6
952 case AF_INET6:
953 ((struct sockaddr_in6 *)(void *)
954 ai->ai_addr)->sin6_port = port;
955 break;
956#endif
957 }
958 }
959
960 return 0;
961}
962
963static const struct afd *
964find_afd(af)
965 int af;
966{
967 const struct afd *afd;
968
969 if (af == PF_UNSPEC)
970 return NULL;
971 for (afd = afdl; afd->a_af; afd++) {
972 if (afd->a_af == af)
973 return afd;
974 }
975 return NULL;
976}
977
978#if 0
979/*
980 * post-2553: AI_ADDRCONFIG check. if we use getipnodeby* as backend, backend
981 * will take care of it.
982 * the semantics of AI_ADDRCONFIG is not defined well. we are not sure
983 * if the code is right or not.
984 */
985static int
986addrconfig(pai)
987 const struct addrinfo *pai;
988{
989 int s;
990
991 /* XXX errno */
992 s = socket(pai->ai_family, SOCK_DGRAM, 0);
993 if (s < 0)
994 return 0;
995 close(s);
996 return 1;
997}
998#endif
999
1000#ifdef INET6
1001/* convert a string to a scope identifier. XXX: IPv6 specific */
1002static int
1003ip6_str2scopeid(scope, sin6, scopeid)
1004 char *scope;
1005 struct sockaddr_in6 *sin6;
1006 u_int32_t *scopeid;
1007{
1008 u_long lscopeid;
1009 struct in6_addr *a6 = &sin6->sin6_addr;
1010 char *ep;
1011
1012 /* empty scopeid portion is invalid */
1013 if (*scope == '\0')
1014 return -1;
1015
1016 if (IN6_IS_ADDR_LINKLOCAL(a6) || IN6_IS_ADDR_MC_LINKLOCAL(a6)) {
1017 /*
1018 * We currently assume a one-to-one mapping between links
1019 * and interfaces, so we simply use interface indices for
1020 * like-local scopes.
1021 */
1022 *scopeid = if_nametoindex(scope);
1023 if (*scopeid == 0)
1024 goto trynumeric;
1025 return 0;
1026 }
1027
1028 /* still unclear about literal, allow numeric only - placeholder */
1029 if (IN6_IS_ADDR_SITELOCAL(a6) || IN6_IS_ADDR_MC_SITELOCAL(a6))
1030 goto trynumeric;
1031 if (IN6_IS_ADDR_MC_ORGLOCAL(a6))
1032 goto trynumeric;
1033 else
1034 goto trynumeric; /* global */
1035
1036 /* try to convert to a numeric id as a last resort */
1037 trynumeric:
1038 errno = 0;
1039 lscopeid = strtoul(scope, &ep, 10);
1040 *scopeid = (u_int32_t)(lscopeid & 0xffffffffUL);
1041 if (errno == 0 && ep && *ep == '\0' && *scopeid == lscopeid)
1042 return 0;
1043 else
1044 return -1;
1045}
1046#endif
1047
1048/* code duplicate with gethnamaddr.c */
1049
1050static const char AskedForGot[] =
1051 "gethostby*.getanswer: asked for \"%s\", got \"%s\"";
1052static FILE *hostf = NULL;
1053
1054static struct addrinfo *
1055getanswer(answer, anslen, qname, qtype, pai)
1056 const querybuf *answer;
1057 int anslen;
1058 const char *qname;
1059 int qtype;
1060 const struct addrinfo *pai;
1061{
1062 struct addrinfo sentinel, *cur;
1063 struct addrinfo ai;
1064 const struct afd *afd;
1065 char *canonname;
1066 const HEADER *hp;
1067 const u_char *cp;
1068 int n;
1069 const u_char *eom;
1070 char *bp, *ep;
1071 int type, class, ancount, qdcount;
1072 int haveanswer, had_error;
1073 char tbuf[MAXDNAME];
1074 int (*name_ok)(const char *);
1075 char hostbuf[8*1024];
1076
1077 memset(&sentinel, 0, sizeof(sentinel));
1078 cur = &sentinel;
1079
1080 canonname = NULL;
1081 eom = answer->buf + anslen;
1082 switch (qtype) {
1083 case T_A:
1084 case T_AAAA:
1085 case T_ANY: /*use T_ANY only for T_A/T_AAAA lookup*/
1086 name_ok = res_hnok;
1087 break;
1088 default:
1089 return (NULL); /* XXX should be abort() -- but that is illegal */
1090 }
1091 /*
1092 * find first satisfactory answer
1093 */
1094 hp = &answer->hdr;
1095 ancount = ntohs(hp->ancount);
1096 qdcount = ntohs(hp->qdcount);
1097 bp = hostbuf;
1098 ep = hostbuf + sizeof hostbuf;
1099 cp = answer->buf + HFIXEDSZ;
1100 if (qdcount != 1) {
1101 h_errno = NO_RECOVERY;
1102 return (NULL);
1103 }
1104 n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
1105 if ((n < 0) || !(*name_ok)(bp)) {
1106 h_errno = NO_RECOVERY;
1107 return (NULL);
1108 }
1109 cp += n + QFIXEDSZ;
1110 if (qtype == T_A || qtype == T_AAAA || qtype == T_ANY) {
1111 /* res_send() has already verified that the query name is the
1112 * same as the one we sent; this just gets the expanded name
1113 * (i.e., with the succeeding search-domain tacked on).
1114 */
1115 n = strlen(bp) + 1; /* for the \0 */
1116 if (n >= MAXHOSTNAMELEN) {
1117 h_errno = NO_RECOVERY;
1118 return (NULL);
1119 }
1120 canonname = bp;
1121 bp += n;
1122 /* The qname can be abbreviated, but h_name is now absolute. */
1123 qname = canonname;
1124 }
1125 haveanswer = 0;
1126 had_error = 0;
1127 while (ancount-- > 0 && cp < eom && !had_error) {
1128 n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
1129 if ((n < 0) || !(*name_ok)(bp)) {
1130 had_error++;
1131 continue;
1132 }
1133 cp += n; /* name */
1134 type = _getshort(cp);
1135 cp += INT16SZ; /* type */
1136 class = _getshort(cp);
1137 cp += INT16SZ + INT32SZ; /* class, TTL */
1138 n = _getshort(cp);
1139 cp += INT16SZ; /* len */
1140 if (class != C_IN) {
1141 /* XXX - debug? syslog? */
1142 cp += n;
1143 continue; /* XXX - had_error++ ? */
1144 }
1145 if ((qtype == T_A || qtype == T_AAAA || qtype == T_ANY) &&
1146 type == T_CNAME) {
1147 n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
1148 if ((n < 0) || !(*name_ok)(tbuf)) {
1149 had_error++;
1150 continue;
1151 }
1152 cp += n;
1153 /* Get canonical name. */
1154 n = strlen(tbuf) + 1; /* for the \0 */
1155 if (n > ep - bp || n >= MAXHOSTNAMELEN) {
1156 had_error++;
1157 continue;
1158 }
1159 strlcpy(bp, tbuf, ep - bp);
1160 canonname = bp;
1161 bp += n;
1162 continue;
1163 }
1164 if (qtype == T_ANY) {
1165 if (!(type == T_A || type == T_AAAA)) {
1166 cp += n;
1167 continue;
1168 }
1169 } else if (type != qtype) {
1170 if (type != T_KEY && type != T_SIG)
1171 syslog(LOG_NOTICE|LOG_AUTH,
1172 "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",
1173 qname, p_class(C_IN), p_type(qtype),
1174 p_type(type));
1175 cp += n;
1176 continue; /* XXX - had_error++ ? */
1177 }
1178 switch (type) {
1179 case T_A:
1180 case T_AAAA:
1181 if (strcasecmp(canonname, bp) != 0) {
1182 syslog(LOG_NOTICE|LOG_AUTH,
1183 AskedForGot, canonname, bp);
1184 cp += n;
1185 continue; /* XXX - had_error++ ? */
1186 }
1187 if (type == T_A && n != INADDRSZ) {
1188 cp += n;
1189 continue;
1190 }
1191 if (type == T_AAAA && n != IN6ADDRSZ) {
1192 cp += n;
1193 continue;
1194 }
1195 if (type == T_AAAA) {
1196 struct in6_addr in6;
1197 memcpy(&in6, cp, IN6ADDRSZ);
1198 if (IN6_IS_ADDR_V4MAPPED(&in6)) {
1199 cp += n;
1200 continue;
1201 }
1202 }
1203 if (!haveanswer) {
1204 int nn;
1205
1206 canonname = bp;
1207 nn = strlen(bp) + 1; /* for the \0 */
1208 bp += nn;
1209 }
1210
1211 /* don't overwrite pai */
1212 ai = *pai;
1213 ai.ai_family = (type == T_A) ? AF_INET : AF_INET6;
1214 afd = find_afd(ai.ai_family);
1215 if (afd == NULL) {
1216 cp += n;
1217 continue;
1218 }
1219 cur->ai_next = get_ai(&ai, afd, (const char *)cp);
1220 if (cur->ai_next == NULL)
1221 had_error++;
1222 while (cur && cur->ai_next)
1223 cur = cur->ai_next;
1224 cp += n;
1225 break;
1226 default:
1227 abort(); /* XXX abort illegal in library */
1228 }
1229 if (!had_error)
1230 haveanswer++;
1231 }
1232 if (haveanswer) {
1233 if (!canonname)
1234 (void)get_canonname(pai, sentinel.ai_next, qname);
1235 else
1236 (void)get_canonname(pai, sentinel.ai_next, canonname);
1237 h_errno = NETDB_SUCCESS;
1238 return sentinel.ai_next;
1239 }
1240
1241 h_errno = NO_RECOVERY;
1242 return NULL;
1243}
1244
1245/*ARGSUSED*/
1246static struct addrinfo *
1247_dns_getaddrinfo(name, pai)
1248 const char *name;
1249 const struct addrinfo *pai;
1250{
1251 struct addrinfo *ai;
1252 querybuf *buf, *buf2;
1253 struct addrinfo sentinel, *cur;
1254 struct res_target q, q2;
1255
1256 memset(&q, 0, sizeof(q2));
1257 memset(&q2, 0, sizeof(q2));
1258 memset(&sentinel, 0, sizeof(sentinel));
1259 cur = &sentinel;
1260
1261 buf = malloc(sizeof(*buf));
1262 if (buf == NULL) {
1263 h_errno = NETDB_INTERNAL;
1264 return NULL;
1265 }
1266 buf2 = malloc(sizeof(*buf2));
1267 if (buf2 == NULL) {
1268 free(buf);
1269 h_errno = NETDB_INTERNAL;
1270 return NULL;
1271 }
1272
1273 switch (pai->ai_family) {
1274 case AF_UNSPEC:
1275 /* prefer IPv6 */
1276 q.qclass = C_IN;
1277 q.qtype = T_AAAA;
1278 q.answer = buf->buf;
1279 q.anslen = sizeof(buf->buf);
1280 q.next = &q2;
1281 q2.qclass = C_IN;
1282 q2.qtype = T_A;
1283 q2.answer = buf2->buf;
1284 q2.anslen = sizeof(buf2->buf);
1285 break;
1286 case AF_INET:
1287 q.qclass = C_IN;
1288 q.qtype = T_A;
1289 q.answer = buf->buf;
1290 q.anslen = sizeof(buf->buf);
1291 break;
1292 case AF_INET6:
1293 q.qclass = C_IN;
1294 q.qtype = T_AAAA;
1295 q.answer = buf->buf;
1296 q.anslen = sizeof(buf->buf);
1297 break;
1298 default:
1299 free(buf);
1300 free(buf2);
1301 return NULL;
1302 }
1303 if (res_searchN(name, &q) < 0) {
1304 free(buf);
1305 free(buf2);
1306 return NULL;
1307 }
1308 ai = getanswer(buf, q.n, q.name, q.qtype, pai);
1309 if (ai) {
1310 cur->ai_next = ai;
1311 while (cur && cur->ai_next)
1312 cur = cur->ai_next;
1313 }
1314 if (q.next) {
1315 ai = getanswer(buf2, q2.n, q2.name, q2.qtype, pai);
1316 if (ai)
1317 cur->ai_next = ai;
1318 }
1319 free(buf);
1320 free(buf2);
1321 return sentinel.ai_next;
1322}
1323
1324static FILE *hostf;
1325
1326static void
1327_sethtent()
1328{
1329 if (!hostf)
1330 hostf = fopen(_PATH_HOSTS, "r" );
1331 else
1332 rewind(hostf);
1333}
1334
1335static void
1336_endhtent()
1337{
1338 if (hostf) {
1339 (void) fclose(hostf);
1340 hostf = NULL;
1341 }
1342}
1343
1344static struct addrinfo *
1345_gethtent(name, pai)
1346 const char *name;
1347 const struct addrinfo *pai;
1348{
1349 char *p;
1350 char *cp, *tname, *cname;
1351 struct addrinfo hints, *res0, *res;
1352 int error;
1353 const char *addr;
1354 char hostbuf[8*1024];
1355
1356 if (!hostf && !(hostf = fopen(_PATH_HOSTS, "r" )))
1357 return (NULL);
1358 again:
1359 if (!(p = fgets(hostbuf, sizeof hostbuf, hostf)))
1360 return (NULL);
1361 if (*p == '#')
1362 goto again;
1363 if (!(cp = strpbrk(p, "#\n")))
1364 goto again;
1365 *cp = '\0';
1366 if (!(cp = strpbrk(p, " \t")))
1367 goto again;
1368 *cp++ = '\0';
1369 addr = p;
1370 /* if this is not something we're looking for, skip it. */
1371 cname = NULL;
1372 while (cp && *cp) {
1373 if (*cp == ' ' || *cp == '\t') {
1374 cp++;
1375 continue;
1376 }
1377 if (!cname)
1378 cname = cp;
1379 tname = cp;
1380 if ((cp = strpbrk(cp, " \t")) != NULL)
1381 *cp++ = '\0';
1382 if (strcasecmp(name, tname) == 0)
1383 goto found;
1384 }
1385 goto again;
1386
1387found:
1388 hints = *pai;
1389 hints.ai_flags = AI_NUMERICHOST;
1390 error = getaddrinfo(addr, NULL, &hints, &res0);
1391 if (error)
1392 goto again;
1393 for (res = res0; res; res = res->ai_next) {
1394 /* cover it up */
1395 res->ai_flags = pai->ai_flags;
1396
1397 if (pai->ai_flags & AI_CANONNAME) {
1398 if (get_canonname(pai, res, cname) != 0) {
1399 freeaddrinfo(res0);
1400 goto again;
1401 }
1402 }
1403 }
1404 return res0;
1405}
1406
1407/*ARGSUSED*/
1408static struct addrinfo *
1409_files_getaddrinfo(name, pai)
1410 const char *name;
1411 const struct addrinfo *pai;
1412{
1413 struct addrinfo sentinel, *cur;
1414 struct addrinfo *p;
1415
1416 memset(&sentinel, 0, sizeof(sentinel));
1417 cur = &sentinel;
1418
1419 _sethtent();
1420 while ((p = _gethtent(name, pai)) != NULL) {
1421 cur->ai_next = p;
1422 while (cur && cur->ai_next)
1423 cur = cur->ai_next;
1424 }
1425 _endhtent();
1426
1427 return sentinel.ai_next;
1428}
1429
1430#ifdef YP
1431static char *__ypdomain;
1432
1433/*ARGSUSED*/
1434static struct addrinfo *
1435_yphostent(line, pai)
1436 char *line;
1437 const struct addrinfo *pai;
1438{
1439 struct addrinfo sentinel, *cur;
1440 struct addrinfo hints, *res, *res0;
1441 int error;
1442 char *p = line;
1443 const char *addr, *canonname;
1444 char *nextline;
1445 char *cp;
1446
1447 addr = canonname = NULL;
1448
1449 memset(&sentinel, 0, sizeof(sentinel));
1450 cur = &sentinel;
1451
1452nextline:
1453 /* terminate line */
1454 cp = strchr(p, '\n');
1455 if (cp) {
1456 *cp++ = '\0';
1457 nextline = cp;
1458 } else
1459 nextline = NULL;
1460
1461 cp = strpbrk(p, " \t");
1462 if (cp == NULL) {
1463 if (canonname == NULL)
1464 return (NULL);
1465 else
1466 goto done;
1467 }
1468 *cp++ = '\0';
1469
1470 addr = p;
1471
1472 while (cp && *cp) {
1473 if (*cp == ' ' || *cp == '\t') {
1474 cp++;
1475 continue;
1476 }
1477 if (!canonname)
1478 canonname = cp;
1479 if ((cp = strpbrk(cp, " \t")) != NULL)
1480 *cp++ = '\0';
1481 }
1482
1483 hints = *pai;
1484 hints.ai_flags = AI_NUMERICHOST;
1485 error = getaddrinfo(addr, NULL, &hints, &res0);
1486 if (error == 0) {
1487 for (res = res0; res; res = res->ai_next) {
1488 /* cover it up */
1489 res->ai_flags = pai->ai_flags;
1490
1491 if (pai->ai_flags & AI_CANONNAME)
1492 (void)get_canonname(pai, res, canonname);
1493 }
1494 } else
1495 res0 = NULL;
1496 if (res0) {
1497 cur->ai_next = res0;
1498 while (cur && cur->ai_next)
1499 cur = cur->ai_next;
1500 }
1501
1502 if (nextline) {
1503 p = nextline;
1504 goto nextline;
1505 }
1506
1507done:
1508 return sentinel.ai_next;
1509}
1510
1511/*ARGSUSED*/
1512static struct addrinfo *
1513_yp_getaddrinfo(name, pai)
1514 const char *name;
1515 const struct addrinfo *pai;
1516{
1517 struct addrinfo sentinel, *cur;
1518 struct addrinfo *ai = NULL;
1519 static char *__ypcurrent;
1520 int __ypcurrentlen, r;
1521
1522 memset(&sentinel, 0, sizeof(sentinel));
1523 cur = &sentinel;
1524
1525 if (!__ypdomain) {
1526 if (_yp_check(&__ypdomain) == 0)
1527 return NULL;
1528 }
1529 if (__ypcurrent)
1530 free(__ypcurrent);
1531 __ypcurrent = NULL;
1532
1533 /* hosts.byname is only for IPv4 (Solaris8) */
1534 if (pai->ai_family == PF_UNSPEC || pai->ai_family == PF_INET) {
1535 r = yp_match(__ypdomain, "hosts.byname", name,
1536 (int)strlen(name), &__ypcurrent, &__ypcurrentlen);
1537 if (r == 0) {
1538 struct addrinfo ai4;
1539
1540 ai4 = *pai;
1541 ai4.ai_family = AF_INET;
1542 ai = _yphostent(__ypcurrent, &ai4);
1543 if (ai) {
1544 cur->ai_next = ai;
1545 while (cur && cur->ai_next)
1546 cur = cur->ai_next;
1547 }
1548 }
1549 }
1550
1551 /* ipnodes.byname can hold both IPv4/v6 */
1552 r = yp_match(__ypdomain, "ipnodes.byname", name,
1553 (int)strlen(name), &__ypcurrent, &__ypcurrentlen);
1554 if (r == 0) {
1555 ai = _yphostent(__ypcurrent, pai);
1556 if (ai) {
1557 cur->ai_next = ai;
1558 while (cur && cur->ai_next)
1559 cur = cur->ai_next;
1560 }
1561 }
1562
1563 return sentinel.ai_next;
1564}
1565#endif
1566
1567
1568/* resolver logic */
1569
1570extern const char *__hostalias(const char *);
1571extern int h_errno;
1572extern int res_opt(int, u_char *, int, int);
1573
1574/*
1575 * Formulate a normal query, send, and await answer.
1576 * Returned answer is placed in supplied buffer "answer".
1577 * Perform preliminary check of answer, returning success only
1578 * if no error is indicated and the answer count is nonzero.
1579 * Return the size of the response on success, -1 on error.
1580 * Error number is left in h_errno.
1581 *
1582 * Caller must parse answer and determine whether it answers the question.
1583 */
1584static int
1585res_queryN(name, target)
1586 const char *name; /* domain name */
1587 struct res_target *target;
1588{
1589 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
1590 u_char *buf;
1591 HEADER *hp;
1592 int n;
1593 struct res_target *t;
1594 int rcode;
1595 int ancount;
1596
1597 buf = malloc(MAXPACKET);
1598 if (buf == NULL) {
1599 h_errno = NETDB_INTERNAL;
1600 return (-1);
1601 }
1602
1603 rcode = NOERROR;
1604 ancount = 0;
1605
1606 if ((_resp->options & RES_INIT) == 0 && res_init() == -1) {
1607 h_errno = NETDB_INTERNAL;
1608 free(buf);
1609 return (-1);
1610 }
1611
1612 for (t = target; t; t = t->next) {
1613 int class, type;
1614 u_char *answer;
1615 int anslen;
1616
1617 hp = (HEADER *)(void *)t->answer;
1618 hp->rcode = NOERROR; /* default */
1619
1620 /* make it easier... */
1621 class = t->qclass;
1622 type = t->qtype;
1623 answer = t->answer;
1624 anslen = t->anslen;
1625#ifdef DEBUG
1626 if (_resp->options & RES_DEBUG)
1627 printf(";; res_query(%s, %d, %d)\n", name, class, type);
1628#endif
1629
1630 n = res_mkquery(QUERY, name, class, type, NULL, 0, NULL,
1631 buf, MAXPACKET);
1632 if (n > 0 && (_resp->options & RES_USE_EDNS0) != 0)
1633 n = res_opt(n, buf, MAXPACKET, anslen);
1634 if (n <= 0) {
1635#ifdef DEBUG
1636 if (_resp->options & RES_DEBUG)
1637 printf(";; res_query: mkquery failed\n");
1638#endif
1639 h_errno = NO_RECOVERY;
1640 free(buf);
1641 return (n);
1642 }
1643 n = res_send(buf, n, answer, anslen);
1644#if 0
1645 if (n < 0) {
1646#ifdef DEBUG
1647 if (_resp->options & RES_DEBUG)
1648 printf(";; res_query: send error\n");
1649#endif
1650 h_errno = TRY_AGAIN;
1651 free(buf);
1652 return (n);
1653 }
1654#endif
1655
1656 if (n < 0 || hp->rcode != NOERROR || ntohs(hp->ancount) == 0) {
1657 rcode = hp->rcode; /* record most recent error */
1658#ifdef DEBUG
1659 if (_resp->options & RES_DEBUG)
1660 printf(";; rcode = %u, ancount=%u\n", hp->rcode,
1661 ntohs(hp->ancount));
1662#endif
1663 continue;
1664 }
1665
1666 ancount += ntohs(hp->ancount);
1667
1668 t->n = n;
1669 }
1670
1671 if (ancount == 0) {
1672 switch (rcode) {
1673 case NXDOMAIN:
1674 h_errno = HOST_NOT_FOUND;
1675 break;
1676 case SERVFAIL:
1677 h_errno = TRY_AGAIN;
1678 break;
1679 case NOERROR:
1680 h_errno = NO_DATA;
1681 break;
1682 case FORMERR:
1683 case NOTIMP:
1684 case REFUSED:
1685 default:
1686 h_errno = NO_RECOVERY;
1687 break;
1688 }
1689 free(buf);
1690 return (-1);
1691 }
1692 free(buf);
1693 return (ancount);
1694}
1695
1696/*
1697 * Formulate a normal query, send, and retrieve answer in supplied buffer.
1698 * Return the size of the response on success, -1 on error.
1699 * If enabled, implement search rules until answer or unrecoverable failure
1700 * is detected. Error code, if any, is left in h_errno.
1701 */
1702static int
1703res_searchN(name, target)
1704 const char *name; /* domain name */
1705 struct res_target *target;
1706{
1707 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
1708 const char *cp, * const *domain;
1709 HEADER *hp = (HEADER *)(void *)target->answer; /*XXX*/
1710 u_int dots;
1711 int trailing_dot, ret, saved_herrno;
1712 int got_nodata = 0, got_servfail = 0, tried_as_is = 0;
1713
1714 if ((_resp->options & RES_INIT) == 0 && res_init() == -1) {
1715 h_errno = NETDB_INTERNAL;
1716 return (-1);
1717 }
1718
1719 errno = 0;
1720 h_errno = HOST_NOT_FOUND; /* default, if we never query */
1721 dots = 0;
1722 for (cp = name; *cp; cp++)
1723 dots += (*cp == '.');
1724 trailing_dot = 0;
1725 if (cp > name && *--cp == '.')
1726 trailing_dot++;
1727
1728 /*
1729 * if there aren't any dots, it could be a user-level alias
1730 */
1731 if (!dots && (cp = __hostalias(name)) != NULL)
1732 return (res_queryN(cp, target));
1733
1734 /*
1735 * If there are dots in the name already, let's just give it a try
1736 * 'as is'. The threshold can be set with the "ndots" option.
1737 */
1738 saved_herrno = -1;
1739 if (dots >= _resp->ndots) {
1740 ret = res_querydomainN(name, NULL, target);
1741 if (ret > 0)
1742 return (ret);
1743 saved_herrno = h_errno;
1744 tried_as_is++;
1745 }
1746
1747 /*
1748 * We do at least one level of search if
1749 * - there is no dot and RES_DEFNAME is set, or
1750 * - there is at least one dot, there is no trailing dot,
1751 * and RES_DNSRCH is set.
1752 */
1753 if ((!dots && (_resp->options & RES_DEFNAMES)) ||
1754 (dots && !trailing_dot && (_resp->options & RES_DNSRCH))) {
1755 int done = 0;
1756
1757 for (domain = (const char * const *)_resp->dnsrch;
1758 *domain && !done;
1759 domain++) {
1760
1761 ret = res_querydomainN(name, *domain, target);
1762 if (ret > 0)
1763 return (ret);
1764
1765 /*
1766 * If no server present, give up.
1767 * If name isn't found in this domain,
1768 * keep trying higher domains in the search list
1769 * (if that's enabled).
1770 * On a NO_DATA error, keep trying, otherwise
1771 * a wildcard entry of another type could keep us
1772 * from finding this entry higher in the domain.
1773 * If we get some other error (negative answer or
1774 * server failure), then stop searching up,
1775 * but try the input name below in case it's
1776 * fully-qualified.
1777 */
1778 if (errno == ECONNREFUSED) {
1779 h_errno = TRY_AGAIN;
1780 return (-1);
1781 }
1782
1783 switch (h_errno) {
1784 case NO_DATA:
1785 got_nodata++;
1786 /* FALLTHROUGH */
1787 case HOST_NOT_FOUND:
1788 /* keep trying */
1789 break;
1790 case TRY_AGAIN:
1791 if (hp->rcode == SERVFAIL) {
1792 /* try next search element, if any */
1793 got_servfail++;
1794 break;
1795 }
1796 /* FALLTHROUGH */
1797 default:
1798 /* anything else implies that we're done */
1799 done++;
1800 }
1801 /*
1802 * if we got here for some reason other than DNSRCH,
1803 * we only wanted one iteration of the loop, so stop.
1804 */
1805 if (!(_resp->options & RES_DNSRCH))
1806 done++;
1807 }
1808 }
1809
1810 /*
1811 * if we have not already tried the name "as is", do that now.
1812 * note that we do this regardless of how many dots were in the
1813 * name or whether it ends with a dot.
1814 */
1815 if (!tried_as_is) {
1816 ret = res_querydomainN(name, NULL, target);
1817 if (ret > 0)
1818 return (ret);
1819 }
1820
1821 /*
1822 * if we got here, we didn't satisfy the search.
1823 * if we did an initial full query, return that query's h_errno
1824 * (note that we wouldn't be here if that query had succeeded).
1825 * else if we ever got a nodata, send that back as the reason.
1826 * else send back meaningless h_errno, that being the one from
1827 * the last DNSRCH we did.
1828 */
1829 if (saved_herrno != -1)
1830 h_errno = saved_herrno;
1831 else if (got_nodata)
1832 h_errno = NO_DATA;
1833 else if (got_servfail)
1834 h_errno = TRY_AGAIN;
1835 return (-1);
1836}
1837
1838/*
1839 * Perform a call on res_query on the concatenation of name and domain,
1840 * removing a trailing dot from name if domain is NULL.
1841 */
1842static int
1843res_querydomainN(name, domain, target)
1844 const char *name, *domain;
1845 struct res_target *target;
1846{
1847 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
1848 char nbuf[MAXDNAME];
1849 const char *longname = nbuf;
1850 size_t n, d;
1851
1852 if ((_resp->options & RES_INIT) == 0 && res_init() == -1) {
1853 h_errno = NETDB_INTERNAL;
1854 return (-1);
1855 }
1856#ifdef DEBUG
1857 if (_resp->options & RES_DEBUG)
1858 printf(";; res_querydomain(%s, %s)\n",
1859 name, domain?domain:"<Nil>");
1860#endif
1861 if (domain == NULL) {
1862 /*
1863 * Check for trailing '.';
1864 * copy without '.' if present.
1865 */
1866 n = strlen(name);
1867 if (n >= MAXDNAME) {
1868 h_errno = NO_RECOVERY;
1869 return (-1);
1870 }
1871 if (n > 0 && name[--n] == '.') {
1872 strlcpy(nbuf, name, n + 1);
1873 } else
1874 longname = name;
1875 } else {
1876 n = strlen(name);
1877 d = strlen(domain);
1878 if (n + d + 1 >= MAXDNAME) {
1879 h_errno = NO_RECOVERY;
1880 return (-1);
1881 }
1882 snprintf(nbuf, sizeof(nbuf), "%s.%s", name, domain);
1883 }
1884 return (res_queryN(longname, target));
1885}
diff --git a/src/lib/libc/net/gethostbyname.3 b/src/lib/libc/net/gethostbyname.3
index bac0368296..51377dbc21 100644
--- a/src/lib/libc/net/gethostbyname.3
+++ b/src/lib/libc/net/gethostbyname.3
@@ -1,4 +1,4 @@
1.\" $NetBSD: gethostbyname.3,v 1.6 1995/02/25 06:20:28 cgd Exp $ 1.\" $OpenBSD: gethostbyname.3,v 1.22 2004/03/14 18:05:37 jmc Exp $
2.\" 2.\"
3.\" Copyright (c) 1983, 1987, 1991, 1993 3.\" Copyright (c) 1983, 1987, 1991, 1993
4.\" The Regents of the University of California. All rights reserved. 4.\" The Regents of the University of California. All rights reserved.
@@ -11,11 +11,7 @@
11.\" 2. Redistributions in binary form must reproduce the above copyright 11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the 12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution. 13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software 14.\" 3. Neither the name of the University nor the names of its contributors
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 15.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission. 16.\" without specific prior written permission.
21.\" 17.\"
@@ -31,17 +27,17 @@
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE. 28.\" SUCH DAMAGE.
33.\" 29.\"
34.\" @(#)gethostbyname.3 8.2 (Berkeley) 4/19/94 30.Dd March 13, 1997
35.\"
36.Dd April 19, 1994
37.Dt GETHOSTBYNAME 3 31.Dt GETHOSTBYNAME 3
38.Os BSD 4.2 32.Os
39.Sh NAME 33.Sh NAME
40.Nm gethostbyname , 34.Nm gethostbyname ,
35.Nm gethostbyname2 ,
41.Nm gethostbyaddr , 36.Nm gethostbyaddr ,
42.Nm gethostent , 37.Nm gethostent ,
43.Nm sethostent , 38.Nm sethostent ,
44.Nm endhostent , 39.Nm endhostent ,
40.Nm hstrerror ,
45.Nm herror 41.Nm herror
46.Nd get network host entry 42.Nd get network host entry
47.Sh SYNOPSIS 43.Sh SYNOPSIS
@@ -50,30 +46,38 @@
50.Ft struct hostent * 46.Ft struct hostent *
51.Fn gethostbyname "const char *name" 47.Fn gethostbyname "const char *name"
52.Ft struct hostent * 48.Ft struct hostent *
53.Fn gethostbyaddr "const char *addr" "int len" "int type" 49.Fn gethostbyname2 "const char *name" "int af"
50.Ft struct hostent *
51.Fn gethostbyaddr "const char *addr" "int len" "int af"
54.Ft struct hostent * 52.Ft struct hostent *
55.Fn gethostent void 53.Fn gethostent void
54.Ft void
56.Fn sethostent "int stayopen" 55.Fn sethostent "int stayopen"
56.Ft void
57.Fn endhostent void 57.Fn endhostent void
58.Fn herror "char *string" 58.Ft void
59.Fn herror "const char *string"
60.Ft const char *
61.Fn hstrerror "int err"
59.Sh DESCRIPTION 62.Sh DESCRIPTION
60The 63The
61.Fn gethostbyname 64.Fn gethostbyname ,
65.Fn gethostbyname2
62and 66and
63.Fn gethostbyaddr 67.Fn gethostbyaddr
64functions 68functions each return a pointer to an object with the following structure
65each return a pointer to an object with the 69describing an internet host referenced by name or by address, respectively.
66following structure describing an internet host 70This structure contains either information obtained from the name server (i.e.,
67referenced by name or by address, respectively. 71.Xr resolver 3
68This structure contains either the information obtained from the name server, 72and
69.Xr named 8 , 73.Xr named 8 ) ,
70broken-out fields from a line in 74broken-out fields from a line in
71.Pa /etc/hosts , 75.Pa /etc/hosts ,
72or database entries supplied by the 76or database entries supplied by the
73.Xr yp 8 77.Xr yp 8
74system . 78system.
75If the local name server is not running these routines do a lookup in 79.Xr resolv.conf 5
76.Pa /etc/hosts . 80describes how the particular database is chosen.
77.Bd -literal 81.Bd -literal
78struct hostent { 82struct hostent {
79 char *h_name; /* official name of host */ 83 char *h_name; /* official name of host */
@@ -90,36 +94,50 @@ The members of this structure are:
90.It Fa h_name 94.It Fa h_name
91Official name of the host. 95Official name of the host.
92.It Fa h_aliases 96.It Fa h_aliases
93A zero terminated array of alternate names for the host. 97A NULL-terminated array of alternate names for the host.
94.It Fa h_addrtype 98.It Fa h_addrtype
95The type of address being returned; currently always 99The type of address being returned.
96.Dv AF_INET .
97.It Fa h_length 100.It Fa h_length
98The length, in bytes, of the address. 101The length, in bytes, of the address.
99.It Fa h_addr_list 102.It Fa h_addr_list
100A zero terminated array of network addresses for the host. 103A zero-terminated array of network addresses for the host.
101Host addresses are returned in network byte order. 104Host addresses are returned in network byte order.
102.It Fa h_addr 105.It Fa h_addr
103The first address in 106The first address in
104.Fa h_addr_list ; 107.Fa h_addr_list ;
105this is for backward compatibility. 108this is for backward compatibility.
109.El
106.Pp 110.Pp
107When using the nameserver, 111The function
108.Fn gethostbyname 112.Fn gethostbyname
109will search for the named host in the current domain and its parents 113will search for the named host in the current domain and its parents
110unless the name ends in a dot. 114using the search lookup semantics detailed in
111If the name contains no dot, and if the environment variable 115.Xr resolv.conf 5
112.Dq Ev HOSTALIASES 116and
113contains the name of an alias file, the alias file will first be searched 117.Xr hostname 7 .
114for an alias matching the input name. 118.Pp
115See 119.Fn gethostbyname2
116.Xr hostname 7 120is an advanced form of
117for the domain search procedure and the alias file format. 121.Fn gethostbyname
122which allows lookups in address families other than
123.Dv AF_INET .
124Currently, the only supported address family besides
125.Dv AF_INET
126is
127.Dv AF_INET6 .
128.Pp
129The
130.Fn gethostbyaddr
131function will search for the specified address of length
132.Fa len
133in the address family
134.Fa af .
135The only address family currently supported is
136.Dv AF_INET .
118.Pp 137.Pp
119The 138The
120.Fn sethostent 139.Fn sethostent
121function 140function may be used to request the use of a connected
122may be used to request the use of a connected
123.Tn TCP 141.Tn TCP
124socket for queries. 142socket for queries.
125If the 143If the
@@ -127,7 +145,7 @@ If the
127flag is non-zero, 145flag is non-zero,
128this sets the option to send all queries to the name server using 146this sets the option to send all queries to the name server using
129.Tn TCP 147.Tn TCP
130and to retain the connection after each call to 148and to retain the connection after each call to
131.Fn gethostbyname 149.Fn gethostbyname
132or 150or
133.Fn gethostbyaddr . 151.Fn gethostbyaddr .
@@ -137,17 +155,46 @@ datagrams.
137.Pp 155.Pp
138The 156The
139.Fn endhostent 157.Fn endhostent
140function 158function closes the
141closes the
142.Tn TCP 159.Tn TCP
143connection. 160connection.
161.Pp
162The
163.Fn herror
164function prints an error message describing the failure.
165If its argument
166.Fa string
167is non-null,
168it is prepended to the message string and separated from it by a colon
169.Pq Ql \&:
170and a space.
171The error message is printed with a trailing newline.
172The contents of the error message is the same as that returned by
173.Fn hstrerror
174with argument
175.Fa h_errno .
176.Sh ENVIRONMENT
177.Bl -tag -width HOSTALIASES
178.It HOSTALIASES
179A file containing local host aliases.
180See
181.Xr hostname 7
182for more information.
183.It RES_OPTIONS
184A list of options to override the resolver's internal defaults.
185See
186.Xr resolver 3
187for more information.
188.El
144.Sh FILES 189.Sh FILES
145.Bl -tag -width /etc/hosts -compact 190.Bl -tag -width /etc/resolv.conf -compact
146.It Pa /etc/hosts 191.It Pa /etc/hosts
192.It Pa /etc/resolv.conf
147.El 193.El
148.Sh DIAGNOSTICS 194.Sh DIAGNOSTICS
149Error return status from 195Error return status from
150.Fn gethostbyname 196.Fn gethostbyname ,
197.Fn gethostbyname2 ,
151and 198and
152.Fn gethostbyaddr 199.Fn gethostbyaddr
153is indicated by return of a null pointer. 200is indicated by return of a null pointer.
@@ -155,15 +202,6 @@ The external integer
155.Va h_errno 202.Va h_errno
156may then be checked to see whether this is a temporary failure 203may then be checked to see whether this is a temporary failure
157or an invalid or unknown host. 204or an invalid or unknown host.
158The routine
159.Fn herror
160can be used to print an error message describing the failure.
161If its argument
162.Fa string
163is
164.Pf non Dv -NULL ,
165it is printed, followed by a colon and a space.
166The error message is printed with a trailing newline.
167.Pp 205.Pp
168The variable 206The variable
169.Va h_errno 207.Va h_errno
@@ -180,75 +218,79 @@ A retry at some later time may succeed.
180Some unexpected server failure was encountered. 218Some unexpected server failure was encountered.
181This is a non-recoverable error. 219This is a non-recoverable error.
182.It Dv NO_DATA 220.It Dv NO_DATA
183The requested name is valid but does not have an IP address; 221The requested name is valid but does not have an IP address;
184this is not a temporary error. 222this is not a temporary error.
185This means that the name is known to the name server but there is no address 223This means that the name is known to the name server but there is no address
186associated with this name. 224associated with this name.
187Another type of request to the name server using this domain name 225Another type of request to the name server using this domain name
188will result in an answer; 226will result in an answer;
189for example, a mail-forwarder may be registered for this domain. 227for example, a mail-forwarder may be registered for this domain.
228.It Dv NETDB_INTERNAL
229An internal error occurred.
230This may occurs when an address family other than
231.Dv AF_INET
232or
233.Dv AF_INET6
234is specified or when a resource is unable to be allocated.
235.It Dv NETDB_SUCCESS
236The function completed successfully.
190.El 237.El
191.Sh SEE ALSO 238.Sh SEE ALSO
239.Xr getaddrinfo 3 ,
240.Xr getnameinfo 3 ,
192.Xr resolver 3 , 241.Xr resolver 3 ,
193.Xr hosts 5 , 242.Xr hosts 5 ,
243.Xr resolv.conf 5 ,
194.Xr hostname 7 , 244.Xr hostname 7 ,
195.Xr named 8 245.Xr named 8
196.Sh CAVEAT 246.Sh HISTORY
197The 247The
198.Fn gethostent 248.Fn herror
199function 249function appeared in
200is defined, and 250.Bx 4.3 .
201.Fn sethostent 251The
252.Fn endhostent ,
253.Fn gethostbyaddr ,
254.Fn gethostbyname ,
255.Fn gethostent ,
202and 256and
203.Fn endhostent 257.Fn sethostent
204are redefined, 258functions appeared in
205when 259.Bx 4.2 .
206.Xr libc 3 260.Sh CAVEATS
207is built to use only the routines to lookup in 261If the search routines in
262.Xr resolv.conf 5
263decide to read the
208.Pa /etc/hosts 264.Pa /etc/hosts
209and not the name server. 265file,
210.Pp
211The
212.Fn gethostent 266.Fn gethostent
213function 267and other functions will
214reads the next line of 268read the next line of the file,
215.Pa /etc/hosts , 269re-opening the file if necessary.
216opening the file if necessary.
217.Pp 270.Pp
218The 271The
219.Fn sethostent 272.Fn sethostent
220function 273function opens and/or rewinds the file
221opens and/or rewinds the file
222.Pa /etc/hosts . 274.Pa /etc/hosts .
223If the 275If the
224.Fa stayopen 276.Fa stayopen
225argument is non-zero, 277argument is non-zero, the file will not be closed after each call to
226the file will not be closed after each call to 278.Fn gethostbyname ,
227.Fn gethostbyname 279.Fn gethostbyname2 ,
228or 280or
229.Fn gethostbyaddr . 281.Fn gethostbyaddr .
230.Pp 282.Pp
231The 283The
232.Fn endhostent 284.Fn endhostent
233function 285function closes the file.
234closes the file.
235.Sh HISTORY
236The
237.Fn herror
238function appeared in
239.Bx 4.3 .
240The
241.Fn endhostent ,
242.Fn gethostbyaddr ,
243.Fn gethostbyname ,
244.Fn gethostent ,
245and
246.Fn sethostent
247functions appeared in
248.Bx 4.2 .
249.Sh BUGS 286.Sh BUGS
250These functions use static data storage; 287These functions use static data storage;
251if the data is needed for future use, it should be 288if the data is needed for future use, it should be
252copied before any subsequent calls overwrite it. 289copied before any subsequent calls overwrite it.
253Only the Internet 290Only the Internet
254address format is currently understood. 291address formats are currently understood.
292.Pp
293YP does not support any address families other than
294.Dv AF_INET
295and uses
296the traditional database format.
diff --git a/src/lib/libc/net/gethostnamadr.c b/src/lib/libc/net/gethostnamadr.c
index ec3f14a900..ee4af36191 100644
--- a/src/lib/libc/net/gethostnamadr.c
+++ b/src/lib/libc/net/gethostnamadr.c
@@ -1,5 +1,3 @@
1/* $NetBSD: gethostnamadr.c,v 1.13 1995/05/21 16:21:14 mycroft Exp $ */
2
3/*- 1/*-
4 * Copyright (c) 1985, 1988, 1993 2 * Copyright (c) 1985, 1988, 1993
5 * The Regents of the University of California. All rights reserved. 3 * The Regents of the University of California. All rights reserved.
@@ -12,11 +10,7 @@
12 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission. 15 * without specific prior written permission.
22 * 16 *
@@ -54,12 +48,7 @@
54 */ 48 */
55 49
56#if defined(LIBC_SCCS) && !defined(lint) 50#if defined(LIBC_SCCS) && !defined(lint)
57#if 0 51static const char rcsid[] = "$OpenBSD: gethostnamadr.c,v 1.59 2003/10/06 19:18:09 millert Exp $";
58static char sccsid[] = "@(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93";
59static char rcsid[] = "$Id: gethnamaddr.c,v 4.9.1.1 1993/05/02 22:43:03 vixie Rel ";
60#else
61static char rcsid[] = "$NetBSD: gethostnamadr.c,v 1.13 1995/05/21 16:21:14 mycroft Exp $";
62#endif
63#endif /* LIBC_SCCS and not lint */ 52#endif /* LIBC_SCCS and not lint */
64 53
65#include <sys/param.h> 54#include <sys/param.h>
@@ -73,11 +62,17 @@ static char rcsid[] = "$NetBSD: gethostnamadr.c,v 1.13 1995/05/21 16:21:14 mycro
73#include <ctype.h> 62#include <ctype.h>
74#include <errno.h> 63#include <errno.h>
75#include <string.h> 64#include <string.h>
65#include <syslog.h>
66#include <stdlib.h>
76#ifdef YP 67#ifdef YP
77#include <rpc/rpc.h> 68#include <rpc/rpc.h>
78#include <rpcsvc/yp_prot.h> 69#include <rpcsvc/yp.h>
79#include <rpcsvc/ypclnt.h> 70#include <rpcsvc/ypclnt.h>
71#include "ypinternal.h"
80#endif 72#endif
73#include "thread_private.h"
74
75#define MULTI_PTRS_ARE_ALIASES 1 /* XXX - experimental */
81 76
82#define MAXALIASES 35 77#define MAXALIASES 35
83#define MAXADDRS 35 78#define MAXADDRS 35
@@ -91,47 +86,101 @@ static char *__ypdomain;
91static struct hostent host; 86static struct hostent host;
92static char *host_aliases[MAXALIASES]; 87static char *host_aliases[MAXALIASES];
93static char hostbuf[BUFSIZ+1]; 88static char hostbuf[BUFSIZ+1];
94static struct in_addr host_addr; 89static union {
90 struct in_addr _host_in_addr;
91 u_char _host_addr[16]; /* IPv4 or IPv6 */
92} _host_addr_u;
93#define host_addr _host_addr_u._host_addr
95static FILE *hostf = NULL; 94static FILE *hostf = NULL;
96static int stayopen = 0; 95static int stayopen = 0;
97 96
98#if PACKETSZ > 1024 97static void map_v4v6_address(const char *src, char *dst);
99#define MAXPACKET PACKETSZ 98static void map_v4v6_hostent(struct hostent *hp, char **bp, char *);
100#else 99
101#define MAXPACKET 1024 100#ifdef RESOLVSORT
101static void addrsort(char **, int);
102#endif 102#endif
103 103
104int _hokchar(const char *);
105
106static const char AskedForGot[] =
107 "gethostby*.getanswer: asked for \"%s\", got \"%s\"";
108
109#define MAXPACKET (64*1024)
110
104typedef union { 111typedef union {
105 HEADER hdr; 112 HEADER hdr;
106 u_char buf[MAXPACKET]; 113 u_char buf[MAXPACKET];
107} querybuf; 114} querybuf;
108 115
109typedef union { 116typedef union {
110 int32_t al; 117 int32_t al;
111 char ac; 118 char ac;
112} align; 119} align;
113 120
114static int qcomp __P((struct in_addr **, struct in_addr **)); 121static struct hostent *getanswer(const querybuf *, int, const char *, int);
115static struct hostent *getanswer __P((querybuf *, int, int));
116 122
117extern int h_errno; 123extern int h_errno;
118 124
125int
126_hokchar(const char *p)
127{
128 char c;
129
130 /*
131 * Many people do not obey RFC 822 and 1035. The valid
132 * characters are a-z, A-Z, 0-9, '-' and . But the others
133 * tested for below can happen, and we must be more permissive
134 * than the resolver until those idiots clean up their act.
135 * We let '/' through, but not '..'
136 */
137 while ((c = *p++)) {
138 if (('a' <= c && c <= 'z') ||
139 ('A' <= c && c <= 'Z') ||
140 ('0' <= c && c <= '9'))
141 continue;
142 if (strchr("-_/", c))
143 continue;
144 if (c == '.' && *p != '.')
145 continue;
146 return 0;
147 }
148 return 1;
149}
150
119static struct hostent * 151static struct hostent *
120getanswer(answer, anslen, iquery) 152getanswer(const querybuf *answer, int anslen, const char *qname, int qtype)
121 querybuf *answer;
122 int anslen;
123 int iquery;
124{ 153{
125 register HEADER *hp; 154 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
126 register u_char *cp; 155 const HEADER *hp;
127 register int n; 156 const u_char *cp, *eom;
128 u_char *eom; 157 char tbuf[MAXDNAME];
129 char *bp, **ap; 158 char *bp, **ap, **hap, *ep;
130 int type, class, buflen, ancount, qdcount; 159 int type, class, ancount, qdcount, n;
131 int haveanswer, getclass = C_ANY; 160 int haveanswer, had_error, toobig = 0;
132 char **hap; 161 const char *tname;
162 int (*name_ok)(const char *);
133 163
164 tname = qname;
165 host.h_name = NULL;
134 eom = answer->buf + anslen; 166 eom = answer->buf + anslen;
167 switch (qtype) {
168 case T_A:
169 case T_AAAA:
170#ifdef USE_RESOLV_NAME_OK
171 name_ok = res_hnok;
172 break;
173#endif
174 case T_PTR:
175#ifdef USE_RESOLV_NAME_OK
176 name_ok = res_dnok;
177#else
178 name_ok = _hokchar;
179#endif
180 break;
181 default:
182 return (NULL);
183 }
135 /* 184 /*
136 * find first satisfactory answer 185 * find first satisfactory answer
137 */ 186 */
@@ -139,31 +188,28 @@ getanswer(answer, anslen, iquery)
139 ancount = ntohs(hp->ancount); 188 ancount = ntohs(hp->ancount);
140 qdcount = ntohs(hp->qdcount); 189 qdcount = ntohs(hp->qdcount);
141 bp = hostbuf; 190 bp = hostbuf;
142 buflen = sizeof(hostbuf); 191 ep = hostbuf + sizeof hostbuf;
143 cp = answer->buf + sizeof(HEADER); 192 cp = answer->buf + HFIXEDSZ;
144 if (qdcount) { 193 if (qdcount != 1) {
145 if (iquery) { 194 h_errno = NO_RECOVERY;
146 if ((n = dn_expand((u_char *)answer->buf, 195 return (NULL);
147 (u_char *)eom, (u_char *)cp, (u_char *)bp, 196 }
148 buflen)) < 0) { 197 n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
149 h_errno = NO_RECOVERY; 198 if ((n < 0) || !(*name_ok)(bp)) {
150 return ((struct hostent *) NULL); 199 h_errno = NO_RECOVERY;
151 } 200 return (NULL);
152 cp += n + QFIXEDSZ; 201 }
153 host.h_name = bp; 202 cp += n + QFIXEDSZ;
154 n = strlen(bp) + 1; 203 if (qtype == T_A || qtype == T_AAAA) {
155 bp += n; 204 /* res_send() has already verified that the query name is the
156 buflen -= n; 205 * same as the one we sent; this just gets the expanded name
157 } else 206 * (i.e., with the succeeding search-domain tacked on).
158 cp += __dn_skipname(cp, eom) + QFIXEDSZ; 207 */
159 while (--qdcount > 0) 208 n = strlen(bp) + 1; /* for the \0 */
160 cp += __dn_skipname(cp, eom) + QFIXEDSZ; 209 host.h_name = bp;
161 } else if (iquery) { 210 bp += n;
162 if (hp->aa) 211 /* The qname can be abbreviated, but h_name is now absolute. */
163 h_errno = HOST_NOT_FOUND; 212 qname = host.h_name;
164 else
165 h_errno = TRY_AGAIN;
166 return ((struct hostent *) NULL);
167 } 213 }
168 ap = host_aliases; 214 ap = host_aliases;
169 *ap = NULL; 215 *ap = NULL;
@@ -172,103 +218,321 @@ getanswer(answer, anslen, iquery)
172 *hap = NULL; 218 *hap = NULL;
173 host.h_addr_list = h_addr_ptrs; 219 host.h_addr_list = h_addr_ptrs;
174 haveanswer = 0; 220 haveanswer = 0;
175 while (--ancount >= 0 && cp < eom) { 221 had_error = 0;
176 if ((n = dn_expand((u_char *)answer->buf, (u_char *)eom, 222 while (ancount-- > 0 && cp < eom && !had_error) {
177 (u_char *)cp, (u_char *)bp, buflen)) < 0) 223 n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
224 if ((n < 0) || !(*name_ok)(bp)) {
225 had_error++;
226 continue;
227 }
228 cp += n; /* name */
229 if (cp >= eom)
178 break; 230 break;
179 cp += n;
180 type = _getshort(cp); 231 type = _getshort(cp);
181 cp += sizeof(u_int16_t); 232 cp += INT16SZ; /* type */
233 if (cp >= eom)
234 break;
182 class = _getshort(cp); 235 class = _getshort(cp);
183 cp += sizeof(u_int16_t) + sizeof(u_int32_t); 236 cp += INT16SZ + INT32SZ; /* class, TTL */
237 if (cp >= eom)
238 break;
184 n = _getshort(cp); 239 n = _getshort(cp);
185 cp += sizeof(u_int16_t); 240 cp += INT16SZ; /* len */
186 if (type == T_CNAME) { 241 if (cp >= eom)
242 break;
243 if (type == T_SIG) {
244 /* XXX - ignore signatures as we don't use them yet */
187 cp += n; 245 cp += n;
246 continue;
247 }
248 if (class != C_IN) {
249 /* XXX - debug? syslog? */
250 cp += n;
251 continue; /* XXX - had_error++ ? */
252 }
253 if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME) {
188 if (ap >= &host_aliases[MAXALIASES-1]) 254 if (ap >= &host_aliases[MAXALIASES-1])
189 continue; 255 continue;
256 n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
257 if ((n < 0) || !(*name_ok)(tbuf)) {
258 had_error++;
259 continue;
260 }
261 cp += n;
262 /* Store alias. */
190 *ap++ = bp; 263 *ap++ = bp;
191 n = strlen(bp) + 1; 264 n = strlen(bp) + 1; /* for the \0 */
192 bp += n; 265 bp += n;
193 buflen -= n; 266 /* Get canonical name. */
194 continue; 267 n = strlen(tbuf) + 1; /* for the \0 */
195 } 268 if (n > ep - bp) {
196 if (iquery && type == T_PTR) { 269 had_error++;
197 if ((n = dn_expand((u_char *)answer->buf, 270 continue;
198 (u_char *)eom, (u_char *)cp, (u_char *)bp, 271 }
199 buflen)) < 0) 272 strlcpy(bp, tbuf, ep - bp);
200 break;
201 cp += n;
202 host.h_name = bp; 273 host.h_name = bp;
203 return(&host); 274 bp += n;
275 continue;
204 } 276 }
205 if (iquery || type != T_A) { 277 if (qtype == T_PTR && type == T_CNAME) {
206#ifdef DEBUG 278 n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
207 if (_res.options & RES_DEBUG) 279#ifdef USE_RESOLV_NAME_OK
208 printf("unexpected answer type %d, size %d\n", 280 if ((n < 0) || !res_hnok(tbuf)) {
209 type, n); 281#else
282 if ((n < 0) || !_hokchar(tbuf)) {
210#endif 283#endif
284 had_error++;
285 continue;
286 }
211 cp += n; 287 cp += n;
288 /* Get canonical name. */
289 n = strlen(tbuf) + 1; /* for the \0 */
290 if (n > ep - bp) {
291 had_error++;
292 continue;
293 }
294 strlcpy(bp, tbuf, ep - bp);
295 tname = bp;
296 bp += n;
212 continue; 297 continue;
213 } 298 }
214 if (haveanswer) { 299 if (type != qtype) {
215 if (n != host.h_length) { 300 syslog(LOG_NOTICE|LOG_AUTH,
301 "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",
302 qname, p_class(C_IN), p_type(qtype),
303 p_type(type));
304 cp += n;
305 continue; /* XXX - had_error++ ? */
306 }
307 switch (type) {
308 case T_PTR:
309 if (strcasecmp(tname, bp) != 0) {
310 syslog(LOG_NOTICE|LOG_AUTH,
311 AskedForGot, qname, bp);
216 cp += n; 312 cp += n;
217 continue; 313 continue; /* XXX - had_error++ ? */
314 }
315 n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
316#ifdef USE_RESOLV_NAME_OK
317 if ((n < 0) || !res_hnok(bp)) {
318#else
319 if ((n < 0) || !_hokchar(bp)) {
320#endif
321 had_error++;
322 break;
323 }
324#if MULTI_PTRS_ARE_ALIASES
325 cp += n;
326 if (!haveanswer)
327 host.h_name = bp;
328 else if (ap < &host_aliases[MAXALIASES-1])
329 *ap++ = bp;
330 else
331 n = -1;
332 if (n != -1) {
333 n = strlen(bp) + 1; /* for the \0 */
334 bp += n;
335 }
336 break;
337#else
338 host.h_name = bp;
339 if (_resp->options & RES_USE_INET6) {
340 n = strlen(bp) + 1; /* for the \0 */
341 bp += n;
342 map_v4v6_hostent(&host, &bp, ep);
218 } 343 }
219 if (class != getclass) { 344 h_errno = NETDB_SUCCESS;
345 return (&host);
346#endif
347 case T_A:
348 case T_AAAA:
349 if (strcasecmp(host.h_name, bp) != 0) {
350 syslog(LOG_NOTICE|LOG_AUTH,
351 AskedForGot, host.h_name, bp);
352 cp += n;
353 continue; /* XXX - had_error++ ? */
354 }
355 if (n != host.h_length) {
220 cp += n; 356 cp += n;
221 continue; 357 continue;
222 } 358 }
223 } else { 359 if (type == T_AAAA) {
224 host.h_length = n; 360 struct in6_addr in6;
225 getclass = class; 361 memcpy(&in6, cp, IN6ADDRSZ);
226 host.h_addrtype = (class == C_IN) ? AF_INET : AF_UNSPEC; 362 if (IN6_IS_ADDR_V4MAPPED(&in6)) {
227 if (!iquery) { 363 cp += n;
364 continue;
365 }
366 }
367 if (!haveanswer) {
368 int nn;
369
228 host.h_name = bp; 370 host.h_name = bp;
229 bp += strlen(bp) + 1; 371 nn = strlen(bp) + 1; /* for the \0 */
372 bp += nn;
230 } 373 }
231 }
232 374
233 bp += sizeof(align) - ((u_long)bp % sizeof(align)); 375 bp += sizeof(align) - ((u_long)bp % sizeof(align));
234 376
235 if (bp + n >= &hostbuf[sizeof(hostbuf)]) { 377 if (bp + n >= &hostbuf[sizeof hostbuf]) {
236#ifdef DEBUG 378#ifdef DEBUG
237 if (_res.options & RES_DEBUG) 379 if (_resp->options & RES_DEBUG)
238 printf("size (%d) too big\n", n); 380 printf("size (%d) too big\n", n);
239#endif 381#endif
382 had_error++;
383 continue;
384 }
385 if (hap >= &h_addr_ptrs[MAXADDRS-1]) {
386 if (!toobig++)
387#ifdef DEBUG
388 if (_resp->options & RES_DEBUG)
389 printf("Too many addresses (%d)\n", MAXADDRS);
390#endif
391 cp += n;
392 continue;
393 }
394 bcopy(cp, *hap++ = bp, n);
395 bp += n;
396 cp += n;
240 break; 397 break;
241 } 398 }
242 bcopy(cp, *hap++ = bp, n); 399 if (!had_error)
243 bp +=n; 400 haveanswer++;
244 cp += n;
245 haveanswer++;
246 } 401 }
247 if (haveanswer) { 402 if (haveanswer) {
248 *ap = NULL; 403 *ap = NULL;
249 *hap = NULL; 404 *hap = NULL;
250 if (_res.nsort) { 405# if defined(RESOLVSORT)
251 qsort(host.h_addr_list, haveanswer, 406 /*
252 sizeof(struct in_addr), 407 * Note: we sort even if host can take only one address
253 (int (*)__P((const void *, const void *)))qcomp); 408 * in its return structures - should give it the "best"
409 * address in that case, not some random one
410 */
411 if (_resp->nsort && haveanswer > 1 && qtype == T_A)
412 addrsort(h_addr_ptrs, haveanswer);
413# endif /*RESOLVSORT*/
414 if (!host.h_name) {
415 n = strlen(qname) + 1; /* for the \0 */
416 if (n > ep - bp)
417 goto try_again;
418 strlcpy(bp, qname, ep - bp);
419 host.h_name = bp;
420 bp += n;
254 } 421 }
422 if (_resp->options & RES_USE_INET6)
423 map_v4v6_hostent(&host, &bp, ep);
424 h_errno = NETDB_SUCCESS;
255 return (&host); 425 return (&host);
256 } else {
257 h_errno = TRY_AGAIN;
258 return ((struct hostent *) NULL);
259 } 426 }
427 try_again:
428 h_errno = TRY_AGAIN;
429 return (NULL);
430}
431
432#ifdef notyet
433/*
434 * XXX This is an extremely bogus implementation.
435 *
436 * FreeBSD has this interface:
437 * int gethostbyaddr_r(const char *addr, int len, int type,
438 * struct hostent *result, struct hostent_data *buffer)
439 */
440
441struct hostent *
442gethostbyname_r(const char *name, struct hostent *hp, char *buf, int buflen,
443 int *errorp)
444{
445 struct hostent *res;
446
447 res = gethostbyname(name);
448 *errorp = h_errno;
449 if (res == NULL)
450 return NULL;
451 memcpy(hp, res, sizeof *hp); /* XXX not sufficient */
452 return hp;
453}
454
455/*
456 * XXX This is an extremely bogus implementation.
457 */
458struct hostent *
459gethostbyaddr_r(const char *addr, int len, int af, struct hostent *he,
460 char *buf, int buflen, int *errorp)
461{
462 struct hostent * res;
463
464 res = gethostbyaddr(addr, len, af);
465 *errorp = h_errno;
466 if (res == NULL)
467 return NULL;
468 memcpy(he, res, sizeof *he); /* XXX not sufficient */
469 return he;
470}
471
472/* XXX RFC2133 expects a gethostbyname2_r() -- unimplemented */
473#endif
474
475struct hostent *
476gethostbyname(const char *name)
477{
478 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
479 struct hostent *hp;
480 extern struct hostent *_gethtbyname2(const char *, int);
481
482 if ((_resp->options & RES_INIT) == 0 && res_init() == -1)
483 hp = _gethtbyname2(name, AF_INET);
484
485 else if (_resp->options & RES_USE_INET6) {
486 hp = gethostbyname2(name, AF_INET6);
487 if (hp == NULL)
488 hp = gethostbyname2(name, AF_INET);
489 }
490 else
491 hp = gethostbyname2(name, AF_INET);
492 return hp;
260} 493}
261 494
262struct hostent * 495struct hostent *
263gethostbyname(name) 496gethostbyname2(const char *name, int af)
264 const char *name;
265{ 497{
266 querybuf buf; 498 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
267 register const char *cp; 499 querybuf *buf;
268 int n, i; 500 const char *cp;
269 extern struct hostent *_gethtbyname(), *_yp_gethtbyname(); 501 char *bp, *ep;
270 register struct hostent *hp; 502 int n, size, type, i;
503 struct hostent *hp;
271 char lookups[MAXDNSLUS]; 504 char lookups[MAXDNSLUS];
505 extern struct hostent *_gethtbyname2(const char *, int);
506 extern struct hostent *_yp_gethtbyname(const char *);
507
508 if ((_resp->options & RES_INIT) == 0 && res_init() == -1)
509 return (_gethtbyname2(name, af));
510
511 switch (af) {
512 case AF_INET:
513 size = INADDRSZ;
514 type = T_A;
515 break;
516 case AF_INET6:
517 size = IN6ADDRSZ;
518 type = T_AAAA;
519 break;
520 default:
521 h_errno = NETDB_INTERNAL;
522 errno = EAFNOSUPPORT;
523 return (NULL);
524 }
525
526 host.h_addrtype = af;
527 host.h_length = size;
528
529 /*
530 * if there aren't any dots, it could be a user-level alias.
531 * this is also done in res_query() since we are not the only
532 * function that looks up host names.
533 */
534 if (!strchr(name, '.') && (cp = __hostalias(name)))
535 name = cp;
272 536
273 /* 537 /*
274 * disallow names consisting only of digits/dots, unless 538 * disallow names consisting only of digits/dots, unless
@@ -284,122 +548,234 @@ gethostbyname(name)
284 * Fake up a hostent as if we'd actually 548 * Fake up a hostent as if we'd actually
285 * done a lookup. 549 * done a lookup.
286 */ 550 */
287 if (!inet_aton(name, &host_addr)) { 551 if (inet_pton(af, name, host_addr) <= 0) {
288 h_errno = HOST_NOT_FOUND; 552 h_errno = HOST_NOT_FOUND;
289 return((struct hostent *) NULL); 553 return (NULL);
290 } 554 }
291 host.h_name = (char *)name; 555 strlcpy(hostbuf, name, MAXHOSTNAMELEN);
556 bp = hostbuf + MAXHOSTNAMELEN;
557 ep = hostbuf + sizeof(hostbuf);
558 host.h_name = hostbuf;
292 host.h_aliases = host_aliases; 559 host.h_aliases = host_aliases;
293 host_aliases[0] = NULL; 560 host_aliases[0] = NULL;
294 host.h_addrtype = AF_INET; 561 h_addr_ptrs[0] = (char *)host_addr;
295 host.h_length = sizeof(u_int32_t);
296 h_addr_ptrs[0] = (char *)&host_addr;
297 h_addr_ptrs[1] = NULL; 562 h_addr_ptrs[1] = NULL;
298 host.h_addr_list = h_addr_ptrs; 563 host.h_addr_list = h_addr_ptrs;
564 if (_resp->options & RES_USE_INET6)
565 map_v4v6_hostent(&host, &bp, ep);
566 h_errno = NETDB_SUCCESS;
299 return (&host); 567 return (&host);
300 } 568 }
301 if (!isdigit(*cp) && *cp != '.') 569 if (!isdigit(*cp) && *cp != '.')
302 break; 570 break;
303 } 571 }
572 if ((isxdigit(name[0]) && strchr(name, ':') != NULL) ||
573 name[0] == ':')
574 for (cp = name;; ++cp) {
575 if (!*cp) {
576 if (*--cp == '.')
577 break;
578 /*
579 * All-IPv6-legal, no dot at the end.
580 * Fake up a hostent as if we'd actually
581 * done a lookup.
582 */
583 if (inet_pton(af, name, host_addr) <= 0) {
584 h_errno = HOST_NOT_FOUND;
585 return (NULL);
586 }
587 strlcpy(hostbuf, name, MAXHOSTNAMELEN);
588 bp = hostbuf + MAXHOSTNAMELEN;
589 ep = hostbuf + sizeof(hostbuf);
590 host.h_name = hostbuf;
591 host.h_aliases = host_aliases;
592 host_aliases[0] = NULL;
593 h_addr_ptrs[0] = (char *)host_addr;
594 h_addr_ptrs[1] = NULL;
595 host.h_addr_list = h_addr_ptrs;
596 h_errno = NETDB_SUCCESS;
597 return (&host);
598 }
599 if (!isxdigit(*cp) && *cp != ':' && *cp != '.')
600 break;
601 }
304 602
305 if ((_res.options & RES_INIT) == 0 && res_init() == -1) 603 bcopy(_resp->lookups, lookups, sizeof lookups);
306 return (_gethtbyname(name));
307
308 bcopy(_res.lookups, lookups, sizeof lookups);
309 if (lookups[0] == '\0') 604 if (lookups[0] == '\0')
310 strncpy(lookups, "bf", sizeof lookups); 605 strlcpy(lookups, "bf", sizeof lookups);
311 606
312 hp = (struct hostent *)NULL; 607 hp = (struct hostent *)NULL;
313 for (i = 0; i < MAXDNSLUS && hp == NULL && lookups[i]; i++) { 608 for (i = 0; i < MAXDNSLUS && hp == NULL && lookups[i]; i++) {
314 switch (lookups[i]) { 609 switch (lookups[i]) {
315#ifdef YP 610#ifdef YP
316 case 'y': 611 case 'y':
317 hp = _yp_gethtbyname(name); 612 /* YP only supports AF_INET. */
613 if (af == AF_INET)
614 hp = _yp_gethtbyname(name);
318 break; 615 break;
319#endif 616#endif
320 case 'b': 617 case 'b':
321 if ((n = res_search(name, C_IN, T_A, buf.buf, 618 buf = malloc(sizeof(*buf));
322 sizeof(buf))) < 0) { 619 if (buf == NULL)
620 break;
621 if ((n = res_search(name, C_IN, type, buf->buf,
622 sizeof(buf->buf))) < 0) {
623 free(buf);
323#ifdef DEBUG 624#ifdef DEBUG
324 if (_res.options & RES_DEBUG) 625 if (_resp->options & RES_DEBUG)
325 printf("res_search failed\n"); 626 printf("res_search failed\n");
326#endif 627#endif
327 break; 628 break;
328 } 629 }
329 hp = getanswer(&buf, n, 0); 630 hp = getanswer(buf, n, name, type);
631 free(buf);
330 break; 632 break;
331 case 'f': 633 case 'f':
332 hp = _gethtbyname(name); 634 hp = _gethtbyname2(name, af);
333 break; 635 break;
334 } 636 }
335 } 637 }
638 /* XXX h_errno not correct in all cases... */
336 return (hp); 639 return (hp);
337} 640}
338 641
339struct hostent * 642struct hostent *
340gethostbyaddr(addr, len, type) 643gethostbyaddr(const char *addr, int len, int af)
341 const char *addr;
342 int len, type;
343{ 644{
344 int n, i; 645 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
345 querybuf buf; 646 const u_char *uaddr = (const u_char *)addr;
346 register struct hostent *hp; 647 int n, size, i;
347 char qbuf[MAXDNAME]; 648 querybuf *buf;
348 extern struct hostent *_gethtbyaddr(), *_yp_gethtbyaddr(); 649 struct hostent *hp;
650 char qbuf[MAXDNAME+1], *qp, *ep;
349 char lookups[MAXDNSLUS]; 651 char lookups[MAXDNSLUS];
652 struct hostent *res;
653 extern struct hostent *_gethtbyaddr(const char *, int, int);
654 extern struct hostent *_yp_gethtbyaddr(const char *);
350 655
351 if (type != AF_INET) 656 if ((_resp->options & RES_INIT) == 0 && res_init() == -1) {
352 return ((struct hostent *) NULL); 657 res = _gethtbyaddr(addr, len, af);
353 (void)sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa", 658 return (res);
354 ((unsigned)addr[3] & 0xff), 659 }
355 ((unsigned)addr[2] & 0xff), 660
356 ((unsigned)addr[1] & 0xff), 661 if (af == AF_INET6 && len == IN6ADDRSZ &&
357 ((unsigned)addr[0] & 0xff)); 662 (IN6_IS_ADDR_LINKLOCAL((struct in6_addr *)uaddr) ||
358 663 IN6_IS_ADDR_SITELOCAL((struct in6_addr *)uaddr))) {
359 if ((_res.options & RES_INIT) == 0 && res_init() == -1) 664 h_errno = HOST_NOT_FOUND;
360 return (_gethtbyaddr(addr, len, type)); 665 return (NULL);
361 666 }
362 bcopy(_res.lookups, lookups, sizeof lookups); 667 if (af == AF_INET6 && len == IN6ADDRSZ &&
668 (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)uaddr) ||
669 IN6_IS_ADDR_V4COMPAT((struct in6_addr *)uaddr))) {
670 /* Unmap. */
671 addr += IN6ADDRSZ - INADDRSZ;
672 uaddr += IN6ADDRSZ - INADDRSZ;
673 af = AF_INET;
674 len = INADDRSZ;
675 }
676 switch (af) {
677 case AF_INET:
678 size = INADDRSZ;
679 break;
680 case AF_INET6:
681 size = IN6ADDRSZ;
682 break;
683 default:
684 errno = EAFNOSUPPORT;
685 h_errno = NETDB_INTERNAL;
686 return (NULL);
687 }
688 if (size != len) {
689 errno = EINVAL;
690 h_errno = NETDB_INTERNAL;
691 return (NULL);
692 }
693 ep = qbuf + sizeof(qbuf);
694 switch (af) {
695 case AF_INET:
696 (void) snprintf(qbuf, sizeof qbuf, "%u.%u.%u.%u.in-addr.arpa",
697 (uaddr[3] & 0xff), (uaddr[2] & 0xff),
698 (uaddr[1] & 0xff), (uaddr[0] & 0xff));
699 break;
700 case AF_INET6:
701 qp = qbuf;
702 for (n = IN6ADDRSZ - 1; n >= 0; n--) {
703 i = snprintf(qp, ep - qp, "%x.%x.",
704 uaddr[n] & 0xf, (uaddr[n] >> 4) & 0xf);
705 if (i <= 0) {
706 errno = EINVAL;
707 h_errno = NETDB_INTERNAL;
708 return (NULL);
709 }
710 qp += i;
711 }
712 break;
713 }
714
715 bcopy(_resp->lookups, lookups, sizeof lookups);
363 if (lookups[0] == '\0') 716 if (lookups[0] == '\0')
364 strncpy(lookups, "bf", sizeof lookups); 717 strlcpy(lookups, "bf", sizeof lookups);
365 718
366 hp = (struct hostent *)NULL; 719 hp = (struct hostent *)NULL;
367 for (i = 0; i < MAXDNSLUS && hp == NULL && lookups[i]; i++) { 720 for (i = 0; i < MAXDNSLUS && hp == NULL && lookups[i]; i++) {
368 switch (lookups[i]) { 721 switch (lookups[i]) {
369#ifdef YP 722#ifdef YP
370 case 'y': 723 case 'y':
371 hp = _yp_gethtbyaddr(addr, len, type); 724 /* YP only supports AF_INET. */
725 if (af == AF_INET)
726 hp = _yp_gethtbyaddr(addr);
372 break; 727 break;
373#endif 728#endif
374 case 'b': 729 case 'b':
375 n = res_query(qbuf, C_IN, T_PTR, (char *)&buf, sizeof(buf)); 730 if (af == AF_INET6)
731 strlcpy(qp, "ip6.arpa", ep - qp);
732 buf = malloc(sizeof(*buf));
733 if (!buf)
734 break;
735 n = res_query(qbuf, C_IN, T_PTR, buf->buf,
736 sizeof(buf->buf));
737 if (n < 0 && af == AF_INET6) {
738 strlcpy(qp, "ip6.int", ep - qp);
739 n = res_query(qbuf, C_IN, T_PTR,
740 buf->buf, sizeof(buf->buf));
741 }
376 if (n < 0) { 742 if (n < 0) {
743 free(buf);
377#ifdef DEBUG 744#ifdef DEBUG
378 if (_res.options & RES_DEBUG) 745 if (_resp->options & RES_DEBUG)
379 printf("res_query failed\n"); 746 printf("res_query failed\n");
380#endif 747#endif
381 break; 748 break;
382 } 749 }
383 hp = getanswer(&buf, n, 1); 750 if (!(hp = getanswer(buf, n, qbuf, T_PTR))) {
384 if (hp == NULL) 751 free(buf);
385 break; 752 break;
386 hp->h_addrtype = type; 753 }
754 free(buf);
755 hp->h_addrtype = af;
387 hp->h_length = len; 756 hp->h_length = len;
388 h_addr_ptrs[0] = (char *)&host_addr; 757 bcopy(addr, host_addr, len);
389 h_addr_ptrs[1] = (char *)0; 758 h_addr_ptrs[0] = (char *)host_addr;
390 host_addr = *(struct in_addr *)addr; 759 h_addr_ptrs[1] = NULL;
760 if (af == AF_INET && (_resp->options & RES_USE_INET6)) {
761 map_v4v6_address((char*)host_addr,
762 (char*)host_addr);
763 hp->h_addrtype = AF_INET6;
764 hp->h_length = IN6ADDRSZ;
765 }
766 h_errno = NETDB_SUCCESS;
391 break; 767 break;
392 case 'f': 768 case 'f':
393 hp = _gethtbyaddr(addr, len, type); 769 hp = _gethtbyaddr(addr, len, af);
394 break; 770 break;
395 } 771 }
396 } 772 }
773 /* XXX h_errno not correct in all cases... */
397 return (hp); 774 return (hp);
398} 775}
399 776
400void 777void
401_sethtent(f) 778_sethtent(int f)
402 int f;
403{ 779{
404 if (hostf == NULL) 780 if (hostf == NULL)
405 hostf = fopen(_PATH_HOSTS, "r" ); 781 hostf = fopen(_PATH_HOSTS, "r" );
@@ -409,7 +785,7 @@ _sethtent(f)
409} 785}
410 786
411void 787void
412_endhtent() 788_endhtent(void)
413{ 789{
414 if (hostf && !stayopen) { 790 if (hostf && !stayopen) {
415 (void) fclose(hostf); 791 (void) fclose(hostf);
@@ -418,39 +794,65 @@ _endhtent()
418} 794}
419 795
420struct hostent * 796struct hostent *
421_gethtent() 797_gethtent(void)
422{ 798{
423 char *p; 799 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
424 register char *cp, **q; 800 char *p, *cp, **q;
801 int af;
802 size_t len;
425 803
426 if (hostf == NULL && (hostf = fopen(_PATH_HOSTS, "r" )) == NULL) 804 if (!hostf && !(hostf = fopen(_PATH_HOSTS, "r" ))) {
805 h_errno = NETDB_INTERNAL;
427 return (NULL); 806 return (NULL);
428again: 807 }
429 if ((p = fgets(hostbuf, BUFSIZ, hostf)) == NULL) 808 again:
809 if ((p = fgetln(hostf, &len)) == NULL) {
810 h_errno = HOST_NOT_FOUND;
430 return (NULL); 811 return (NULL);
812 }
813 if (p[len-1] == '\n')
814 len--;
815 if (len >= sizeof(hostbuf) || len == 0)
816 goto again;
817 p = memcpy(hostbuf, p, len);
818 hostbuf[len] = '\0';
431 if (*p == '#') 819 if (*p == '#')
432 goto again; 820 goto again;
433 cp = strpbrk(p, "#\n"); 821 if ((cp = strchr(p, '#')))
434 if (cp == NULL) 822 *cp = '\0';
435 goto again; 823 if (!(cp = strpbrk(p, " \t")))
436 *cp = '\0';
437 cp = strpbrk(p, " \t");
438 if (cp == NULL)
439 goto again; 824 goto again;
440 *cp++ = '\0'; 825 *cp++ = '\0';
441 /* THIS STUFF IS INTERNET SPECIFIC */ 826 if (inet_pton(AF_INET6, p, host_addr) > 0) {
442 h_addr_ptrs[0] = (char *)&host_addr; 827 af = AF_INET6;
828 len = IN6ADDRSZ;
829 } else if (inet_pton(AF_INET, p, host_addr) > 0) {
830 if (_resp->options & RES_USE_INET6) {
831 map_v4v6_address((char*)host_addr, (char*)host_addr);
832 af = AF_INET6;
833 len = IN6ADDRSZ;
834 } else {
835 af = AF_INET;
836 len = INADDRSZ;
837 }
838 } else {
839 goto again;
840 }
841 /* if this is not something we're looking for, skip it. */
842 if (host.h_addrtype != af)
843 goto again;
844 if (host.h_length != len)
845 goto again;
846 h_addr_ptrs[0] = (char *)host_addr;
443 h_addr_ptrs[1] = NULL; 847 h_addr_ptrs[1] = NULL;
444 (void) inet_aton(p, &host_addr);
445 host.h_addr_list = h_addr_ptrs; 848 host.h_addr_list = h_addr_ptrs;
446 host.h_length = sizeof(u_int32_t); 849 host.h_length = len;
447 host.h_addrtype = AF_INET; 850 host.h_addrtype = af;
448 while (*cp == ' ' || *cp == '\t') 851 while (*cp == ' ' || *cp == '\t')
449 cp++; 852 cp++;
450 host.h_name = cp; 853 host.h_name = cp;
451 q = host.h_aliases = host_aliases; 854 q = host.h_aliases = host_aliases;
452 cp = strpbrk(cp, " \t"); 855 if ((cp = strpbrk(cp, " \t")))
453 if (cp != NULL)
454 *cp++ = '\0'; 856 *cp++ = '\0';
455 while (cp && *cp) { 857 while (cp && *cp) {
456 if (*cp == ' ' || *cp == '\t') { 858 if (*cp == ' ' || *cp == '\t') {
@@ -459,74 +861,75 @@ again:
459 } 861 }
460 if (q < &host_aliases[MAXALIASES - 1]) 862 if (q < &host_aliases[MAXALIASES - 1])
461 *q++ = cp; 863 *q++ = cp;
462 cp = strpbrk(cp, " \t"); 864 if ((cp = strpbrk(cp, " \t")))
463 if (cp != NULL)
464 *cp++ = '\0'; 865 *cp++ = '\0';
465 } 866 }
466 *q = NULL; 867 *q = NULL;
868 if (_resp->options & RES_USE_INET6) {
869 char *bp = hostbuf;
870 char *ep = hostbuf + sizeof hostbuf;
871
872 map_v4v6_hostent(&host, &bp, ep);
873 }
874 h_errno = NETDB_SUCCESS;
467 return (&host); 875 return (&host);
468} 876}
469 877
470struct hostent * 878struct hostent *
471_gethtbyname(name) 879_gethtbyname(const char *name)
472 char *name;
473{ 880{
474 register struct hostent *p; 881 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
475 register char **cp; 882 struct hostent *hp;
883 extern struct hostent *_gethtbyname2(const char *, int);
884
885 if (_resp->options & RES_USE_INET6) {
886 hp = _gethtbyname2(name, AF_INET6);
887 if (hp)
888 return (hp);
889 }
890 return (_gethtbyname2(name, AF_INET));
891}
892
893struct hostent *
894_gethtbyname2(const char *name, int af)
895{
896 struct hostent *p;
897 char **cp;
476 898
477 _sethtent(0); 899 _sethtent(0);
478 while (p = _gethtent()) { 900 while ((p = _gethtent())) {
901 if (p->h_addrtype != af)
902 continue;
479 if (strcasecmp(p->h_name, name) == 0) 903 if (strcasecmp(p->h_name, name) == 0)
480 break; 904 break;
481 for (cp = p->h_aliases; *cp != 0; cp++) 905 for (cp = p->h_aliases; *cp != 0; cp++)
482 if (strcasecmp(*cp, name) == 0) 906 if (strcasecmp(*cp, name) == 0)
483 goto found; 907 goto found;
484 } 908 }
485found: 909 found:
486 _endhtent(); 910 _endhtent();
487 if (p==NULL)
488 h_errno = HOST_NOT_FOUND;
489 return (p); 911 return (p);
490} 912}
491 913
492struct hostent * 914struct hostent *
493_gethtbyaddr(addr, len, type) 915_gethtbyaddr(const char *addr, int len, int af)
494 const char *addr;
495 int len, type;
496{ 916{
497 register struct hostent *p; 917 struct hostent *p;
918
919 host.h_length = len;
920 host.h_addrtype = af;
498 921
499 _sethtent(0); 922 _sethtent(0);
500 while (p = _gethtent()) 923 while ((p = _gethtent()))
501 if (p->h_addrtype == type && !bcmp(p->h_addr, addr, len)) 924 if (p->h_addrtype == af && !bcmp(p->h_addr, addr, len))
502 break; 925 break;
503 _endhtent(); 926 _endhtent();
504 if (p==NULL)
505 h_errno = HOST_NOT_FOUND;
506 return (p); 927 return (p);
507} 928}
508 929
509static int
510qcomp(a1, a2)
511 struct in_addr **a1, **a2;
512{
513 int pos1, pos2;
514
515 for (pos1 = 0; pos1 < _res.nsort; pos1++)
516 if (_res.sort_list[pos1].addr.s_addr ==
517 ((*a1)->s_addr & _res.sort_list[pos1].mask))
518 break;
519 for (pos2 = 0; pos2 < _res.nsort; pos2++)
520 if (_res.sort_list[pos2].addr.s_addr ==
521 ((*a2)->s_addr & _res.sort_list[pos2].mask))
522 break;
523 return pos1 - pos2;
524}
525
526#ifdef YP 930#ifdef YP
527struct hostent * 931struct hostent *
528_yphostent(line) 932_yphostent(char *line)
529 char *line;
530{ 933{
531 static struct in_addr host_addrs[MAXADDRS]; 934 static struct in_addr host_addrs[MAXADDRS];
532 char *p = line; 935 char *p = line;
@@ -537,21 +940,21 @@ _yphostent(line)
537 940
538 host.h_name = NULL; 941 host.h_name = NULL;
539 host.h_addr_list = h_addr_ptrs; 942 host.h_addr_list = h_addr_ptrs;
540 host.h_length = sizeof(u_int32_t); 943 host.h_length = INADDRSZ;
541 host.h_addrtype = AF_INET; 944 host.h_addrtype = AF_INET;
542 hap = h_addr_ptrs; 945 hap = h_addr_ptrs;
543 buf = host_addrs; 946 buf = host_addrs;
544 q = host.h_aliases = host_aliases; 947 q = host.h_aliases = host_aliases;
545 948
546nextline: 949nextline:
950 /* check for host_addrs overflow */
951 if (buf >= &host_addrs[sizeof(host_addrs) / sizeof(host_addrs[0])])
952 goto done;
953
547 more = 0; 954 more = 0;
548 cp = strpbrk(p, " \t"); 955 cp = strpbrk(p, " \t");
549 if (cp == NULL) { 956 if (cp == NULL)
550 if (host.h_name == NULL) 957 goto done;
551 return (NULL);
552 else
553 goto done;
554 }
555 *cp++ = '\0'; 958 *cp++ = '\0';
556 959
557 *hap++ = (char *)buf; 960 *hap++ = (char *)buf;
@@ -592,30 +995,28 @@ nextline:
592 *cp++ = '\0'; 995 *cp++ = '\0';
593 } 996 }
594done: 997done:
998 if (host.h_name == NULL)
999 return (NULL);
595 *q = NULL; 1000 *q = NULL;
596 *hap = NULL; 1001 *hap = NULL;
597 return (&host); 1002 return (&host);
598} 1003}
599 1004
600struct hostent * 1005struct hostent *
601_yp_gethtbyaddr(addr, len, type) 1006_yp_gethtbyaddr(const char *addr)
602 const char *addr;
603 int len, type;
604{ 1007{
605 struct hostent *hp = (struct hostent *)NULL; 1008 struct hostent *hp = (struct hostent *)NULL;
606 static char *__ypcurrent; 1009 static char *__ypcurrent;
607 int __ypcurrentlen, r; 1010 int __ypcurrentlen, r;
608 char name[sizeof("xxx.xxx.xxx.xxx") + 1]; 1011 char name[sizeof("xxx.xxx.xxx.xxx")];
609 1012
610 if (!__ypdomain) { 1013 if (!__ypdomain) {
611 if (_yp_check(&__ypdomain) == 0) 1014 if (_yp_check(&__ypdomain) == 0)
612 return (hp); 1015 return (hp);
613 } 1016 }
614 sprintf(name, "%u.%u.%u.%u", 1017 snprintf(name, sizeof name, "%u.%u.%u.%u",
615 ((unsigned)addr[0] & 0xff), 1018 ((unsigned)addr[0] & 0xff), ((unsigned)addr[1] & 0xff),
616 ((unsigned)addr[1] & 0xff), 1019 ((unsigned)addr[2] & 0xff), ((unsigned)addr[3] & 0xff));
617 ((unsigned)addr[2] & 0xff),
618 ((unsigned)addr[3] & 0xff));
619 if (__ypcurrent) 1020 if (__ypcurrent)
620 free(__ypcurrent); 1021 free(__ypcurrent);
621 __ypcurrent = NULL; 1022 __ypcurrent = NULL;
@@ -629,13 +1030,14 @@ _yp_gethtbyaddr(addr, len, type)
629} 1030}
630 1031
631struct hostent * 1032struct hostent *
632_yp_gethtbyname(name) 1033_yp_gethtbyname(const char *name)
633 const char *name;
634{ 1034{
635 struct hostent *hp = (struct hostent *)NULL; 1035 struct hostent *hp = (struct hostent *)NULL;
636 static char *__ypcurrent; 1036 static char *__ypcurrent;
637 int __ypcurrentlen, r; 1037 int __ypcurrentlen, r;
638 1038
1039 if (strlen(name) >= MAXHOSTNAMELEN)
1040 return (NULL);
639 if (!__ypdomain) { 1041 if (!__ypdomain) {
640 if (_yp_check(&__ypdomain) == 0) 1042 if (_yp_check(&__ypdomain) == 0)
641 return (hp); 1043 return (hp);
@@ -645,10 +1047,102 @@ _yp_gethtbyname(name)
645 __ypcurrent = NULL; 1047 __ypcurrent = NULL;
646 r = yp_match(__ypdomain, "hosts.byname", name, 1048 r = yp_match(__ypdomain, "hosts.byname", name,
647 strlen(name), &__ypcurrent, &__ypcurrentlen); 1049 strlen(name), &__ypcurrent, &__ypcurrentlen);
648 if (r==0) 1050 if (r == 0)
649 hp = _yphostent(__ypcurrent); 1051 hp = _yphostent(__ypcurrent);
650 if (hp==NULL) 1052 if (hp == NULL)
651 h_errno = HOST_NOT_FOUND; 1053 h_errno = HOST_NOT_FOUND;
652 return (hp); 1054 return (hp);
653} 1055}
654#endif 1056#endif
1057
1058static void
1059map_v4v6_address(const char *src, char *dst)
1060{
1061 u_char *p = (u_char *)dst;
1062 char tmp[INADDRSZ];
1063 int i;
1064
1065 /* Stash a temporary copy so our caller can update in place. */
1066 bcopy(src, tmp, INADDRSZ);
1067 /* Mark this ipv6 addr as a mapped ipv4. */
1068 for (i = 0; i < 10; i++)
1069 *p++ = 0x00;
1070 *p++ = 0xff;
1071 *p++ = 0xff;
1072 /* Retrieve the saved copy and we're done. */
1073 bcopy(tmp, (void*)p, INADDRSZ);
1074}
1075
1076static void
1077map_v4v6_hostent(struct hostent *hp, char **bpp, char *ep)
1078{
1079 char **ap;
1080
1081 if (hp->h_addrtype != AF_INET || hp->h_length != INADDRSZ)
1082 return;
1083 hp->h_addrtype = AF_INET6;
1084 hp->h_length = IN6ADDRSZ;
1085 for (ap = hp->h_addr_list; *ap; ap++) {
1086 int i = sizeof(align) - ((u_long)*bpp % sizeof(align));
1087
1088 if (ep - *bpp < (i + IN6ADDRSZ)) {
1089 /* Out of memory. Truncate address list here. XXX */
1090 *ap = NULL;
1091 return;
1092 }
1093 *bpp += i;
1094 map_v4v6_address(*ap, *bpp);
1095 *ap = *bpp;
1096 *bpp += IN6ADDRSZ;
1097 }
1098}
1099
1100struct hostent *
1101gethostent(void)
1102{
1103 return (_gethtent());
1104}
1105
1106#ifdef RESOLVSORT
1107static void
1108addrsort(char **ap, int num)
1109{
1110 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
1111 int i, j;
1112 char **p;
1113 short aval[MAXADDRS];
1114 int needsort = 0;
1115
1116 p = ap;
1117 for (i = 0; i < num; i++, p++) {
1118 for (j = 0 ; (unsigned)j < _resp->nsort; j++)
1119 if (_resp->sort_list[j].addr.s_addr ==
1120 (((struct in_addr *)(*p))->s_addr &
1121 _resp->sort_list[j].mask))
1122 break;
1123 aval[i] = j;
1124 if (needsort == 0 && i > 0 && j < aval[i-1])
1125 needsort = i;
1126 }
1127 if (!needsort)
1128 return;
1129
1130 while (needsort < num) {
1131 for (j = needsort - 1; j >= 0; j--) {
1132 if (aval[j] > aval[j+1]) {
1133 char *hp;
1134
1135 i = aval[j];
1136 aval[j] = aval[j+1];
1137 aval[j+1] = i;
1138
1139 hp = ap[j];
1140 ap[j] = ap[j+1];
1141 ap[j+1] = hp;
1142 } else
1143 break;
1144 }
1145 needsort++;
1146 }
1147}
1148#endif
diff --git a/src/lib/libc/net/getifaddrs.3 b/src/lib/libc/net/getifaddrs.3
new file mode 100644
index 0000000000..9287b3b734
--- /dev/null
+++ b/src/lib/libc/net/getifaddrs.3
@@ -0,0 +1,159 @@
1.\" $OpenBSD: getifaddrs.3,v 1.10 2003/05/30 21:37:59 jmc 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 SEE ALSO
137.Xr ioctl 2 ,
138.Xr socket 2 ,
139.Xr sysctl 3 ,
140.Xr networking 4 ,
141.Xr ifconfig 8
142.Sh HISTORY
143The
144.Fn getifaddrs
145function first appeared in BSDI BSD/OS.
146The function is supplied on
147.Ox
148since
149.Ox 2.7 .
150.Sh BUGS
151If both
152.Aq Pa net/if.h
153and
154.Aq Pa ifaddrs.h
155are being included,
156.Aq Pa net/if.h
157.Em must
158be included before
159.Aq Pa ifaddrs.h .
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..3b3a0fd290
--- /dev/null
+++ b/src/lib/libc/net/getnameinfo.3
@@ -0,0 +1,348 @@
1.\" $OpenBSD: getnameinfo.3,v 1.27 2003/08/28 10:16:38 jmc 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. Neither the name of the University 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 REGENTS 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 REGENTS 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.\" From: @(#)gethostbyname.3 8.4 (Berkeley) 5/25/95
32.\"
33.Dd May 25, 1995
34.Dt GETNAMEINFO 3
35.Os
36.\"
37.Sh NAME
38.Nm getnameinfo
39.Nd address-to-nodename translation in protocol-independent manner
40.\"
41.Sh SYNOPSIS
42.Fd #include <sys/types.h>
43.Fd #include <sys/socket.h>
44.Fd #include <netdb.h>
45.Ft int
46.Fn getnameinfo "const struct sockaddr *sa" "socklen_t salen" \
47"char *host" "size_t hostlen" "char *serv" "size_t servlen" "int flags"
48.\"
49.Sh DESCRIPTION
50The
51.Fn getnameinfo
52function is defined for protocol-independent address-to-nodename translation.
53Its functionality is a reverse conversion of
54.Xr getaddrinfo 3 ,
55and implements similar functionality to
56.Xr gethostbyaddr 3
57and
58.Xr getservbyport 3
59in a more sophisticated manner.
60.Pp
61This function looks up an IP address and port number provided by the
62caller in the DNS and system-specific database, and returns text
63strings for both in buffers provided by the caller.
64The function indicates successful completion by a zero return value;
65a non-zero return value indicates failure.
66.Pp
67The first argument,
68.Fa sa ,
69points to either a
70.Li sockaddr_in
71structure (for IPv4) or a
72.Li sockaddr_in6
73structure (for IPv6) that holds the IP address and port number.
74The
75.Fa salen
76argument gives the length of the
77.Li sockaddr_in
78or
79.Li sockaddr_in6
80structure.
81.Pp
82The function returns the nodename associated with the IP address in
83the buffer pointed to by the
84.Fa host
85argument.
86The caller provides the size of this buffer via the
87.Fa hostlen
88argument.
89The service name associated with the port number is returned in the buffer
90pointed to by
91.Fa serv ,
92and the
93.Fa servlen
94argument gives the length of this buffer.
95The caller specifies not to return either string by providing a zero
96value for the
97.Fa hostlen
98or
99.Fa servlen
100arguments.
101Otherwise, the caller must provide buffers large enough to hold the
102nodename and the service name, including the terminating null characters.
103.Pp
104Unfortunately most systems do not provide constants that specify the
105maximum size of either a fully-qualified domain name or a service name.
106Therefore to aid the application in allocating buffers for these two
107returned strings the following constants are defined in
108.Aq Pa netdb.h :
109.Bd -literal -offset
110#define NI_MAXHOST MAXHOSTNAMELEN
111#define NI_MAXSERV 32
112.Ed
113.Pp
114The first value is actually defined as the constant
115.Dv MAXDNAME
116in recent versions of BIND's
117.Aq Pa arpa/nameser.h
118header (older versions of BIND define this constant to be 256)
119and the second is a guess based on the services listed in the current
120Assigned Numbers RFC.
121.Pp
122The final argument is a
123.Fa flag
124that changes the default actions of this function.
125By default the fully-qualified domain name (FQDN) for the host is
126looked up in the DNS and returned.
127If the flag bit
128.Dv NI_NOFQDN
129is set, only the nodename portion of the FQDN is returned for local hosts.
130.Pp
131If the
132.Fa flag
133bit
134.Dv NI_NUMERICHOST
135is set, or if the host's name cannot be located in the DNS,
136the numeric form of the host's address is returned instead of its name
137.Po
138e.g., by calling
139.Fn inet_ntop
140instead of
141.Fn gethostbyaddr
142.Pc .
143If the
144.Fa flag
145bit
146.Dv NI_NAMEREQD
147is set, an error is returned if the host's name cannot be located in the DNS.
148.Pp
149If the flag bit
150.Dv NI_NUMERICSERV
151is set, the numeric form of the service address is returned
152.Pq e.g., its port number
153instead of its name.
154The two
155.Dv NI_NUMERICxxx
156flags are required to support the
157.Fl n
158flag that many commands provide.
159.Pp
160A fifth flag bit,
161.Dv NI_DGRAM ,
162specifies that the service is a datagram service, and causes
163.Fn getservbyport
164to be called with a second argument of
165.Qq udp
166instead of its default of
167.Qq tcp .
168This is required for the few ports (512-514)
169that have different services for UDP and TCP.
170.Pp
171These
172.Dv NI_xxx
173flags are defined in
174.Aq Pa netdb.h .
175.\"
176.Ss Extension for scoped IPv6 address
177The implementation allows experimental numeric IPv6 address notation with
178scope identifier.
179IPv6 link-local address will appear as a string like
180.Dq Li fe80::1%ne0 .
181Refer to
182.Xr getaddrinfo 3
183for the notation.
184.\"
185.Sh EXAMPLES
186The following code tries to get a numeric hostname, and service name,
187for given socket address.
188Observe that there is no hardcoded reference to a particular address family.
189.Bd -literal -offset indent
190struct sockaddr *sa; /* input */
191char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
192
193if (getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf), sbuf,
194 sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV)) {
195 errx(1, "could not get numeric hostname");
196 /*NOTREACHED*/
197}
198printf("host=%s, serv=%s\en", hbuf, sbuf);
199.Ed
200.Pp
201The following version checks if the socket address has reverse address mapping.
202.Bd -literal -offset indent
203struct sockaddr *sa; /* input */
204char hbuf[NI_MAXHOST];
205
206if (getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf), NULL, 0,
207 NI_NAMEREQD)) {
208 errx(1, "could not resolve hostname");
209 /*NOTREACHED*/
210}
211printf("host=%s\en", hbuf);
212.Ed
213.\"
214.Sh DIAGNOSTICS
215The function indicates successful completion by a zero return value;
216a non-zero return value indicates failure.
217Error codes are as below:
218.Bl -tag -width Er
219.It Dv EAI_AGAIN
220The name could not be resolved at this time.
221Future attempts may succeed.
222.It Dv EAI_BADFLAGS
223The flags had an invalid value.
224.It Dv EAI_FAIL
225A non-recoverable error occurred.
226.It Dv EAI_FAMILY
227The address family was not recognized or the address length was invalid
228for the specified family.
229.It Dv EAI_MEMORY
230There was a memory allocation failure.
231.It Dv EAI_NONAME
232The name does not resolve for the supplied parameters.
233.Dv NI_NAMEREQD
234is set and the host's name cannot be located,
235or both nodename and servname were null.
236.It Dv EAI_SYSTEM
237A system error occurred.
238The error code can be found in errno.
239.El
240.\"
241.Sh SEE ALSO
242.Xr getaddrinfo 3 ,
243.Xr gethostbyaddr 3 ,
244.Xr getservbyport 3 ,
245.Xr hosts 5 ,
246.Xr resolv.conf 5 ,
247.Xr services 5 ,
248.Xr hostname 7 ,
249.Xr named 8
250.Rs
251.%A R. Gilligan
252.%A S. Thomson
253.%A J. Bound
254.%A W. Stevens
255.%T Basic Socket Interface Extensions for IPv6
256.%R RFC 2553
257.%D March 1999
258.Re
259.Rs
260.%A Tatsuya Jinmei
261.%A Atsushi Onoe
262.%T "An Extension of Format for IPv6 Scoped Addresses"
263.%R internet draft
264.%N draft-ietf-ipngwg-scopedaddr-format-02.txt
265.%O work in progress material
266.Re
267.Rs
268.%A Craig Metz
269.%T Protocol Independence Using the Sockets API
270.%B "Proceedings of the freenix track: 2000 USENIX annual technical conference"
271.%D June 2000
272.Re
273.\"
274.Sh STANDARDS
275The
276.Fn getnameinfo
277function is defined in IEEE POSIX 1003.1g draft specification,
278and documented in
279.Dq Basic Socket Interface Extensions for IPv6
280.Pq RFC 2553 .
281.\"
282.Sh HISTORY
283The implementation first appeared in WIDE Hydrangea IPv6 protocol stack kit.
284.\"
285.Sh CAVEATS
286.Fn getnameinfo
287returns both numeric and FQDN notation of the address specified in
288.Fa sa .
289There is no return value that indicates if the string returned in
290.Fa host
291is a result of binary to numeric-text translation (like
292.Xr inet_ntop 3 ) ,
293or the result of DNS reverse lookup.
294Therefore, malicious parties could set up a PTR record as below:
295.Bd -literal -offset indent
2961.0.0.127.in-addr.arpa. IN PTR 10.1.1.1
297.Ed
298.Pp
299and trick the caller of
300.Fn getnameinfo
301into believing that
302.Fa sa
303is
304.Li 10.1.1.1
305when it actually is
306.Li 127.0.0.1 .
307.Pp
308To prevent such attacks, the use of
309.Dv NI_NAMEREQD
310is recommended when you use the result of
311.Fn getnameinfo
312for access control purposes:
313.Bd -literal -offset indent
314struct sockaddr *sa;
315socklen_t salen;
316char addr[NI_MAXHOST];
317struct addrinfo hints, *res;
318int error;
319
320error = getnameinfo(sa, salen, addr, sizeof(addr),
321 NULL, 0, NI_NAMEREQD);
322if (error == 0) {
323 memset(&hints, 0, sizeof(hints));
324 hints.ai_socktype = SOCK_DGRAM; /*dummy*/
325 hints.ai_flags = AI_NUMERICHOST;
326 if (getaddrinfo(addr, "0", &hints, &res) == 0) {
327 /* malicious PTR record */
328 freeaddrinfo(res);
329 printf("bogus PTR record\\n");
330 return -1;
331 }
332 /* addr is FQDN as a result of PTR lookup */
333} else {
334 /* addr is numeric string */
335 error = getnameinfo(sa, salen, addr, sizeof(addr),
336 NULL, 0, NI_NUMERICHOST);
337}
338.Ed
339.\"
340.Sh BUGS
341The current implementation is not thread-safe.
342.Pp
343The text was shamelessly copied from RFC 2553.
344.Pp
345.Ox
346intentionally uses a different
347.Dv NI_MAXHOST
348value from what RFC 2553 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..da5df507ab
--- /dev/null
+++ b/src/lib/libc/net/getnameinfo.c
@@ -0,0 +1,372 @@
1/* $OpenBSD: getnameinfo.c,v 1.27 2003/07/21 23:17:53 marc 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
62#include "thread_private.h"
63
64static const struct afd {
65 int a_af;
66 int a_addrlen;
67 int a_socklen;
68 int a_off;
69} afdl [] = {
70#ifdef INET6
71 {PF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6),
72 offsetof(struct sockaddr_in6, sin6_addr)},
73#endif
74 {PF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in),
75 offsetof(struct sockaddr_in, sin_addr)},
76 {0, 0, 0},
77};
78
79struct sockinet {
80 u_char si_len;
81 u_char si_family;
82 u_short si_port;
83};
84
85#ifdef INET6
86static int ip6_parsenumeric(const struct sockaddr *, const char *, char *,
87 size_t, int);
88static int ip6_sa2str(const struct sockaddr_in6 *, char *, size_t, int);
89#endif
90
91/*
92 * this mutex is also used by get_port in getaddrinfo.c
93 */
94pthread_mutex_t __THREAD_MUTEX_NAME(serv_mutex) = PTHREAD_MUTEX_INITIALIZER;
95
96int
97getnameinfo(sa, salen, host, hostlen, serv, servlen, flags)
98 const struct sockaddr *sa;
99 socklen_t salen;
100 char *host;
101 size_t hostlen;
102 char *serv;
103 size_t servlen;
104 int flags;
105{
106 const struct afd *afd;
107 struct servent *sp;
108 struct hostent *hp;
109 u_short port;
110 int family, i;
111 const char *addr;
112 u_int32_t v4a;
113 int h_error;
114 char numserv[512];
115 char numaddr[512];
116
117 if (sa == NULL)
118 return EAI_FAIL;
119
120 if (sa->sa_len != salen)
121 return EAI_FAIL;
122
123 family = sa->sa_family;
124 for (i = 0; afdl[i].a_af; i++)
125 if (afdl[i].a_af == family) {
126 afd = &afdl[i];
127 goto found;
128 }
129 return EAI_FAMILY;
130
131 found:
132 if (salen != afd->a_socklen)
133 return EAI_FAIL;
134
135 /* network byte order */
136 port = ((const struct sockinet *)sa)->si_port;
137 addr = (const char *)sa + afd->a_off;
138
139 if (serv == NULL || servlen == 0) {
140 /*
141 * do nothing in this case.
142 * in case you are wondering if "&&" is more correct than
143 * "||" here: rfc2553bis-03 says that serv == NULL OR
144 * servlen == 0 means that the caller does not want the result.
145 */
146 } else {
147 if (flags & NI_NUMERICSERV)
148 sp = NULL;
149 else {
150 _THREAD_PRIVATE_MUTEX_LOCK(serv_mutex);
151 sp = getservbyport(port,
152 (flags & NI_DGRAM) ? "udp" : "tcp");
153 _THREAD_PRIVATE_MUTEX_UNLOCK(serv_mutex);
154 }
155 if (sp) {
156 if (strlen(sp->s_name) + 1 > servlen)
157 return EAI_MEMORY;
158 strlcpy(serv, sp->s_name, servlen);
159 } else {
160 snprintf(numserv, sizeof(numserv), "%u", ntohs(port));
161 if (strlen(numserv) + 1 > servlen)
162 return EAI_MEMORY;
163 strlcpy(serv, numserv, servlen);
164 }
165 }
166
167 switch (sa->sa_family) {
168 case AF_INET:
169 v4a = (u_int32_t)
170 ntohl(((const struct sockaddr_in *)sa)->sin_addr.s_addr);
171 if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a))
172 flags |= NI_NUMERICHOST;
173 v4a >>= IN_CLASSA_NSHIFT;
174 if (v4a == 0)
175 flags |= NI_NUMERICHOST;
176 break;
177#ifdef INET6
178 case AF_INET6:
179 {
180 const struct sockaddr_in6 *sin6;
181 sin6 = (const struct sockaddr_in6 *)sa;
182 switch (sin6->sin6_addr.s6_addr[0]) {
183 case 0x00:
184 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr))
185 ;
186 else if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr))
187 ;
188 else
189 flags |= NI_NUMERICHOST;
190 break;
191 default:
192 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
193 flags |= NI_NUMERICHOST;
194 }
195 else if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))
196 flags |= NI_NUMERICHOST;
197 break;
198 }
199 }
200 break;
201#endif
202 }
203 if (host == NULL || hostlen == 0) {
204 /*
205 * do nothing in this case.
206 * in case you are wondering if "&&" is more correct than
207 * "||" here: rfc2553bis-03 says that host == NULL or
208 * hostlen == 0 means that the caller does not want the result.
209 */
210 } else if (flags & NI_NUMERICHOST) {
211 int numaddrlen;
212
213 /* NUMERICHOST and NAMEREQD conflicts with each other */
214 if (flags & NI_NAMEREQD)
215 return EAI_NONAME;
216
217 switch(afd->a_af) {
218#ifdef INET6
219 case AF_INET6:
220 {
221 int error;
222
223 if ((error = ip6_parsenumeric(sa, addr, host,
224 hostlen, flags)) != 0)
225 return(error);
226 break;
227 }
228#endif
229 default:
230 if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr))
231 == NULL)
232 return EAI_SYSTEM;
233 numaddrlen = strlen(numaddr);
234 if (numaddrlen + 1 > hostlen) /* don't forget terminator */
235 return EAI_MEMORY;
236 strlcpy(host, numaddr, hostlen);
237 break;
238 }
239 } else {
240 _THREAD_PRIVATE_MUTEX_LOCK(serv_mutex);
241 hp = gethostbyaddr(addr, afd->a_addrlen, afd->a_af);
242 _THREAD_PRIVATE_MUTEX_UNLOCK(serv_mutex);
243 h_error = h_errno;
244
245 if (hp) {
246#if 0
247 /*
248 * commented out, since "for local host" is not
249 * implemented here - see RFC2553 p30
250 */
251 if (flags & NI_NOFQDN) {
252 char *p;
253 p = strchr(hp->h_name, '.');
254 if (p)
255 *p = '\0';
256 }
257#endif
258 if (strlen(hp->h_name) + 1 > hostlen) {
259 return EAI_MEMORY;
260 }
261 strlcpy(host, hp->h_name, hostlen);
262 } else {
263 if (flags & NI_NAMEREQD)
264 return EAI_NONAME;
265 switch(afd->a_af) {
266#ifdef INET6
267 case AF_INET6:
268 {
269 int error;
270
271 if ((error = ip6_parsenumeric(sa, addr, host,
272 hostlen,
273 flags)) != 0)
274 return(error);
275 break;
276 }
277#endif
278 default:
279 if (inet_ntop(afd->a_af, addr, host,
280 hostlen) == NULL)
281 return EAI_SYSTEM;
282 break;
283 }
284 }
285 }
286 return(0);
287}
288
289#ifdef INET6
290static int
291ip6_parsenumeric(sa, addr, host, hostlen, flags)
292 const struct sockaddr *sa;
293 const char *addr;
294 char *host;
295 size_t hostlen;
296 int flags;
297{
298 int numaddrlen;
299 char numaddr[512];
300
301 if (inet_ntop(AF_INET6, addr, numaddr, sizeof(numaddr)) == NULL)
302 return EAI_SYSTEM;
303
304 numaddrlen = strlen(numaddr);
305 if (numaddrlen + 1 > hostlen) /* don't forget terminator */
306 return EAI_MEMORY;
307 strlcpy(host, numaddr, hostlen);
308
309 if (((const struct sockaddr_in6 *)sa)->sin6_scope_id) {
310 char zonebuf[MAXHOSTNAMELEN];
311 int zonelen;
312
313 zonelen = ip6_sa2str(
314 (const struct sockaddr_in6 *)(const void *)sa,
315 zonebuf, sizeof(zonebuf), flags);
316 if (zonelen < 0)
317 return EAI_MEMORY;
318 if (zonelen + 1 + numaddrlen + 1 > hostlen)
319 return EAI_MEMORY;
320
321 /* construct <numeric-addr><delim><zoneid> */
322 memcpy(host + numaddrlen + 1, zonebuf,
323 (size_t)zonelen);
324 host[numaddrlen] = SCOPE_DELIMITER;
325 host[numaddrlen + 1 + zonelen] = '\0';
326 }
327
328 return 0;
329}
330
331/* ARGSUSED */
332static int
333ip6_sa2str(sa6, buf, bufsiz, flags)
334 const struct sockaddr_in6 *sa6;
335 char *buf;
336 size_t bufsiz;
337 int flags;
338{
339 unsigned int ifindex;
340 const struct in6_addr *a6;
341 int n;
342
343 ifindex = (unsigned int)sa6->sin6_scope_id;
344 a6 = &sa6->sin6_addr;
345
346#ifdef notdef
347 if ((flags & NI_NUMERICSCOPE) != 0) {
348 n = snprintf(buf, bufsiz, "%u", sa6->sin6_scope_id);
349 if (n < 0 || n >= bufsiz)
350 return -1;
351 else
352 return n;
353 }
354#endif
355
356 /* if_indextoname() does not take buffer size. not a good api... */
357 if ((IN6_IS_ADDR_LINKLOCAL(a6) || IN6_IS_ADDR_MC_LINKLOCAL(a6)) &&
358 bufsiz >= IF_NAMESIZE) {
359 char *p = if_indextoname(ifindex, buf);
360 if (p) {
361 return(strlen(p));
362 }
363 }
364
365 /* last resort */
366 n = snprintf(buf, bufsiz, "%u", sa6->sin6_scope_id);
367 if (n < 0 || n >= bufsiz)
368 return -1;
369 else
370 return n;
371}
372#endif /* INET6 */
diff --git a/src/lib/libc/net/getnetbyaddr.c b/src/lib/libc/net/getnetbyaddr.c
index c193860e36..29365d4735 100644
--- a/src/lib/libc/net/getnetbyaddr.c
+++ b/src/lib/libc/net/getnetbyaddr.c
@@ -1,5 +1,3 @@
1/* $NetBSD: getnetbyaddr.c,v 1.4 1995/02/25 06:20:30 cgd Exp $ */
2
3/* 1/*
4 * Copyright (c) 1983, 1993 2 * Copyright (c) 1983, 1993
5 * The Regents of the University of California. All rights reserved. 3 * The Regents of the University of California. All rights reserved.
@@ -12,11 +10,7 @@
12 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission. 15 * without specific prior written permission.
22 * 16 *
@@ -34,11 +28,7 @@
34 */ 28 */
35 29
36#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
37#if 0 31static char rcsid[] = "$OpenBSD: getnetbyaddr.c,v 1.6 2003/06/02 20:18:35 millert Exp $";
38static char sccsid[] = "@(#)getnetbyaddr.c 8.1 (Berkeley) 6/4/93";
39#else
40static char rcsid[] = "$NetBSD: getnetbyaddr.c,v 1.4 1995/02/25 06:20:30 cgd Exp $";
41#endif
42#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
43 33
44#include <netdb.h> 34#include <netdb.h>
@@ -46,14 +36,14 @@ static char rcsid[] = "$NetBSD: getnetbyaddr.c,v 1.4 1995/02/25 06:20:30 cgd Exp
46extern int _net_stayopen; 36extern int _net_stayopen;
47 37
48struct netent * 38struct netent *
49getnetbyaddr(net, type) 39_getnetbyaddr(net, type)
50 register long net; 40 register in_addr_t net;
51 register int type; 41 register int type;
52{ 42{
53 register struct netent *p; 43 register struct netent *p;
54 44
55 setnetent(_net_stayopen); 45 setnetent(_net_stayopen);
56 while (p = getnetent()) 46 while ((p = getnetent()))
57 if (p->n_addrtype == type && p->n_net == net) 47 if (p->n_addrtype == type && p->n_net == net)
58 break; 48 break;
59 if (!_net_stayopen) 49 if (!_net_stayopen)
diff --git a/src/lib/libc/net/getnetbyname.c b/src/lib/libc/net/getnetbyname.c
index 93a2e1256c..04ab7b6332 100644
--- a/src/lib/libc/net/getnetbyname.c
+++ b/src/lib/libc/net/getnetbyname.c
@@ -1,5 +1,3 @@
1/* $NetBSD: getnetbyname.c,v 1.4 1995/02/25 06:20:31 cgd Exp $ */
2
3/* 1/*
4 * Copyright (c) 1983, 1993 2 * Copyright (c) 1983, 1993
5 * The Regents of the University of California. All rights reserved. 3 * The Regents of the University of California. All rights reserved.
@@ -12,11 +10,7 @@
12 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission. 15 * without specific prior written permission.
22 * 16 *
@@ -34,11 +28,7 @@
34 */ 28 */
35 29
36#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
37#if 0 31static char rcsid[] = "$OpenBSD: getnetbyname.c,v 1.6 2003/06/02 20:18:35 millert Exp $";
38static char sccsid[] = "@(#)getnetbyname.c 8.1 (Berkeley) 6/4/93";
39#else
40static char rcsid[] = "$NetBSD: getnetbyname.c,v 1.4 1995/02/25 06:20:31 cgd Exp $";
41#endif
42#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
43 33
44#include <netdb.h> 34#include <netdb.h>
@@ -47,18 +37,18 @@ static char rcsid[] = "$NetBSD: getnetbyname.c,v 1.4 1995/02/25 06:20:31 cgd Exp
47extern int _net_stayopen; 37extern int _net_stayopen;
48 38
49struct netent * 39struct netent *
50getnetbyname(name) 40_getnetbyname(name)
51 register const char *name; 41 register const char *name;
52{ 42{
53 register struct netent *p; 43 register struct netent *p;
54 register char **cp; 44 register char **cp;
55 45
56 setnetent(_net_stayopen); 46 setnetent(_net_stayopen);
57 while (p = getnetent()) { 47 while ((p = getnetent())) {
58 if (strcmp(p->n_name, name) == 0) 48 if (strcasecmp(p->n_name, name) == 0)
59 break; 49 break;
60 for (cp = p->n_aliases; *cp != 0; cp++) 50 for (cp = p->n_aliases; *cp != 0; cp++)
61 if (strcmp(*cp, name) == 0) 51 if (strcasecmp(*cp, name) == 0)
62 goto found; 52 goto found;
63 } 53 }
64found: 54found:
diff --git a/src/lib/libc/net/getnetent.3 b/src/lib/libc/net/getnetent.3
index d4f0bedbf9..40b50a8c3f 100644
--- a/src/lib/libc/net/getnetent.3
+++ b/src/lib/libc/net/getnetent.3
@@ -1,4 +1,4 @@
1.\" $NetBSD: getnetent.3,v 1.3 1995/02/25 06:20:32 cgd Exp $ 1.\" $OpenBSD: getnetent.3,v 1.13 2004/02/01 19:45:00 nordin Exp $
2.\" 2.\"
3.\" Copyright (c) 1983, 1991, 1993 3.\" Copyright (c) 1983, 1991, 1993
4.\" The Regents of the University of California. All rights reserved. 4.\" The Regents of the University of California. All rights reserved.
@@ -11,11 +11,7 @@
11.\" 2. Redistributions in binary form must reproduce the above copyright 11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the 12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution. 13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software 14.\" 3. Neither the name of the University nor the names of its contributors
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 15.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission. 16.\" without specific prior written permission.
21.\" 17.\"
@@ -31,11 +27,9 @@
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE. 28.\" SUCH DAMAGE.
33.\" 29.\"
34.\" @(#)getnetent.3 8.1 (Berkeley) 6/4/93 30.Dd March 13, 1997
35.\"
36.Dd June 4, 1993
37.Dt GETNETENT 3 31.Dt GETNETENT 3
38.Os BSD 4.2 32.Os
39.Sh NAME 33.Sh NAME
40.Nm getnetent , 34.Nm getnetent ,
41.Nm getnetbyaddr , 35.Nm getnetbyaddr ,
@@ -46,31 +40,30 @@
46.Sh SYNOPSIS 40.Sh SYNOPSIS
47.Fd #include <netdb.h> 41.Fd #include <netdb.h>
48.Ft struct netent * 42.Ft struct netent *
49.Fn getnetent 43.Fn getnetent "void"
50.Ft struct netent * 44.Ft struct netent *
51.Fn getnetbyname "char *name" 45.Fn getnetbyname "const char *name"
52.Ft struct netent * 46.Ft struct netent *
53.Fn getnetbyaddr "long net" "int type" 47.Fn getnetbyaddr "in_addr_t net" "int type"
48.Ft void
54.Fn setnetent "int stayopen" 49.Fn setnetent "int stayopen"
55.Fn endnetent 50.Ft void
51.Fn endnetent "void"
56.Sh DESCRIPTION 52.Sh DESCRIPTION
57The 53The
58.Fn getnetent , 54.Fn getnetent ,
59.Fn getnetbyname , 55.Fn getnetbyname ,
60and 56and
61.Fn getnetbyaddr 57.Fn getnetbyaddr
62functions 58functions each return a pointer to an object with the following structure
63each return a pointer to an object with the 59containing the broken-out fields of a line in the network database,
64following structure
65containing the broken-out
66fields of a line in the network data base,
67.Pa /etc/networks . 60.Pa /etc/networks .
68.Bd -literal -offset indent 61.Bd -literal -offset indent
69struct netent { 62struct netent {
70 char *n_name; /* official name of net */ 63 char *n_name; /* official name of net */
71 char **n_aliases; /* alias list */ 64 char **n_aliases; /* alias list */
72 int n_addrtype; /* net number type */ 65 int n_addrtype; /* net number type */
73 unsigned long n_net; /* net number */ 66 in_addr_t n_net; /* net number */
74}; 67};
75.Ed 68.Ed
76.Pp 69.Pp
@@ -79,45 +72,42 @@ The members of this structure are:
79.It Fa n_name 72.It Fa n_name
80The official name of the network. 73The official name of the network.
81.It Fa n_aliases 74.It Fa n_aliases
82A zero terminated list of alternate names for the network. 75A zero-terminated list of alternate names for the network.
83.It Fa n_addrtype 76.It Fa n_addrtype
84The type of the network number returned; currently only AF_INET. 77The type of the network number returned; currently only
78.Dv AF_INET .
85.It Fa n_net 79.It Fa n_net
86The network number. Network numbers are returned in machine byte 80The network number.
87order. 81Network numbers are returned in machine byte order.
88.El 82.El
89.Pp 83.Pp
90The 84The
91.Fn getnetent 85.Fn getnetent
92function 86function reads the next line of the file, opening the file if necessary.
93reads the next line of the file, opening the file if necessary.
94.Pp 87.Pp
95The 88The
96.Fn setnetent 89.Fn setnetent
97function 90function opens and rewinds the file.
98opens and rewinds the file. If the 91If the
99.Fa stayopen 92.Fa stayopen
100flag is non-zero, 93flag is non-zero,
101the net data base will not be closed after each call to 94the net database will not be closed after each call to
102.Fn getnetbyname 95.Fn getnetbyname
103or 96or
104.Fn getnetbyaddr . 97.Fn getnetbyaddr .
105.Pp 98.Pp
106The 99The
107.Fn endnetent 100.Fn endnetent
108function 101function closes the file.
109closes the file.
110.Pp 102.Pp
111The 103The
112.Fn getnetbyname 104.Fn getnetbyname
113function
114and 105and
115.Fn getnetbyaddr 106.Fn getnetbyaddr
116sequentially search from the beginning 107functions search the domain name server if the system is configured to use one.
117of the file until a matching 108If the search fails, or no name server is configured, they sequentially
118net name or 109search from the beginning of the file until a matching net name or
119net address and type is found, 110net address and type is found, or until
120or until
121.Dv EOF 111.Dv EOF
122is encountered. 112is encountered.
123Network numbers are supplied in host order. 113Network numbers are supplied in host order.
@@ -126,11 +116,11 @@ Network numbers are supplied in host order.
126.It Pa /etc/networks 116.It Pa /etc/networks
127.El 117.El
128.Sh DIAGNOSTICS 118.Sh DIAGNOSTICS
129Null pointer 119Null pointer (0) returned on
130(0) returned on
131.Dv EOF 120.Dv EOF
132or error. 121or error.
133.Sh SEE ALSO 122.Sh SEE ALSO
123.Xr resolver 3 ,
134.Xr networks 5 124.Xr networks 5
135.Sh HISTORY 125.Sh HISTORY
136The 126The
@@ -140,14 +130,11 @@ The
140.Fn setnetent , 130.Fn setnetent ,
141and 131and
142.Fn endnetent 132.Fn endnetent
143functions appeared in 133functions appeared in
144.Bx 4.2 . 134.Bx 4.2 .
145.Sh BUGS 135.Sh BUGS
146The data space used by 136The data space used by these functions is static; if future use
147these functions is static; if future use requires the data, it should be 137requires the data, it should be copied before any subsequent calls
148copied before any subsequent calls to these functions overwrite it. 138to these functions overwrite it.
149Only Internet network 139Only Internet network numbers are currently understood.
150numbers are currently understood. 140Expecting network numbers to fit in no more than 32 bits is naive.
151Expecting network numbers to fit
152in no more than 32 bits is probably
153naive.
diff --git a/src/lib/libc/net/getnetent.c b/src/lib/libc/net/getnetent.c
index b4e16b8f5d..4c3b38e7d8 100644
--- a/src/lib/libc/net/getnetent.c
+++ b/src/lib/libc/net/getnetent.c
@@ -1,5 +1,3 @@
1/* $NetBSD: getnetent.c,v 1.4 1995/02/25 06:20:33 cgd Exp $ */
2
3/* 1/*
4 * Copyright (c) 1983, 1993 2 * Copyright (c) 1983, 1993
5 * The Regents of the University of California. All rights reserved. 3 * The Regents of the University of California. All rights reserved.
@@ -12,11 +10,7 @@
12 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission. 15 * without specific prior written permission.
22 * 16 *
@@ -34,11 +28,7 @@
34 */ 28 */
35 29
36#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
37#if 0 31static char rcsid[] = "$OpenBSD: getnetent.c,v 1.9 2003/06/02 20:18:35 millert Exp $";
38static char sccsid[] = "@(#)getnetent.c 8.1 (Berkeley) 6/4/93";
39#else
40static char rcsid[] = "$NetBSD: getnetent.c,v 1.4 1995/02/25 06:20:33 cgd Exp $";
41#endif
42#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
43 33
44#include <sys/types.h> 34#include <sys/types.h>
@@ -81,22 +71,27 @@ endnetent()
81struct netent * 71struct netent *
82getnetent() 72getnetent()
83{ 73{
84 char *p; 74 char *p, *cp, **q;
85 register char *cp, **q; 75 size_t len;
86 76
87 if (netf == NULL && (netf = fopen(_PATH_NETWORKS, "r" )) == NULL) 77 if (netf == NULL && (netf = fopen(_PATH_NETWORKS, "r" )) == NULL)
88 return (NULL); 78 return (NULL);
89again: 79again:
90 p = fgets(line, BUFSIZ, netf); 80 if ((p = fgetln(netf, &len)) == NULL)
91 if (p == NULL)
92 return (NULL); 81 return (NULL);
93 if (*p == '#') 82 if (p[len-1] == '\n')
83 len--;
84 if (len >= sizeof(line) || len == 0)
94 goto again; 85 goto again;
95 cp = strpbrk(p, "#\n"); 86 p = memcpy(line, p, len);
96 if (cp == NULL) 87 line[len] = '\0';
88 if (*p == '#')
97 goto again; 89 goto again;
98 *cp = '\0'; 90 if ((cp = strchr(p, '#')) != NULL)
91 *cp = '\0';
99 net.n_name = p; 92 net.n_name = p;
93 if (strlen(net.n_name) >= MAXHOSTNAMELEN-1)
94 net.n_name[MAXHOSTNAMELEN-1] = '\0';
100 cp = strpbrk(p, " \t"); 95 cp = strpbrk(p, " \t");
101 if (cp == NULL) 96 if (cp == NULL)
102 goto again; 97 goto again;
@@ -116,8 +111,11 @@ again:
116 cp++; 111 cp++;
117 continue; 112 continue;
118 } 113 }
119 if (q < &net_aliases[MAXALIASES - 1]) 114 if (q < &net_aliases[MAXALIASES - 1]) {
120 *q++ = cp; 115 *q++ = cp;
116 if (strlen(cp) >= MAXHOSTNAMELEN-1)
117 cp[MAXHOSTNAMELEN-1] = '\0';
118 }
121 cp = strpbrk(cp, " \t"); 119 cp = strpbrk(cp, " \t");
122 if (cp != NULL) 120 if (cp != NULL)
123 *cp++ = '\0'; 121 *cp++ = '\0';
diff --git a/src/lib/libc/net/getnetnamadr.c b/src/lib/libc/net/getnetnamadr.c
new file mode 100644
index 0000000000..149216ffd8
--- /dev/null
+++ b/src/lib/libc/net/getnetnamadr.c
@@ -0,0 +1,400 @@
1/* $OpenBSD: getnetnamadr.c,v 1.23 2003/06/03 21:09:00 deraadt 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 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS
16 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT,
19 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27/* Copyright (c) 1993 Carlos Leandro and Rui Salgueiro
28 * Dep. Matematica Universidade de Coimbra, Portugal, Europe
29 *
30 * Permission to use, copy, modify, and distribute this software for any
31 * purpose with or without fee is hereby granted, provided that the above
32 * copyright notice and this permission notice appear in all copies.
33 */
34/*
35 * Copyright (c) 1983, 1993
36 * The Regents of the University of California. All rights reserved.
37 *
38 * Redistribution and use in source and binary forms, with or without
39 * modification, are permitted provided that the following conditions
40 * are met:
41 * 1. Redistributions of source code must retain the above copyright
42 * notice, this list of conditions and the following disclaimer.
43 * 2. Redistributions in binary form must reproduce the above copyright
44 * notice, this list of conditions and the following disclaimer in the
45 * documentation and/or other materials provided with the distribution.
46 * 3. Neither the name of the University nor the names of its contributors
47 * may be used to endorse or promote products derived from this software
48 * without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
51 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
52 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
53 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
54 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
55 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
56 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
57 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
58 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
59 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
60 * SUCH DAMAGE.
61 */
62
63#if defined(LIBC_SCCS) && !defined(lint)
64#if 0
65static char sccsid[] = "@(#)getnetbyaddr.c 8.1 (Berkeley) 6/4/93";
66static char sccsid_[] = "from getnetnamadr.c 1.4 (Coimbra) 93/06/03";
67static char rcsid[] = "$From: getnetnamadr.c,v 8.7 1996/08/05 08:31:35 vixie Exp $";
68#else
69static char rcsid[] = "$OpenBSD: getnetnamadr.c,v 1.23 2003/06/03 21:09:00 deraadt Exp $";
70#endif
71#endif /* LIBC_SCCS and not lint */
72
73#include <sys/types.h>
74#include <sys/param.h>
75#include <sys/socket.h>
76#include <netinet/in.h>
77#include <arpa/inet.h>
78#include <arpa/nameser.h>
79
80#include <stdio.h>
81#include <netdb.h>
82#include <resolv.h>
83#include <ctype.h>
84#include <errno.h>
85#include <string.h>
86#include <stdlib.h>
87
88#include "thread_private.h"
89
90extern int h_errno;
91
92struct netent *_getnetbyaddr(in_addr_t net, int type);
93struct netent *_getnetbyname(const char *name);
94
95int _hokchar(const char *);
96
97#define BYADDR 0
98#define BYNAME 1
99#define MAXALIASES 35
100
101#define MAXPACKET (64*1024)
102
103typedef union {
104 HEADER hdr;
105 u_char buf[MAXPACKET];
106} querybuf;
107
108typedef union {
109 long al;
110 char ac;
111} align;
112
113static struct netent *
114getnetanswer(answer, anslen, net_i)
115 querybuf *answer;
116 int anslen;
117 int net_i;
118{
119
120 register HEADER *hp;
121 register u_char *cp;
122 register int n;
123 u_char *eom;
124 int type, class, ancount, qdcount, haveanswer, i, nchar;
125 char aux1[MAXHOSTNAMELEN], aux2[MAXHOSTNAMELEN], ans[MAXHOSTNAMELEN];
126 char *in, *st, *pauxt, *bp, **ap, *ep;
127 char *paux1 = &aux1[0], *paux2 = &aux2[0];
128 static struct netent net_entry;
129 static char *net_aliases[MAXALIASES], netbuf[BUFSIZ+1];
130
131 /*
132 * find first satisfactory answer
133 *
134 * answer --> +------------+ ( MESSAGE )
135 * | Header |
136 * +------------+
137 * | Question | the question for the name server
138 * +------------+
139 * | Answer | RRs answering the question
140 * +------------+
141 * | Authority | RRs pointing toward an authority
142 * | Additional | RRs holding additional information
143 * +------------+
144 */
145 eom = answer->buf + anslen;
146 hp = &answer->hdr;
147 ancount = ntohs(hp->ancount); /* #/records in the answer section */
148 qdcount = ntohs(hp->qdcount); /* #/entries in the question section */
149 bp = netbuf;
150 ep = netbuf + sizeof(netbuf);
151 cp = answer->buf + HFIXEDSZ;
152 if (!qdcount) {
153 if (hp->aa)
154 h_errno = HOST_NOT_FOUND;
155 else
156 h_errno = TRY_AGAIN;
157 return (NULL);
158 }
159 while (qdcount-- > 0) {
160 n = __dn_skipname(cp, eom);
161 if (n < 0 || (cp + n + QFIXEDSZ) > eom) {
162 h_errno = NO_RECOVERY;
163 return(NULL);
164 }
165 cp += n + QFIXEDSZ;
166 }
167 ap = net_aliases;
168 *ap = NULL;
169 net_entry.n_aliases = net_aliases;
170 haveanswer = 0;
171 while (--ancount >= 0 && cp < eom) {
172 n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
173#ifdef USE_RESOLV_NAME_OK
174 if ((n < 0) || !res_dnok(bp))
175#else
176 if ((n < 0) || !_hokchar(bp))
177#endif
178 break;
179 cp += n;
180 ans[0] = '\0';
181 strlcpy(&ans[0], bp, sizeof ans);
182 GETSHORT(type, cp);
183 GETSHORT(class, cp);
184 cp += INT32SZ; /* TTL */
185 GETSHORT(n, cp);
186 if (class == C_IN && type == T_PTR) {
187 n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
188#ifdef USE_RESOLV_NAME_OK
189 if ((n < 0) || !res_hnok(bp))
190#else
191 if ((n < 0) || !_hokchar(bp))
192#endif
193 {
194 cp += n;
195 return (NULL);
196 }
197 cp += n;
198 if ((ap + 2) < &net_aliases[MAXALIASES]) {
199 *ap++ = bp;
200 bp += strlen(bp) + 1;
201 net_entry.n_addrtype =
202 (class == C_IN) ? AF_INET : AF_UNSPEC;
203 haveanswer++;
204 }
205 }
206 }
207 if (haveanswer) {
208 *ap = NULL;
209 switch (net_i) {
210 case BYADDR:
211 net_entry.n_name = *net_entry.n_aliases;
212 net_entry.n_net = 0L;
213 break;
214 case BYNAME:
215 ap = net_entry.n_aliases;
216 next_alias:
217 in = *ap++;
218 if (in == NULL) {
219 h_errno = HOST_NOT_FOUND;
220 return (NULL);
221 }
222 net_entry.n_name = ans;
223 aux2[0] = '\0';
224 for (i = 0; i < 4; i++) {
225 for (st = in, nchar = 0;
226 isdigit((unsigned char)*st);
227 st++, nchar++)
228 ;
229 if (*st != '.' || nchar == 0 || nchar > 3)
230 goto next_alias;
231 if (i != 0)
232 nchar++;
233 strlcpy(paux1, in, nchar+1);
234 strlcat(paux1, paux2, MAXHOSTNAMELEN);
235 pauxt = paux2;
236 paux2 = paux1;
237 paux1 = pauxt;
238 in = ++st;
239 }
240 if (strcasecmp(in, "IN-ADDR.ARPA") != 0)
241 goto next_alias;
242 net_entry.n_net = inet_network(paux2);
243 break;
244 }
245 net_entry.n_aliases++;
246 return (&net_entry);
247 }
248 h_errno = TRY_AGAIN;
249 return (NULL);
250}
251
252struct netent *
253getnetbyaddr(net, net_type)
254 register in_addr_t net;
255 register int net_type;
256{
257 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
258 unsigned int netbr[4];
259 int nn, anslen;
260 querybuf *buf;
261 char qbuf[MAXDNAME];
262 in_addr_t net2;
263 struct netent *net_entry = NULL;
264 char lookups[MAXDNSLUS];
265 int i;
266
267 if ((_resp->options & RES_INIT) == 0 && res_init() == -1)
268 return(_getnetbyaddr(net, net_type));
269
270 bcopy(_resp->lookups, lookups, sizeof lookups);
271 if (lookups[0] == '\0')
272 strlcpy(lookups, "bf", sizeof lookups);
273
274 for (i = 0; i < MAXDNSLUS && lookups[i]; i++) {
275 switch (lookups[i]) {
276#ifdef YP
277 case 'y':
278 /* There is no YP support. */
279 break;
280#endif /* YP */
281 case 'b':
282 if (net_type != AF_INET)
283 break; /* DNS only supports AF_INET? */
284
285 for (nn = 4, net2 = net; net2; net2 >>= 8)
286 netbr[--nn] = net2 & 0xff;
287 switch (nn) {
288 case 3: /* Class A */
289 snprintf(qbuf, sizeof(qbuf),
290 "0.0.0.%u.in-addr.arpa", netbr[3]);
291 break;
292 case 2: /* Class B */
293 snprintf(qbuf, sizeof(qbuf),
294 "0.0.%u.%u.in-addr.arpa",
295 netbr[3], netbr[2]);
296 break;
297 case 1: /* Class C */
298 snprintf(qbuf, sizeof(qbuf),
299 "0.%u.%u.%u.in-addr.arpa",
300 netbr[3], netbr[2], netbr[1]);
301 break;
302 case 0: /* Class D - E */
303 snprintf(qbuf, sizeof(qbuf),
304 "%u.%u.%u.%u.in-addr.arpa",
305 netbr[3], netbr[2], netbr[1], netbr[0]);
306 break;
307 }
308 buf = malloc(sizeof(*buf));
309 if (buf == NULL)
310 break;
311 anslen = res_query(qbuf, C_IN, T_PTR, buf->buf,
312 sizeof(buf->buf));
313 if (anslen < 0) {
314 free(buf);
315#ifdef DEBUG
316 if (_resp->options & RES_DEBUG)
317 printf("res_query failed\n");
318#endif
319 break;
320 }
321 net_entry = getnetanswer(buf, anslen, BYADDR);
322 free(buf);
323 if (net_entry != NULL) {
324 unsigned u_net = net; /* maybe net should be unsigned ? */
325
326 /* Strip trailing zeros */
327 while ((u_net & 0xff) == 0 && u_net != 0)
328 u_net >>= 8;
329 net_entry->n_net = u_net;
330 return (net_entry);
331 }
332 break;
333 case 'f':
334 net_entry = _getnetbyaddr(net, net_type);
335 if (net_entry != NULL)
336 return (net_entry);
337 }
338 }
339
340 /* Nothing matched. */
341 return (NULL);
342}
343
344struct netent *
345getnetbyname(net)
346 register const char *net;
347{
348 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
349 int anslen;
350 querybuf *buf;
351 char qbuf[MAXDNAME];
352 struct netent *net_entry = NULL;
353 char lookups[MAXDNSLUS];
354 int i;
355
356 if ((_resp->options & RES_INIT) == 0 && res_init() == -1)
357 return (_getnetbyname(net));
358
359 bcopy(_resp->lookups, lookups, sizeof lookups);
360 if (lookups[0] == '\0')
361 strlcpy(lookups, "bf", sizeof lookups);
362
363 for (i = 0; i < MAXDNSLUS && lookups[i]; i++) {
364 switch (lookups[i]) {
365#ifdef YP
366 case 'y':
367 /* There is no YP support. */
368 break;
369#endif /* YP */
370 case 'b':
371 strlcpy(qbuf, net, sizeof qbuf);
372 buf = malloc(sizeof(*buf));
373 if (buf == NULL)
374 break;
375 anslen = res_search(qbuf, C_IN, T_PTR, buf->buf,
376 sizeof(buf->buf));
377 if (anslen < 0) {
378 free(buf);
379#ifdef DEBUG
380 if (_resp->options & RES_DEBUG)
381 printf("res_query failed\n");
382#endif
383 break;
384 }
385 net_entry = getnetanswer(buf, anslen, BYNAME);
386 free(buf);
387 if (net_entry != NULL)
388 return (net_entry);
389 break;
390 case 'f':
391 net_entry = _getnetbyname(net);
392 if (net_entry != NULL)
393 return (net_entry);
394 break;
395 }
396 }
397
398 /* Nothing matched. */
399 return (NULL);
400}
diff --git a/src/lib/libc/net/getproto.c b/src/lib/libc/net/getproto.c
index 49c09b0806..dee089d5c2 100644
--- a/src/lib/libc/net/getproto.c
+++ b/src/lib/libc/net/getproto.c
@@ -1,5 +1,3 @@
1/* $NetBSD: getproto.c,v 1.4 1995/02/25 06:20:33 cgd Exp $ */
2
3/* 1/*
4 * Copyright (c) 1983, 1993 2 * Copyright (c) 1983, 1993
5 * The Regents of the University of California. All rights reserved. 3 * The Regents of the University of California. All rights reserved.
@@ -12,11 +10,7 @@
12 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission. 15 * without specific prior written permission.
22 * 16 *
@@ -34,11 +28,7 @@
34 */ 28 */
35 29
36#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
37#if 0 31static char rcsid[] = "$OpenBSD: getproto.c,v 1.4 2003/06/02 20:18:35 millert Exp $";
38static char sccsid[] = "@(#)getproto.c 8.1 (Berkeley) 6/4/93";
39#else
40static char rcsid[] = "$NetBSD: getproto.c,v 1.4 1995/02/25 06:20:33 cgd Exp $";
41#endif
42#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
43 33
44#include <netdb.h> 34#include <netdb.h>
@@ -52,7 +42,7 @@ getprotobynumber(proto)
52 register struct protoent *p; 42 register struct protoent *p;
53 43
54 setprotoent(_proto_stayopen); 44 setprotoent(_proto_stayopen);
55 while (p = getprotoent()) 45 while ((p = getprotoent()))
56 if (p->p_proto == proto) 46 if (p->p_proto == proto)
57 break; 47 break;
58 if (!_proto_stayopen) 48 if (!_proto_stayopen)
diff --git a/src/lib/libc/net/getprotoent.3 b/src/lib/libc/net/getprotoent.3
index 8d607199ef..5c41e6fb7c 100644
--- a/src/lib/libc/net/getprotoent.3
+++ b/src/lib/libc/net/getprotoent.3
@@ -1,4 +1,4 @@
1.\" $NetBSD: getprotoent.3,v 1.3 1995/02/25 06:20:34 cgd Exp $ 1.\" $OpenBSD: getprotoent.3,v 1.10 2004/02/01 19:45:00 nordin Exp $
2.\" 2.\"
3.\" Copyright (c) 1983, 1991, 1993 3.\" Copyright (c) 1983, 1991, 1993
4.\" The Regents of the University of California. All rights reserved. 4.\" The Regents of the University of California. All rights reserved.
@@ -11,11 +11,7 @@
11.\" 2. Redistributions in binary form must reproduce the above copyright 11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the 12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution. 13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software 14.\" 3. Neither the name of the University nor the names of its contributors
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 15.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission. 16.\" without specific prior written permission.
21.\" 17.\"
@@ -31,11 +27,9 @@
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE. 28.\" SUCH DAMAGE.
33.\" 29.\"
34.\" @(#)getprotoent.3 8.1 (Berkeley) 6/4/93
35.\"
36.Dd June 4, 1993 30.Dd June 4, 1993
37.Dt GETPROTOENT 3 31.Dt GETPROTOENT 3
38.Os BSD 4.2 32.Os
39.Sh NAME 33.Sh NAME
40.Nm getprotoent , 34.Nm getprotoent ,
41.Nm getprotobynumber , 35.Nm getprotobynumber ,
@@ -46,24 +40,23 @@
46.Sh SYNOPSIS 40.Sh SYNOPSIS
47.Fd #include <netdb.h> 41.Fd #include <netdb.h>
48.Ft struct protoent * 42.Ft struct protoent *
49.Fn getprotoent 43.Fn getprotoent "void"
50.Ft struct protoent * 44.Ft struct protoent *
51.Fn getprotobyname "char *name" 45.Fn getprotobyname "const char *name"
52.Ft struct protoent * 46.Ft struct protoent *
53.Fn getprotobynumber "int proto" 47.Fn getprotobynumber "int proto"
48.Ft void
54.Fn setprotoent "int stayopen" 49.Fn setprotoent "int stayopen"
55.Fn endprotoent 50.Ft void
51.Fn endprotoent "void"
56.Sh DESCRIPTION 52.Sh DESCRIPTION
57The 53The
58.Fn getprotoent , 54.Fn getprotoent ,
59.Fn getprotobyname , 55.Fn getprotobyname ,
60and 56and
61.Fn getprotobynumber 57.Fn getprotobynumber
62functions 58functions each return a pointer to an object with the following structure
63each return a pointer to an object with the 59containing the broken-out fields of a line in the network protocol database,
64following structure
65containing the broken-out
66fields of a line in the network protocol data base,
67.Pa /etc/protocols . 60.Pa /etc/protocols .
68.Bd -literal -offset indent 61.Bd -literal -offset indent
69.Pp 62.Pp
@@ -79,47 +72,40 @@ The members of this structure are:
79.It Fa p_name 72.It Fa p_name
80The official name of the protocol. 73The official name of the protocol.
81.It Fa p_aliases 74.It Fa p_aliases
82A zero terminated list of alternate names for the protocol. 75A zero-terminated list of alternate names for the protocol.
83.It Fa p_proto 76.It Fa p_proto
84The protocol number. 77The protocol number.
85.El 78.El
86.Pp 79.Pp
87The 80The
88.Fn getprotoent 81.Fn getprotoent
89function 82function reads the next line of the file, opening the file if necessary.
90reads the next line of the file, opening the file if necessary.
91.Pp 83.Pp
92The 84The
93.Fn setprotoent 85.Fn setprotoent
94function 86function opens and rewinds the file.
95opens and rewinds the file. If the 87If the
96.Fa stayopen 88.Fa stayopen
97flag is non-zero, 89flag is non-zero,
98the net data base will not be closed after each call to 90the net database will not be closed after each call to
99.Fn getprotobyname 91.Fn getprotobyname
100or 92or
101.Fn getprotobynumber . 93.Fn getprotobynumber .
102.Pp 94.Pp
103The 95The
104.Fn endprotoent 96.Fn endprotoent
105function 97function closes the file.
106closes the file.
107.Pp 98.Pp
108The 99The
109.Fn getprotobyname 100.Fn getprotobyname
110function
111and 101and
112.Fn getprotobynumber 102.Fn getprotobynumber
113sequentially search from the beginning 103functions sequentially search from the beginning of the file until a
114of the file until a matching 104matching protocol name or protocol number is found, or until
115protocol name or
116protocol number is found,
117or until
118.Dv EOF 105.Dv EOF
119is encountered. 106is encountered.
120.Sh RETURN VALUES 107.Sh RETURN VALUES
121Null pointer 108Null pointer (0) returned on
122(0) returned on
123.Dv EOF 109.Dv EOF
124or error. 110or error.
125.Sh FILES 111.Sh FILES
@@ -136,11 +122,9 @@ The
136.Fn setprotoent , 122.Fn setprotoent ,
137and 123and
138.Fn endprotoent 124.Fn endprotoent
139functions appeared in 125functions appeared in
140.Bx 4.2 . 126.Bx 4.2 .
141.Sh BUGS 127.Sh BUGS
142These functions use a static data space; 128These functions use a static data space; if the data is needed for future use,
143if the data is needed for future use, it should be 129it should be copied before any subsequent calls overwrite it.
144copied before any subsequent calls overwrite it. 130Only the Internet protocols are currently understood.
145Only the Internet
146protocols are currently understood.
diff --git a/src/lib/libc/net/getprotoent.c b/src/lib/libc/net/getprotoent.c
index 1179b9029b..b2bdd2e164 100644
--- a/src/lib/libc/net/getprotoent.c
+++ b/src/lib/libc/net/getprotoent.c
@@ -1,5 +1,3 @@
1/* $NetBSD: getprotoent.c,v 1.4 1995/02/25 06:20:35 cgd Exp $ */
2
3/* 1/*
4 * Copyright (c) 1983, 1993 2 * Copyright (c) 1983, 1993
5 * The Regents of the University of California. All rights reserved. 3 * The Regents of the University of California. All rights reserved.
@@ -12,11 +10,7 @@
12 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission. 15 * without specific prior written permission.
22 * 16 *
@@ -34,11 +28,7 @@
34 */ 28 */
35 29
36#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
37#if 0 31static char rcsid[] = "$OpenBSD: getprotoent.c,v 1.5 2003/06/02 20:18:35 millert Exp $";
38static char sccsid[] = "@(#)getprotoent.c 8.1 (Berkeley) 6/4/93";
39#else
40static char rcsid[] = "$NetBSD: getprotoent.c,v 1.4 1995/02/25 06:20:35 cgd Exp $";
41#endif
42#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
43 33
44#include <sys/types.h> 34#include <sys/types.h>
@@ -80,20 +70,25 @@ endprotoent()
80struct protoent * 70struct protoent *
81getprotoent() 71getprotoent()
82{ 72{
83 char *p; 73 char *p, *cp, **q, *endp;
84 register char *cp, **q; 74 long l;
75 size_t len;
85 76
86 if (protof == NULL && (protof = fopen(_PATH_PROTOCOLS, "r" )) == NULL) 77 if (protof == NULL && (protof = fopen(_PATH_PROTOCOLS, "r" )) == NULL)
87 return (NULL); 78 return (NULL);
88again: 79again:
89 if ((p = fgets(line, BUFSIZ, protof)) == NULL) 80 if ((p = fgetln(protof, &len)) == NULL)
90 return (NULL); 81 return (NULL);
91 if (*p == '#') 82 if (p[len-1] == '\n')
83 len--;
84 if (len >= sizeof(line) || len == 0)
92 goto again; 85 goto again;
93 cp = strpbrk(p, "#\n"); 86 p = memcpy(line, p, len);
94 if (cp == NULL) 87 line[len] = '\0';
88 if (*p == '#')
95 goto again; 89 goto again;
96 *cp = '\0'; 90 if ((cp = strchr(p, '#')) != NULL)
91 *cp = '\0';
97 proto.p_name = p; 92 proto.p_name = p;
98 cp = strpbrk(p, " \t"); 93 cp = strpbrk(p, " \t");
99 if (cp == NULL) 94 if (cp == NULL)
@@ -104,7 +99,10 @@ again:
104 p = strpbrk(cp, " \t"); 99 p = strpbrk(cp, " \t");
105 if (p != NULL) 100 if (p != NULL)
106 *p++ = '\0'; 101 *p++ = '\0';
107 proto.p_proto = atoi(cp); 102 l = strtol(cp, &endp, 10);
103 if (endp == cp || *endp != '\0' || l < 0 || l >= INT_MAX)
104 goto again;
105 proto.p_proto = l;
108 q = proto.p_aliases = proto_aliases; 106 q = proto.p_aliases = proto_aliases;
109 if (p != NULL) { 107 if (p != NULL) {
110 cp = p; 108 cp = p;
diff --git a/src/lib/libc/net/getprotoname.c b/src/lib/libc/net/getprotoname.c
index 4f8cf21c3f..4742a60a04 100644
--- a/src/lib/libc/net/getprotoname.c
+++ b/src/lib/libc/net/getprotoname.c
@@ -1,5 +1,3 @@
1/* $NetBSD: getprotoname.c,v 1.4 1995/02/25 06:20:36 cgd Exp $ */
2
3/* 1/*
4 * Copyright (c) 1983, 1993 2 * Copyright (c) 1983, 1993
5 * The Regents of the University of California. All rights reserved. 3 * The Regents of the University of California. All rights reserved.
@@ -12,11 +10,7 @@
12 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission. 15 * without specific prior written permission.
22 * 16 *
@@ -34,11 +28,7 @@
34 */ 28 */
35 29
36#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
37#if 0 31static char rcsid[] = "$OpenBSD: getprotoname.c,v 1.4 2003/06/02 20:18:35 millert Exp $";
38static char sccsid[] = "@(#)getprotoname.c 8.1 (Berkeley) 6/4/93";
39#else
40static char rcsid[] = "$NetBSD: getprotoname.c,v 1.4 1995/02/25 06:20:36 cgd Exp $";
41#endif
42#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
43 33
44#include <netdb.h> 34#include <netdb.h>
@@ -54,7 +44,7 @@ getprotobyname(name)
54 register char **cp; 44 register char **cp;
55 45
56 setprotoent(_proto_stayopen); 46 setprotoent(_proto_stayopen);
57 while (p = getprotoent()) { 47 while ((p = getprotoent())) {
58 if (strcmp(p->p_name, name) == 0) 48 if (strcmp(p->p_name, name) == 0)
59 break; 49 break;
60 for (cp = p->p_aliases; *cp != 0; cp++) 50 for (cp = p->p_aliases; *cp != 0; cp++)
diff --git a/src/lib/libc/net/getrrsetbyname.3 b/src/lib/libc/net/getrrsetbyname.3
new file mode 100644
index 0000000000..a786ff8747
--- /dev/null
+++ b/src/lib/libc/net/getrrsetbyname.3
@@ -0,0 +1,165 @@
1.\" $OpenBSD: getrrsetbyname.3,v 1.11 2003/05/30 21:37:59 jmc 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 October 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
105structure.
106Memory allocated for the dynamically allocated structures created by
107a successful call to
108.Fn getrrsetbyname
109is released by
110.Fn freerrset .
111.Li rrset
112is a pointer to a
113.Li struct rrset
114created by a call to
115.Fn getrrsetbyname .
116.Pp
117If the EDNS0 option is activated in
118.Xr resolv.conf 5 ,
119.Fn getrrsetbyname
120will request DNSSEC authentication using the EDNS0 DNSSEC OK (DO) bit.
121.Sh RETURN VALUES
122.Fn getrrsetbyname
123returns zero on success, and one of the following error
124codes if an error occurred:
125.Pp
126.Bl -tag -width ERRSET_NOMEMORY -compact
127.It Dv ERRSET_NONAME
128the name does not exist
129.It Dv ERRSET_NODATA
130the name exists, but does not have data of the desired type
131.It Dv ERRSET_NOMEMORY
132memory could not be allocated
133.It Dv ERRSET_INVAL
134a parameter is invalid
135.It Dv ERRSET_FAIL
136other failure
137.El
138.Sh SEE ALSO
139.Xr resolver 3 ,
140.Xr resolv.conf 5 ,
141.Xr named 8
142.Sh HISTORY
143.Fn getrrsetbyname
144first appeared in
145.Ox 3.0 .
146The API first appeared in ISC BIND version 9.
147.Sh AUTHORS
148.An Jakob Schlyter Aq jakob@openbsd.org
149.Sh CAVEATS
150The
151.Dv RRSET_VALIDATED
152flag in
153.Li rri_flags
154is set if the AD (authenticated data) bit in the DNS answer is
155set.
156This flag
157.Em should not
158be trusted unless the transport between the nameserver and the resolver
159is secure (e.g. IPsec, trusted network, loopback communication).
160.Sh BUGS
161The data in
162.Li *rdi_data
163should be returned in uncompressed wire format.
164Currently, the data is in compressed format and the caller can't
165uncompress since it doesn't have the full message.
diff --git a/src/lib/libc/net/getrrsetbyname.c b/src/lib/libc/net/getrrsetbyname.c
new file mode 100644
index 0000000000..f00ac2b021
--- /dev/null
+++ b/src/lib/libc/net/getrrsetbyname.c
@@ -0,0 +1,512 @@
1/* $OpenBSD: getrrsetbyname.c,v 1.7 2003/03/07 07:34:14 itojun 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#include "thread_private.h"
55
56#define ANSWER_BUFFER_SIZE 1024*64
57
58struct dns_query {
59 char *name;
60 u_int16_t type;
61 u_int16_t class;
62 struct dns_query *next;
63};
64
65struct dns_rr {
66 char *name;
67 u_int16_t type;
68 u_int16_t class;
69 u_int16_t ttl;
70 u_int16_t size;
71 void *rdata;
72 struct dns_rr *next;
73};
74
75struct dns_response {
76 HEADER header;
77 struct dns_query *query;
78 struct dns_rr *answer;
79 struct dns_rr *authority;
80 struct dns_rr *additional;
81};
82
83static struct dns_response *parse_dns_response(const u_char *, int);
84static struct dns_query *parse_dns_qsection(const u_char *, int,
85 const u_char **, int);
86static struct dns_rr *parse_dns_rrsection(const u_char *, int, const u_char **,
87 int);
88
89static void free_dns_query(struct dns_query *);
90static void free_dns_rr(struct dns_rr *);
91static void free_dns_response(struct dns_response *);
92
93static int count_dns_rr(struct dns_rr *, u_int16_t, u_int16_t);
94
95int
96getrrsetbyname(const char *hostname, unsigned int rdclass,
97 unsigned int rdtype, unsigned int flags,
98 struct rrsetinfo **res)
99{
100 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
101 int result;
102 struct rrsetinfo *rrset = NULL;
103 struct dns_response *response;
104 struct dns_rr *rr;
105 struct rdatainfo *rdata;
106 int length;
107 unsigned int index_ans, index_sig;
108 u_char answer[ANSWER_BUFFER_SIZE];
109
110 /* check for invalid class and type */
111 if (rdclass > 0xffff || rdtype > 0xffff) {
112 result = ERRSET_INVAL;
113 goto fail;
114 }
115
116 /* don't allow queries of class or type ANY */
117 if (rdclass == 0xff || rdtype == 0xff) {
118 result = ERRSET_INVAL;
119 goto fail;
120 }
121
122 /* don't allow flags yet, unimplemented */
123 if (flags) {
124 result = ERRSET_INVAL;
125 goto fail;
126 }
127
128 /* initialize resolver */
129 if ((_resp->options & RES_INIT) == 0 && res_init() == -1) {
130 result = ERRSET_FAIL;
131 goto fail;
132 }
133
134#ifdef DEBUG
135 _resp->options |= RES_DEBUG;
136#endif /* DEBUG */
137
138#ifdef RES_USE_DNSSEC
139 /* turn on DNSSEC if EDNS0 is configured */
140 if (_resp->options & RES_USE_EDNS0)
141 _resp->options |= RES_USE_DNSSEC;
142#endif /* RES_USE_DNSEC */
143
144 /* make query */
145 length = res_query(hostname, (signed int) rdclass, (signed int) rdtype,
146 answer, sizeof(answer));
147 if (length < 0) {
148 switch(h_errno) {
149 case HOST_NOT_FOUND:
150 result = ERRSET_NONAME;
151 goto fail;
152 case NO_DATA:
153 result = ERRSET_NODATA;
154 goto fail;
155 default:
156 result = ERRSET_FAIL;
157 goto fail;
158 }
159 }
160
161 /* parse result */
162 response = parse_dns_response(answer, length);
163 if (response == NULL) {
164 result = ERRSET_FAIL;
165 goto fail;
166 }
167
168 if (response->header.qdcount != 1) {
169 result = ERRSET_FAIL;
170 goto fail;
171 }
172
173 /* initialize rrset */
174 rrset = calloc(1, sizeof(struct rrsetinfo));
175 if (rrset == NULL) {
176 result = ERRSET_NOMEMORY;
177 goto fail;
178 }
179 rrset->rri_rdclass = response->query->class;
180 rrset->rri_rdtype = response->query->type;
181 rrset->rri_ttl = response->answer->ttl;
182 rrset->rri_nrdatas = response->header.ancount;
183
184 /* check for authenticated data */
185 if (response->header.ad == 1)
186 rrset->rri_flags |= RRSET_VALIDATED;
187
188 /* copy name from answer section */
189 length = strlen(response->answer->name);
190 rrset->rri_name = malloc(length + 1);
191 if (rrset->rri_name == NULL) {
192 result = ERRSET_NOMEMORY;
193 goto fail;
194 }
195 strlcpy(rrset->rri_name, response->answer->name, length + 1);
196
197 /* count answers */
198 rrset->rri_nrdatas = count_dns_rr(response->answer, rrset->rri_rdclass,
199 rrset->rri_rdtype);
200 rrset->rri_nsigs = count_dns_rr(response->answer, rrset->rri_rdclass,
201 T_SIG);
202
203 /* allocate memory for answers */
204 rrset->rri_rdatas = calloc(rrset->rri_nrdatas,
205 sizeof(struct rdatainfo));
206 if (rrset->rri_rdatas == NULL) {
207 result = ERRSET_NOMEMORY;
208 goto fail;
209 }
210
211 /* allocate memory for signatures */
212 rrset->rri_sigs = calloc(rrset->rri_nsigs, sizeof(struct rdatainfo));
213 if (rrset->rri_sigs == NULL) {
214 result = ERRSET_NOMEMORY;
215 goto fail;
216 }
217
218 /* copy answers & signatures */
219 for (rr = response->answer, index_ans = 0, index_sig = 0;
220 rr; rr = rr->next) {
221
222 rdata = NULL;
223
224 if (rr->class == rrset->rri_rdclass &&
225 rr->type == rrset->rri_rdtype)
226 rdata = &rrset->rri_rdatas[index_ans++];
227
228 if (rr->class == rrset->rri_rdclass &&
229 rr->type == T_SIG)
230 rdata = &rrset->rri_sigs[index_sig++];
231
232 if (rdata) {
233 rdata->rdi_length = rr->size;
234 rdata->rdi_data = malloc(rr->size);
235
236 if (rdata->rdi_data == NULL) {
237 result = ERRSET_NOMEMORY;
238 goto fail;
239 }
240 memcpy(rdata->rdi_data, rr->rdata, rr->size);
241 }
242 }
243
244 *res = rrset;
245 return (ERRSET_SUCCESS);
246
247fail:
248 if (rrset != NULL)
249 freerrset(rrset);
250 return (result);
251}
252
253void
254freerrset(struct rrsetinfo *rrset)
255{
256 u_int16_t i;
257
258 if (rrset == NULL)
259 return;
260
261 if (rrset->rri_rdatas) {
262 for (i = 0; i < rrset->rri_nrdatas; i++) {
263 if (rrset->rri_rdatas[i].rdi_data == NULL)
264 break;
265 free(rrset->rri_rdatas[i].rdi_data);
266 }
267 free(rrset->rri_rdatas);
268 }
269
270 if (rrset->rri_sigs) {
271 for (i = 0; i < rrset->rri_nsigs; i++) {
272 if (rrset->rri_sigs[i].rdi_data == NULL)
273 break;
274 free(rrset->rri_sigs[i].rdi_data);
275 }
276 free(rrset->rri_sigs);
277 }
278
279 if (rrset->rri_name)
280 free(rrset->rri_name);
281 free(rrset);
282}
283
284/*
285 * DNS response parsing routines
286 */
287static struct dns_response *
288parse_dns_response(const u_char *answer, int size)
289{
290 struct dns_response *resp;
291 const u_char *cp;
292
293 /* allocate memory for the response */
294 resp = calloc(1, sizeof(*resp));
295 if (resp == NULL)
296 return (NULL);
297
298 /* initialize current pointer */
299 cp = answer;
300
301 /* copy header */
302 memcpy(&resp->header, cp, HFIXEDSZ);
303 cp += HFIXEDSZ;
304
305 /* fix header byte order */
306 resp->header.qdcount = ntohs(resp->header.qdcount);
307 resp->header.ancount = ntohs(resp->header.ancount);
308 resp->header.nscount = ntohs(resp->header.nscount);
309 resp->header.arcount = ntohs(resp->header.arcount);
310
311 /* there must be at least one query */
312 if (resp->header.qdcount < 1) {
313 free_dns_response(resp);
314 return (NULL);
315 }
316
317 /* parse query section */
318 resp->query = parse_dns_qsection(answer, size, &cp,
319 resp->header.qdcount);
320 if (resp->header.qdcount && resp->query == NULL) {
321 free_dns_response(resp);
322 return (NULL);
323 }
324
325 /* parse answer section */
326 resp->answer = parse_dns_rrsection(answer, size, &cp,
327 resp->header.ancount);
328 if (resp->header.ancount && resp->answer == NULL) {
329 free_dns_response(resp);
330 return (NULL);
331 }
332
333 /* parse authority section */
334 resp->authority = parse_dns_rrsection(answer, size, &cp,
335 resp->header.nscount);
336 if (resp->header.nscount && resp->authority == NULL) {
337 free_dns_response(resp);
338 return (NULL);
339 }
340
341 /* parse additional section */
342 resp->additional = parse_dns_rrsection(answer, size, &cp,
343 resp->header.arcount);
344 if (resp->header.arcount && resp->additional == NULL) {
345 free_dns_response(resp);
346 return (NULL);
347 }
348
349 return (resp);
350}
351
352static struct dns_query *
353parse_dns_qsection(const u_char *answer, int size, const u_char **cp, int count)
354{
355 struct dns_query *head, *curr, *prev;
356 int i, length;
357 char name[MAXDNAME];
358
359 for (i = 1, head = NULL, prev = NULL; i <= count; i++, prev = curr) {
360
361 /* allocate and initialize struct */
362 curr = calloc(1, sizeof(struct dns_query));
363 if (curr == NULL) {
364 free_dns_query(head);
365 return (NULL);
366 }
367 if (head == NULL)
368 head = curr;
369 if (prev != NULL)
370 prev->next = curr;
371
372 /* name */
373 length = dn_expand(answer, answer + size, *cp, name,
374 sizeof(name));
375 if (length < 0) {
376 free_dns_query(head);
377 return (NULL);
378 }
379 curr->name = strdup(name);
380 if (curr->name == NULL) {
381 free_dns_query(head);
382 return (NULL);
383 }
384 *cp += length;
385
386 /* type */
387 curr->type = _getshort(*cp);
388 *cp += INT16SZ;
389
390 /* class */
391 curr->class = _getshort(*cp);
392 *cp += INT16SZ;
393 }
394
395 return (head);
396}
397
398static struct dns_rr *
399parse_dns_rrsection(const u_char *answer, int size, const u_char **cp, int count)
400{
401 struct dns_rr *head, *curr, *prev;
402 int i, length;
403 char name[MAXDNAME];
404
405 for (i = 1, head = NULL, prev = NULL; i <= count; i++, prev = curr) {
406
407 /* allocate and initialize struct */
408 curr = calloc(1, sizeof(struct dns_rr));
409 if (curr == NULL) {
410 free_dns_rr(head);
411 return (NULL);
412 }
413 if (head == NULL)
414 head = curr;
415 if (prev != NULL)
416 prev->next = curr;
417
418 /* name */
419 length = dn_expand(answer, answer + size, *cp, name,
420 sizeof(name));
421 if (length < 0) {
422 free_dns_rr(head);
423 return (NULL);
424 }
425 curr->name = strdup(name);
426 if (curr->name == NULL) {
427 free_dns_rr(head);
428 return (NULL);
429 }
430 *cp += length;
431
432 /* type */
433 curr->type = _getshort(*cp);
434 *cp += INT16SZ;
435
436 /* class */
437 curr->class = _getshort(*cp);
438 *cp += INT16SZ;
439
440 /* ttl */
441 curr->ttl = _getlong(*cp);
442 *cp += INT32SZ;
443
444 /* rdata size */
445 curr->size = _getshort(*cp);
446 *cp += INT16SZ;
447
448 /* rdata itself */
449 curr->rdata = malloc(curr->size);
450 if (curr->rdata == NULL) {
451 free_dns_rr(head);
452 return (NULL);
453 }
454 memcpy(curr->rdata, *cp, curr->size);
455 *cp += curr->size;
456 }
457
458 return (head);
459}
460
461static void
462free_dns_query(struct dns_query *p)
463{
464 if (p == NULL)
465 return;
466
467 if (p->name)
468 free(p->name);
469 free_dns_query(p->next);
470 free(p);
471}
472
473static void
474free_dns_rr(struct dns_rr *p)
475{
476 if (p == NULL)
477 return;
478
479 if (p->name)
480 free(p->name);
481 if (p->rdata)
482 free(p->rdata);
483 free_dns_rr(p->next);
484 free(p);
485}
486
487static void
488free_dns_response(struct dns_response *p)
489{
490 if (p == NULL)
491 return;
492
493 free_dns_query(p->query);
494 free_dns_rr(p->answer);
495 free_dns_rr(p->authority);
496 free_dns_rr(p->additional);
497 free(p);
498}
499
500static int
501count_dns_rr(struct dns_rr *p, u_int16_t class, u_int16_t type)
502{
503 int n = 0;
504
505 while(p) {
506 if (p->class == class && p->type == type)
507 n++;
508 p = p->next;
509 }
510
511 return (n);
512}
diff --git a/src/lib/libc/net/getservbyname.c b/src/lib/libc/net/getservbyname.c
index b4a6311966..f1c312ea82 100644
--- a/src/lib/libc/net/getservbyname.c
+++ b/src/lib/libc/net/getservbyname.c
@@ -1,5 +1,3 @@
1/* $NetBSD: getservbyname.c,v 1.4 1995/02/25 06:20:36 cgd Exp $ */
2
3/* 1/*
4 * Copyright (c) 1983, 1993 2 * Copyright (c) 1983, 1993
5 * The Regents of the University of California. All rights reserved. 3 * The Regents of the University of California. All rights reserved.
@@ -12,11 +10,7 @@
12 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission. 15 * without specific prior written permission.
22 * 16 *
@@ -34,27 +28,30 @@
34 */ 28 */
35 29
36#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
37#if 0 31static char rcsid[] = "$OpenBSD: getservbyname.c,v 1.6 2003/06/02 20:18:35 millert Exp $";
38static char sccsid[] = "@(#)getservbyname.c 8.1 (Berkeley) 6/4/93";
39#else
40static char rcsid[] = "$NetBSD: getservbyname.c,v 1.4 1995/02/25 06:20:36 cgd Exp $";
41#endif
42#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
43 33
44#include <netdb.h> 34#include <netdb.h>
45#include <string.h> 35#include <string.h>
36#include "thread_private.h"
46 37
47extern int _serv_stayopen; 38extern int _serv_stayopen;
48 39
40_THREAD_PRIVATE_MUTEX(getservbyname_r);
41
49struct servent * 42struct servent *
50getservbyname(name, proto) 43getservbyname_r(name, proto, se, buf, buflen)
51 const char *name, *proto; 44 const char *name, *proto;
45 struct servent *se;
46 char *buf;
47 int buflen;
52{ 48{
53 register struct servent *p; 49 register struct servent *p;
54 register char **cp; 50 register char **cp;
55 51
52 _THREAD_PRIVATE_MUTEX_LOCK(getservbyname_r);
56 setservent(_serv_stayopen); 53 setservent(_serv_stayopen);
57 while (p = getservent()) { 54 while ((p = getservent())) {
58 if (strcmp(name, p->s_name) == 0) 55 if (strcmp(name, p->s_name) == 0)
59 goto gotname; 56 goto gotname;
60 for (cp = p->s_aliases; *cp; cp++) 57 for (cp = p->s_aliases; *cp; cp++)
@@ -67,5 +64,20 @@ gotname:
67 } 64 }
68 if (!_serv_stayopen) 65 if (!_serv_stayopen)
69 endservent(); 66 endservent();
67 _THREAD_PRIVATE_MUTEX_UNLOCK(getservbyname_r);
70 return (p); 68 return (p);
71} 69}
70
71struct servent *getservbyname(name, proto)
72 const char *name, *proto;
73{
74 _THREAD_PRIVATE_KEY(getservbyname);
75 static char buf[4096];
76 char *bufp = (char*)_THREAD_PRIVATE(getservbyname, buf, NULL);
77
78 if (bufp == NULL)
79 return (NULL);
80 return getservbyname_r(name, proto, (struct servent*) bufp,
81 bufp + sizeof(struct servent),
82 sizeof buf - sizeof(struct servent) );
83}
diff --git a/src/lib/libc/net/getservbyport.c b/src/lib/libc/net/getservbyport.c
index c34790737b..992a77d638 100644
--- a/src/lib/libc/net/getservbyport.c
+++ b/src/lib/libc/net/getservbyport.c
@@ -1,5 +1,3 @@
1/* $NetBSD: getservbyport.c,v 1.4 1995/02/25 06:20:37 cgd Exp $ */
2
3/* 1/*
4 * Copyright (c) 1983, 1993 2 * Copyright (c) 1983, 1993
5 * The Regents of the University of California. All rights reserved. 3 * The Regents of the University of California. All rights reserved.
@@ -12,11 +10,7 @@
12 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission. 15 * without specific prior written permission.
22 * 16 *
@@ -34,11 +28,7 @@
34 */ 28 */
35 29
36#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
37#if 0 31static char rcsid[] = "$OpenBSD: getservbyport.c,v 1.4 2003/06/02 20:18:35 millert Exp $";
38static char sccsid[] = "@(#)getservbyport.c 8.1 (Berkeley) 6/4/93";
39#else
40static char rcsid[] = "$NetBSD: getservbyport.c,v 1.4 1995/02/25 06:20:37 cgd Exp $";
41#endif
42#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
43 33
44#include <netdb.h> 34#include <netdb.h>
@@ -54,7 +44,7 @@ getservbyport(port, proto)
54 register struct servent *p; 44 register struct servent *p;
55 45
56 setservent(_serv_stayopen); 46 setservent(_serv_stayopen);
57 while (p = getservent()) { 47 while ((p = getservent())) {
58 if (p->s_port != port) 48 if (p->s_port != port)
59 continue; 49 continue;
60 if (proto == 0 || strcmp(p->s_proto, proto) == 0) 50 if (proto == 0 || strcmp(p->s_proto, proto) == 0)
diff --git a/src/lib/libc/net/getservent.3 b/src/lib/libc/net/getservent.3
index 9e0656be00..af75f5037b 100644
--- a/src/lib/libc/net/getservent.3
+++ b/src/lib/libc/net/getservent.3
@@ -1,4 +1,4 @@
1.\" $NetBSD: getservent.3,v 1.3 1995/02/25 06:20:38 cgd Exp $ 1.\" $OpenBSD: getservent.3,v 1.13 2003/12/30 10:35:36 jmc Exp $
2.\" 2.\"
3.\" Copyright (c) 1983, 1991, 1993 3.\" Copyright (c) 1983, 1991, 1993
4.\" The Regents of the University of California. All rights reserved. 4.\" The Regents of the University of California. All rights reserved.
@@ -11,11 +11,7 @@
11.\" 2. Redistributions in binary form must reproduce the above copyright 11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the 12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution. 13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software 14.\" 3. Neither the name of the University nor the names of its contributors
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 15.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission. 16.\" without specific prior written permission.
21.\" 17.\"
@@ -31,11 +27,9 @@
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE. 28.\" SUCH DAMAGE.
33.\" 29.\"
34.\" @(#)getservent.3 8.3 (Berkeley) 1/12/94
35.\"
36.Dd January 12, 1994 30.Dd January 12, 1994
37.Dt GETSERVENT 3 31.Dt GETSERVENT 3
38.Os BSD 4.2 32.Os
39.Sh NAME 33.Sh NAME
40.Nm getservent , 34.Nm getservent ,
41.Nm getservbyport , 35.Nm getservbyport ,
@@ -46,26 +40,23 @@
46.Sh SYNOPSIS 40.Sh SYNOPSIS
47.Fd #include <netdb.h> 41.Fd #include <netdb.h>
48.Ft struct servent * 42.Ft struct servent *
49.Fn getservent 43.Fn getservent "void"
50.Ft struct servent * 44.Ft struct servent *
51.Fn getservbyname "char *name" "char *proto" 45.Fn getservbyname "const char *name" "const char *proto"
52.Ft struct servent * 46.Ft struct servent *
53.Fn getservbyport "int port" proto 47.Fn getservbyport "int port" "const char *proto"
54.Ft void 48.Ft void
55.Fn setservent "int stayopen" 49.Fn setservent "int stayopen"
56.Ft void 50.Ft void
57.Fn endservent void 51.Fn endservent "void"
58.Sh DESCRIPTION 52.Sh DESCRIPTION
59The 53The
60.Fn getservent , 54.Fn getservent ,
61.Fn getservbyname , 55.Fn getservbyname ,
62and 56and
63.Fn getservbyport 57.Fn getservbyport
64functions 58functions each return a pointer to an object with the following structure
65each return a pointer to an object with the 59containing the broken-out fields of a line in the network services database,
66following structure
67containing the broken-out
68fields of a line in the network services data base,
69.Pa /etc/services . 60.Pa /etc/services .
70.Bd -literal -offset indent 61.Bd -literal -offset indent
71struct servent { 62struct servent {
@@ -81,59 +72,50 @@ The members of this structure are:
81.It Fa s_name 72.It Fa s_name
82The official name of the service. 73The official name of the service.
83.It Fa s_aliases 74.It Fa s_aliases
84A zero terminated list of alternate names for the service. 75A zero-terminated list of alternate names for the service.
85.It Fa s_port 76.It Fa s_port
86The port number at which the service resides. 77The port number at which the service resides.
87Port numbers are returned in network byte order. 78Port numbers are returned in network byte order.
88.It Fa s_proto 79.It Fa s_proto
89The name of the protocol to use when contacting the 80The name of the protocol to use when contacting the service.
90service.
91.El 81.El
92.Pp 82.Pp
93The 83The
94.Fn getservent 84.Fn getservent
95function 85function reads the next line of the file, opening the file if necessary.
96reads the next line of the file, opening the file if necessary.
97.Pp 86.Pp
98The 87The
99.Fn setservent 88.Fn setservent
100function 89function opens and rewinds the file.
101opens and rewinds the file. If the 90If the
102.Fa stayopen 91.Fa stayopen
103flag is non-zero, 92flag is non-zero,
104the net data base will not be closed after each call to 93the net database will not be closed after each call to
105.Fn getservbyname 94.Fn getservbyname
106or 95or
107.Fn getservbyport . 96.Fn getservbyport .
108.Pp 97.Pp
109The 98The
110.Fn endservent 99.Fn endservent
111function 100function closes the file.
112closes the file.
113.Pp 101.Pp
114The 102The
115.Fn getservbyname 103.Fn getservbyname
116and 104and
117.Fn getservbyport 105.Fn getservbyport
118functions 106functions sequentially search from the beginning of the file until a
119sequentially search from the beginning 107matching protocol name or port number (specified in network byte order)
120of the file until a matching 108is found, or until
121protocol name or
122port number is found,
123or until
124.Dv EOF 109.Dv EOF
125is encountered. 110is encountered.
126If a protocol name is also supplied (non- 111If a protocol name is also supplied (non-null),
127.Dv NULL ) ,
128searches must also match the protocol. 112searches must also match the protocol.
129.ne 1i
130.Sh FILES 113.Sh FILES
131.Bl -tag -width /etc/services -compact 114.Bl -tag -width /etc/services -compact
132.It Pa /etc/services 115.It Pa /etc/services
133.El 116.El
134.Sh DIAGNOSTICS 117.Sh DIAGNOSTICS
135Null pointer 118Null pointer (0) returned on
136(0) returned on
137.Dv EOF 119.Dv EOF
138or error. 120or error.
139.Sh SEE ALSO 121.Sh SEE ALSO
@@ -147,11 +129,9 @@ The
147.Fn setservent , 129.Fn setservent ,
148and 130and
149.Fn endservent 131.Fn endservent
150functions appeared in 132functions appeared in
151.Bx 4.2 . 133.Bx 4.2 .
152.Sh BUGS 134.Sh BUGS
153These functions use static data storage; 135These functions use static data storage; if the data is needed for future use,
154if the data is needed for future use, it should be 136it should be copied before any subsequent calls overwrite it.
155copied before any subsequent calls overwrite it. 137Expecting port numbers to fit in a 32-bit quantity is probably naive.
156Expecting port numbers to fit in a 32 bit
157quantity is probably naive.
diff --git a/src/lib/libc/net/getservent.c b/src/lib/libc/net/getservent.c
index 316891450e..bad3316f6c 100644
--- a/src/lib/libc/net/getservent.c
+++ b/src/lib/libc/net/getservent.c
@@ -1,5 +1,3 @@
1/* $NetBSD: getservent.c,v 1.4 1995/02/25 06:20:38 cgd Exp $ */
2
3/* 1/*
4 * Copyright (c) 1983, 1993 2 * Copyright (c) 1983, 1993
5 * The Regents of the University of California. All rights reserved. 3 * The Regents of the University of California. All rights reserved.
@@ -12,11 +10,7 @@
12 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission. 15 * without specific prior written permission.
22 * 16 *
@@ -34,11 +28,7 @@
34 */ 28 */
35 29
36#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
37#if 0 31static char rcsid[] = "$OpenBSD: getservent.c,v 1.6 2003/06/02 20:18:35 millert Exp $";
38static char sccsid[] = "@(#)getservent.c 8.1 (Berkeley) 6/4/93";
39#else
40static char rcsid[] = "$NetBSD: getservent.c,v 1.4 1995/02/25 06:20:38 cgd Exp $";
41#endif
42#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
43 33
44#include <sys/types.h> 34#include <sys/types.h>
@@ -80,20 +70,25 @@ endservent()
80struct servent * 70struct servent *
81getservent() 71getservent()
82{ 72{
83 char *p; 73 char *p, *cp, **q, *endp;
84 register char *cp, **q; 74 long l;
75 size_t len;
85 76
86 if (servf == NULL && (servf = fopen(_PATH_SERVICES, "r" )) == NULL) 77 if (servf == NULL && (servf = fopen(_PATH_SERVICES, "r" )) == NULL)
87 return (NULL); 78 return (NULL);
88again: 79again:
89 if ((p = fgets(line, BUFSIZ, servf)) == NULL) 80 if ((p = fgetln(servf, &len)) == NULL)
90 return (NULL); 81 return (NULL);
91 if (*p == '#') 82 if (p[len-1] == '\n')
83 len--;
84 if (len >= sizeof(line) || len == 0)
92 goto again; 85 goto again;
93 cp = strpbrk(p, "#\n"); 86 p = memcpy(line, p, len);
94 if (cp == NULL) 87 line[len] = '\0';
88 if (*p == '#')
95 goto again; 89 goto again;
96 *cp = '\0'; 90 if ((cp = strchr(p, '#')) != NULL)
91 *cp = '\0';
97 serv.s_name = p; 92 serv.s_name = p;
98 p = strpbrk(p, " \t"); 93 p = strpbrk(p, " \t");
99 if (p == NULL) 94 if (p == NULL)
@@ -105,7 +100,10 @@ again:
105 if (cp == NULL) 100 if (cp == NULL)
106 goto again; 101 goto again;
107 *cp++ = '\0'; 102 *cp++ = '\0';
108 serv.s_port = htons((u_short)atoi(p)); 103 l = strtol(p, &endp, 10);
104 if (endp == p || *endp != '\0' || l < 0 || l > USHRT_MAX)
105 goto again;
106 serv.s_port = htons((in_port_t)l);
109 serv.s_proto = cp; 107 serv.s_proto = cp;
110 q = serv.s_aliases = serv_aliases; 108 q = serv.s_aliases = serv_aliases;
111 cp = strpbrk(cp, " \t"); 109 cp = strpbrk(cp, " \t");
diff --git a/src/lib/libc/net/herror.c b/src/lib/libc/net/herror.c
index 41adbf1055..e8f6fa28fc 100644
--- a/src/lib/libc/net/herror.c
+++ b/src/lib/libc/net/herror.c
@@ -1,9 +1,11 @@
1/* $NetBSD: herror.c,v 1.5 1995/02/25 06:20:39 cgd Exp $ */ 1/* $OpenBSD: herror.c,v 1.5 2003/06/02 20:18:35 millert Exp $ */
2 2
3/*- 3/*
4 * ++Copyright++ 1987, 1993
5 * -
4 * Copyright (c) 1987, 1993 6 * Copyright (c) 1987, 1993
5 * The Regents of the University of California. All rights reserved. 7 * The Regents of the University of California. All rights reserved.
6 * 8 *
7 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
9 * are met: 11 * are met:
@@ -12,14 +14,10 @@
12 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 15 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 16 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 17 * 3. Neither the name of the University nor the names of its contributors
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 18 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission. 19 * without specific prior written permission.
22 * 20 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -56,26 +54,27 @@
56#if defined(LIBC_SCCS) && !defined(lint) 54#if defined(LIBC_SCCS) && !defined(lint)
57#if 0 55#if 0
58static char sccsid[] = "@(#)herror.c 8.1 (Berkeley) 6/4/93"; 56static char sccsid[] = "@(#)herror.c 8.1 (Berkeley) 6/4/93";
59static char rcsid[] = "$Id: herror.c,v 4.9.1.1 1993/05/02 23:14:35 vixie Rel "; 57static char rcsid[] = "$From: herror.c,v 8.3 1996/08/05 08:31:35 vixie Exp $";
60#else 58#else
61static char rcsid[] = "$NetBSD: herror.c,v 1.5 1995/02/25 06:20:39 cgd Exp $"; 59static char rcsid[] = "$OpenBSD: herror.c,v 1.5 2003/06/02 20:18:35 millert Exp $";
62#endif 60#endif
63#endif /* LIBC_SCCS and not lint */ 61#endif /* LIBC_SCCS and not lint */
64 62
65#include <sys/types.h> 63#include <sys/types.h>
64#include <sys/param.h>
66#include <sys/uio.h> 65#include <sys/uio.h>
67#include <netdb.h> 66#include <netdb.h>
68#include <unistd.h> 67#include <unistd.h>
69#include <string.h> 68#include <string.h>
70 69
71char *h_errlist[] = { 70const char *h_errlist[] = {
72 "Error 0", 71 "Resolver Error 0 (no error)",
73 "Unknown host", /* 1 HOST_NOT_FOUND */ 72 "Unknown host", /* 1 HOST_NOT_FOUND */
74 "Host name lookup failure", /* 2 TRY_AGAIN */ 73 "Host name lookup failure", /* 2 TRY_AGAIN */
75 "Unknown server error", /* 3 NO_RECOVERY */ 74 "Unknown server error", /* 3 NO_RECOVERY */
76 "No address associated with name", /* 4 NO_ADDRESS */ 75 "No address associated with name", /* 4 NO_ADDRESS */
77}; 76};
78int h_nerr = { sizeof(h_errlist)/sizeof(h_errlist[0]) }; 77int h_nerr = { sizeof h_errlist / sizeof h_errlist[0] };
79 78
80extern int h_errno; 79extern int h_errno;
81 80
@@ -98,8 +97,7 @@ herror(s)
98 v->iov_len = 2; 97 v->iov_len = 2;
99 v++; 98 v++;
100 } 99 }
101 v->iov_base = (u_int)h_errno < h_nerr ? 100 v->iov_base = (char *)hstrerror(h_errno);
102 h_errlist[h_errno] : "Unknown error";
103 v->iov_len = strlen(v->iov_base); 101 v->iov_len = strlen(v->iov_base);
104 v++; 102 v++;
105 v->iov_base = "\n"; 103 v->iov_base = "\n";
@@ -107,9 +105,13 @@ herror(s)
107 writev(STDERR_FILENO, iov, (v - iov) + 1); 105 writev(STDERR_FILENO, iov, (v - iov) + 1);
108} 106}
109 107
110char * 108const char *
111hstrerror(err) 109hstrerror(err)
112 int err; 110 int err;
113{ 111{
114 return (u_int)err < h_nerr ? h_errlist[err] : "Unknown resolver error"; 112 if (err < 0)
113 return ("Resolver internal error");
114 else if (err < h_nerr)
115 return (h_errlist[err]);
116 return ("Unknown resolver error");
115} 117}
diff --git a/src/lib/libc/net/htonl.c b/src/lib/libc/net/htonl.c
index ac85cb0fd7..73b7432731 100644
--- a/src/lib/libc/net/htonl.c
+++ b/src/lib/libc/net/htonl.c
@@ -1,29 +1,25 @@
1/* $NetBSD: htonl.c,v 1.5 1995/04/28 23:25:14 jtc Exp $ */
2
3/* 1/*
4 * Written by J.T. Conklin <jtc@netbsd.org>. 2 * Written by J.T. Conklin <jtc@netbsd.org>.
5 * Public domain. 3 * Public domain.
6 */ 4 */
7 5
8#if defined(LIBC_SCCS) && !defined(lint) 6#if defined(LIBC_SCCS) && !defined(lint)
9static char *rcsid = "$NetBSD: htonl.c,v 1.5 1995/04/28 23:25:14 jtc Exp $"; 7static char *rcsid = "$OpenBSD: htonl.c,v 1.4 1996/12/12 03:19:55 tholo Exp $";
10#endif 8#endif /* LIBC_SCCS and not lint */
11 9
12#include <sys/types.h> 10#include <sys/types.h>
13#include <machine/endian.h> 11#include <machine/endian.h>
14 12
15#undef htonl 13#undef htonl
16 14
17unsigned long 15u_int32_t
18htonl(x) 16htonl(x)
19 unsigned long x; 17 u_int32_t x;
20{ 18{
21 u_int32_t y = x;
22
23#if BYTE_ORDER == LITTLE_ENDIAN 19#if BYTE_ORDER == LITTLE_ENDIAN
24 u_char *s = (u_char *)&y; 20 u_char *s = (u_char *)&x;
25 return s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]; 21 return (u_int32_t)(s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]);
26#else 22#else
27 return y; 23 return x;
28#endif 24#endif
29} 25}
diff --git a/src/lib/libc/net/htons.c b/src/lib/libc/net/htons.c
index b2500a51d1..ded70712ea 100644
--- a/src/lib/libc/net/htons.c
+++ b/src/lib/libc/net/htons.c
@@ -1,26 +1,23 @@
1/* $NetBSD: htons.c,v 1.5 1995/04/28 23:25:19 jtc Exp $ */
2
3/* 1/*
4 * Written by J.T. Conklin <jtc@netbsd.org>. 2 * Written by J.T. Conklin <jtc@netbsd.org>.
5 * Public domain. 3 * Public domain.
6 */ 4 */
7 5
8#if defined(LIBC_SCCS) && !defined(lint) 6#if defined(LIBC_SCCS) && !defined(lint)
9static char *rcsid = "$NetBSD: htons.c,v 1.5 1995/04/28 23:25:19 jtc Exp $"; 7static char *rcsid = "$OpenBSD: htons.c,v 1.7 2002/02/19 19:39:36 millert Exp $";
10#endif 8#endif /* LIBC_SCCS and not lint */
11 9
12#include <sys/types.h> 10#include <sys/types.h>
13#include <machine/endian.h> 11#include <machine/endian.h>
14 12
15#undef htons 13#undef htons
16 14
17unsigned short 15u_int16_t
18htons(x) 16htons(u_int16_t x)
19 unsigned short x;
20{ 17{
21#if BYTE_ORDER == LITTLE_ENDIAN 18#if BYTE_ORDER == LITTLE_ENDIAN
22 u_char *s = (u_char *) &x; 19 u_char *s = (u_char *) &x;
23 return s[0] << 8 | s[1]; 20 return (u_int16_t)(s[0] << 8 | s[1]);
24#else 21#else
25 return x; 22 return x;
26#endif 23#endif
diff --git a/src/lib/libc/net/if_indextoname.3 b/src/lib/libc/net/if_indextoname.3
new file mode 100644
index 0000000000..30293dcdf2
--- /dev/null
+++ b/src/lib/libc/net/if_indextoname.3
@@ -0,0 +1,136 @@
1.\" $OpenBSD: if_indextoname.3,v 1.7 2003/08/08 09:26:02 jmc 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. Neither the name of the University nor the names of its contributors
14.\" may be used to endorse or promote products derived from this software
15.\" without specific prior written permission.
16.\"
17.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27.\" SUCH DAMAGE.
28.\"
29.\" From: @(#)rcmd.3 8.1 (Berkeley) 6/4/93
30.\"
31.Dd May 21, 1998
32.Dt IF_NAMETOINDEX 3
33.Os
34.Sh NAME
35.Nm if_nametoindex ,
36.Nm if_indextoname ,
37.Nm if_nameindex ,
38.Nm if_freenameindex
39.Nd convert interface index to name, and vice versa
40.Sh SYNOPSIS
41.Fd #include <net/if.h>
42.Ft "unsigned int"
43.Fn if_nametoindex "const char *ifname"
44.Ft "char *"
45.Fn if_indextoname "unsigned int ifindex" "char *ifname"
46.Ft "struct if_nameindex *"
47.Fn if_nameindex "void"
48.Ft "void"
49.Fn if_freenameindex "struct if_nameindex *ptr"
50.Sh DESCRIPTION
51These functions map interface indexes to interface names (such as
52.Dq lo0 ) ,
53and vice versa.
54.Pp
55The
56.Fn if_nametoindex
57function converts an interface name specified by the
58.Fa ifname
59argument to an interface index (positive integer value).
60If the specified interface does not exist, 0 will be returned.
61.Pp
62.Fn if_indextoname
63converts an interface index specified by the
64.Fa ifindex
65argument to an interface name.
66The
67.Fa ifname
68argument must point to a buffer of at least
69.Dv IF_NAMESIZE
70bytes into which the interface name corresponding to the specified index is
71returned.
72.Pf ( Dv IF_NAMESIZE
73is also defined in
74.Aq Pa net/if.h
75and its value includes a terminating null byte at the end of the
76interface name.)
77This pointer is also the return value of the function.
78If there is no interface corresponding to the specified index,
79.Dv NULL
80is returned.
81.Pp
82.Fn if_nameindex
83returns an array of
84.Fa if_nameindex
85structures.
86.Fa if_nametoindex
87is also defined in
88.Aq Pa net/if.h ,
89and is as follows:
90.Bd -literal -offset
91struct if_nameindex {
92 unsigned int if_index; /* 1, 2, ... */
93 char *if_name; /* null terminated name: "le0", ... */
94};
95.Ed
96.Pp
97The end of the array of structures is indicated by a structure with
98an
99.Fa if_index
100of 0 and an
101.Fa if_name
102of
103.Dv NULL .
104The function returns a null pointer on error.
105The memory used for this array of structures along with the interface
106names pointed to by the
107.Fa if_name
108members is obtained dynamically.
109This memory is freed by the
110.Fn if_freenameindex
111function.
112.Pp
113.Fn if_freenameindex
114takes a pointer that was returned by
115.Fn if_nameindex
116as argument
117.Pq Fa ptr ,
118and it reclaims the region allocated.
119.Sh DIAGNOSTICS
120.Fn if_nametoindex
121returns 0 on error, positive integer on success.
122.Fn if_indextoname
123and
124.Fn if_nameindex
125return
126.Dv NULL
127on errors.
128.Sh SEE ALSO
129.Xr getifaddrs 3 ,
130.Xr networking 4
131.Pp
132R. Gilligan, S. Thomson, J. Bound, and W. Stevens,
133``Basic Socket Interface Extensions for IPv6,'' RFC 2553, March 1999.
134.Sh STANDARDS
135These functions are defined in ``Basic Socket Interface Extensions for IPv6''
136.Pq RFC 2533 .
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
index 49bac97e96..43cb5bafd7 100644
--- a/src/lib/libc/net/inet.3
+++ b/src/lib/libc/net/inet.3
@@ -1,4 +1,5 @@
1.\" $NetBSD: inet.3,v 1.4 1995/02/27 09:45:26 chopps Exp $ 1.\" $OpenBSD: inet.3,v 1.18 2003/09/09 12:00:39 jmc Exp $
2.\" $NetBSD: inet.3,v 1.7 1997/06/18 02:25:24 lukem Exp $
2.\" 3.\"
3.\" Copyright (c) 1983, 1990, 1991, 1993 4.\" Copyright (c) 1983, 1990, 1991, 1993
4.\" The Regents of the University of California. All rights reserved. 5.\" The Regents of the University of California. All rights reserved.
@@ -11,11 +12,7 @@
11.\" 2. Redistributions in binary form must reproduce the above copyright 12.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the 13.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution. 14.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software 15.\" 3. Neither the name of the University nor the names of its contributors
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 16.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission. 17.\" without specific prior written permission.
21.\" 18.\"
@@ -33,36 +30,43 @@
33.\" 30.\"
34.\" @(#)inet.3 8.1 (Berkeley) 6/4/93 31.\" @(#)inet.3 8.1 (Berkeley) 6/4/93
35.\" 32.\"
36.Dd June 4, 1993 33.Dd June 18, 1997
37.Dt INET 3 34.Dt INET 3
38.Os BSD 4.2 35.Os
39.Sh NAME 36.Sh NAME
40.Nm inet_aton ,
41.Nm inet_addr , 37.Nm inet_addr ,
38.Nm inet_aton ,
39.Nm inet_lnaof ,
40.Nm inet_makeaddr ,
41.Nm inet_netof ,
42.Nm inet_network , 42.Nm inet_network ,
43.Nm inet_ntoa , 43.Nm inet_ntoa ,
44.Nm inet_makeaddr , 44.Nm inet_ntop ,
45.Nm inet_lnaof , 45.Nm inet_pton
46.Nm inet_netof
47.Nd Internet address manipulation routines 46.Nd Internet address manipulation routines
48.Sh SYNOPSIS 47.Sh SYNOPSIS
48.Fd #include <sys/types.h>
49.Fd #include <sys/socket.h> 49.Fd #include <sys/socket.h>
50.Fd #include <netinet/in.h> 50.Fd #include <netinet/in.h>
51.Fd #include <arpa/inet.h> 51.Fd #include <arpa/inet.h>
52.Ft int 52.Ft in_addr_t
53.Fn inet_aton "const char *cp" "struct in_addr *pin"
54.Ft unsigned long
55.Fn inet_addr "const char *cp" 53.Fn inet_addr "const char *cp"
56.Ft unsigned long 54.Ft int
55.Fn inet_aton "const char *cp" "struct in_addr *addr"
56.Ft in_addr_t
57.Fn inet_lnaof "struct in_addr in"
58.Ft struct in_addr
59.Fn inet_makeaddr "in_addr_t net" "in_addr_t lna"
60.Ft in_addr_t
61.Fn inet_netof "struct in_addr in"
62.Ft in_addr_t
57.Fn inet_network "const char *cp" 63.Fn inet_network "const char *cp"
58.Ft char * 64.Ft char *
59.Fn inet_ntoa "struct in_addr in" 65.Fn inet_ntoa "struct in_addr in"
60.Ft struct in_addr 66.Ft const char *
61.Fn inet_makeaddr "int net" "int lna" 67.Fn inet_ntop "int af" "const void *src" "char *dst" "size_t size"
62.Ft unsigned long 68.Ft int
63.Fn inet_lnaof "struct in_addr in" 69.Fn inet_pton "int af" "const char *src" "void *dst"
64.Ft unsigned long
65.Fn inet_netof "struct in_addr in"
66.Sh DESCRIPTION 70.Sh DESCRIPTION
67The routines 71The routines
68.Fn inet_aton , 72.Fn inet_aton ,
@@ -74,11 +78,26 @@ numbers expressed in the Internet standard
74.Ql \&. 78.Ql \&.
75notation. 79notation.
76The 80The
81.Fn inet_pton
82function converts a presentation format address (that is, printable form
83as held in a character string) to network format (usually a
84.Li struct in_addr
85or some other internal binary representation, in network byte order).
86It returns 1 if the address was valid for the specified address family, or
870 if the address wasn't parseable in the specified address family, or \-1
88if some system error occurred (in which case
89.Va errno
90will have been set).
91This function is presently valid for
92.Dv AF_INET
93and
94.Dv AF_INET6 .
95The
77.Fn inet_aton 96.Fn inet_aton
78routine interprets the specified character string as an Internet address, 97routine interprets the specified character string as an Internet address,
79placing the address into the structure provided. 98placing the address into the structure provided.
80It returns 1 if the string was successfully interpreted, 99It returns 1 if the string was successfully interpreted,
81or 0 if the string is invalid. 100or 0 if the string was invalid.
82The 101The
83.Fn inet_addr 102.Fn inet_addr
84and 103and
@@ -86,17 +105,32 @@ and
86functions return numbers suitable for use 105functions return numbers suitable for use
87as Internet addresses and Internet network 106as Internet addresses and Internet network
88numbers, respectively. 107numbers, respectively.
108.Pp
109The function
110.Fn inet_ntop
111converts an address from network format (usually a
112.Li struct in_addr
113or some other binary form, in network byte order) to presentation format
114(suitable for external display purposes).
115It returns
116.Dv NULL
117if a system
118error occurs (in which case,
119.Va errno
120will have been set), or it returns a pointer to the destination string.
89The routine 121The routine
90.Fn inet_ntoa 122.Fn inet_ntoa
91takes an Internet address and returns an 123takes an Internet address and returns an
92.Tn ASCII 124.Tn ASCII
93string representing the address in 125string representing the address in
94.Ql \&. 126.Ql \&.
95notation. The routine 127notation.
128The routine
96.Fn inet_makeaddr 129.Fn inet_makeaddr
97takes an Internet network number and a local 130takes an Internet network number and a local
98network address and constructs an Internet address 131network address and constructs an Internet address
99from it. The routines 132from it.
133The routines
100.Fn inet_netof 134.Fn inet_netof
101and 135and
102.Fn inet_lnaof 136.Fn inet_lnaof
@@ -108,7 +142,7 @@ All Internet addresses are returned in network
108order (bytes ordered from left to right). 142order (bytes ordered from left to right).
109All network numbers and local address parts are 143All network numbers and local address parts are
110returned as machine format integer values. 144returned as machine format integer values.
111.Sh INTERNET ADDRESSES 145.Sh INTERNET ADDRESSES (IP VERSION 4)
112Values specified using the 146Values specified using the
113.Ql \&. 147.Ql \&.
114notation take one 148notation take one
@@ -122,28 +156,27 @@ a
122.Pp 156.Pp
123When four parts are specified, each is interpreted 157When four parts are specified, each is interpreted
124as a byte of data and assigned, from left to right, 158as a byte of data and assigned, from left to right,
125to the four bytes of an Internet address. Note 159to the four bytes of an Internet address.
126that when an Internet address is viewed as a 32-bit 160Note that when an Internet address is viewed as a 32-bit
127integer quantity on the 161integer quantity on a system that uses little-endian
128.Tn VAX 162byte order (such as the
129the bytes referred to 163.Tn Intel 386, 486
130above appear as 164and
165.Tn Pentium
166processors) the bytes referred to above appear as
131.Dq Li d.c.b.a . 167.Dq Li d.c.b.a .
132That is, 168That is, little-endian bytes are ordered from right to left.
133.Tn VAX
134bytes are
135ordered from right to left.
136.Pp 169.Pp
137When a three part address is specified, the last 170When a three part address is specified, the last
138part is interpreted as a 16-bit quantity and placed 171part is interpreted as a 16-bit quantity and placed
139in the right-most two bytes of the network address. 172in the rightmost two bytes of the network address.
140This makes the three part address format convenient 173This makes the three part address format convenient
141for specifying Class B network addresses as 174for specifying Class B network addresses as
142.Dq Li 128.net.host . 175.Dq Li 128.net.host .
143.Pp 176.Pp
144When a two part address is supplied, the last part 177When a two part address is supplied, the last part
145is interpreted as a 24-bit quantity and placed in 178is interpreted as a 24-bit quantity and placed in
146the right most three bytes of the network address. 179the rightmost three bytes of the network address.
147This makes the two part address format convenient 180This makes the two part address format convenient
148for specifying Class A network addresses as 181for specifying Class A network addresses as
149.Dq Li net.host . 182.Dq Li net.host .
@@ -155,12 +188,89 @@ rearrangement.
155All numbers supplied as 188All numbers supplied as
156.Dq parts 189.Dq parts
157in a 190in a
158.Ql \&. 191.Ql \&.
159notation 192notation
160may be decimal, octal, or hexadecimal, as specified 193may be decimal, octal, or hexadecimal, as specified
161in the C language (i.e., a leading 0x or 0X implies 194in the C language (i.e., a leading 0x or 0X implies
162hexadecimal; otherwise, a leading 0 implies octal; 195hexadecimal; otherwise, a leading 0 implies octal;
163otherwise, the number is interpreted as decimal). 196otherwise, the number is interpreted as decimal).
197.Sh INTERNET ADDRESSES (IP VERSION 6)
198In order to support scoped IPv6 addresses,
199.Xr getaddrinfo 3
200and
201.Xr getnameinfo 3
202are recommended rather than the functions presented here.
203.Pp
204The presentation format of an IPv6 address is given in RFC 2373:
205.Pp
206There are three conventional forms for representing IPv6 addresses as
207text strings:
208.Bl -enum
209.It
210The preferred form is x:x:x:x:x:x:x:x, where the 'x's are the
211hexadecimal values of the eight 16-bit pieces of the address.
212Examples:
213.Bd -literal -offset indent
214FEDC:BA98:7654:3210:FEDC:BA98:7654:3210
2151080:0:0:0:8:800:200C:417A
216.Ed
217.Pp
218Note that it is not necessary to write the leading zeros in an
219individual field, but there must be at least one numeral in
220every field (except for the case described in 2.).
221.It
222Due to the method of allocating certain styles of IPv6
223addresses, it will be common for addresses to contain long
224strings of zero bits.
225In order to make writing addresses
226containing zero bits easier, a special syntax is available to
227compress the zeros.
228The use of
229.Dq \&:\&:
230indicates multiple groups
231of 16 bits of zeros.
232The
233.Dq \&:\&:
234can only appear once in an
235address.
236The
237.Dq \&:\&:
238can also be used to compress the leading and/or trailing zeros in an address.
239.Pp
240For example the following addresses:
241.Bd -literal -offset indent
2421080:0:0:0:8:800:200C:417A a unicast address
243FF01:0:0:0:0:0:0:43 a multicast address
2440:0:0:0:0:0:0:1 the loopback address
2450:0:0:0:0:0:0:0 the unspecified addresses
246.Ed
247.Pp
248may be represented as:
249.Bd -literal -offset indent
2501080::8:800:200C:417A a unicast address
251FF01::43 a multicast address
252::1 the loopback address
253:: the unspecified addresses
254.Ed
255.It
256An alternative form that is sometimes more convenient when
257dealing with a mixed environment of IPv4 and IPv6 nodes is
258x:x:x:x:x:x:d.d.d.d, where the 'x's are the hexadecimal values
259of the six high-order 16-bit pieces of the address, and the 'd's
260are the decimal values of the four low-order 8-bit pieces of the
261address (standard IPv4 representation).
262Examples:
263.Bd -literal -offset indent
2640:0:0:0:0:0:13.1.68.3
2650:0:0:0:0:FFFF:129.144.52.38
266.Ed
267.Pp
268or in compressed form:
269.Bd -literal -offset indent
270::13.1.68.3
271::FFFF:129.144.52.38
272.Ed
273.El
164.Sh DIAGNOSTICS 274.Sh DIAGNOSTICS
165The constant 275The constant
166.Dv INADDR_NONE 276.Dv INADDR_NONE
@@ -170,28 +280,76 @@ and
170.Fn inet_network 280.Fn inet_network
171for malformed requests. 281for malformed requests.
172.Sh SEE ALSO 282.Sh SEE ALSO
283.Xr byteorder 3 ,
173.Xr gethostbyname 3 , 284.Xr gethostbyname 3 ,
174.Xr getnetent 3 , 285.Xr getnetent 3 ,
286.Xr inet_net 3 ,
175.Xr hosts 5 , 287.Xr hosts 5 ,
176.Xr networks 5 , 288.Xr networks 5
289.Rs
290.%R RFC 2373
291.%D July 1998
292.%T "IP Version 6 Addressing Architecture"
293.Re
294.Rs
295.%R RFC 3493
296.%D February 2003
297.%T "Basic Socket Interface Extensions for IPv6"
298.Re
299.Sh STANDARDS
300The
301.Nm inet_ntop
302and
303.Nm inet_pton
304functions conform to the IETF IPv6 BSD API and address formatting
305specifications.
306Note that
307.Nm inet_pton
308does not accept 1-, 2-, or 3-part dotted addresses; all four parts
309must be specified.
310This is a narrower input set than that accepted by
311.Nm inet_aton .
177.Sh HISTORY 312.Sh HISTORY
178These 313The
179functions appeared in 314.Nm inet_addr ,
315.Nm inet_network ,
316.Nm inet_makeaddr ,
317.Nm inet_lnaof
318and
319.Nm inet_netof
320functions appeared in
180.Bx 4.2 . 321.Bx 4.2 .
322The
323.Nm inet_aton
324and
325.Nm inet_ntoa
326functions appeared in
327.Bx 4.3 .
328The
329.Nm inet_pton
330and
331.Nm inet_ntop
332functions appeared in BIND 4.9.4.
181.Sh BUGS 333.Sh BUGS
182The value 334The value
183.Dv INADDR_NONE 335.Dv INADDR_NONE
184(0xffffffff) is a valid broadcast address, but 336(0xffffffff) is a valid broadcast address, but
185.Fn inet_addr 337.Fn inet_addr
186cannot return that value without indicating failure. 338cannot return that value without indicating failure.
339Also,
340.Fn inet_addr
341should have been designed to return a
342.Li struct in_addr .
187The newer 343The newer
188.Fn inet_aton 344.Fn inet_aton
189function does not share this problem. 345function does not share these problems, and almost all existing code
346should be modified to use
347.Fn inet_aton
348instead.
349.Pp
190The problem of host byte ordering versus network byte ordering is 350The problem of host byte ordering versus network byte ordering is
191confusing. 351confusing.
352.Pp
192The string returned by 353The string returned by
193.Fn inet_ntoa 354.Fn inet_ntoa
194resides in a static memory area. 355resides in a static memory area.
195.Pp
196Inet_addr should return a
197.Fa struct in_addr .
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..4e5dc22711
--- /dev/null
+++ b/src/lib/libc/net/inet6_option_space.3
@@ -0,0 +1,444 @@
1.\" $OpenBSD: inet6_option_space.3,v 1.13 2003/08/08 09:26:02 jmc 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. Neither the name of the University 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 REGENTS 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 REGENTS 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.Dd December 10, 1999
32.Dt INET6_OPTION_SPACE 3
33.Os
34.\"
35.Sh NAME
36.Nm inet6_option_space ,
37.Nm inet6_option_init ,
38.Nm inet6_option_append ,
39.Nm inet6_option_alloc ,
40.Nm inet6_option_next ,
41.Nm inet6_option_find
42.Nd IPv6 Hop-by-Hop and Destination Options manipulation
43.\"
44.Sh SYNOPSIS
45.Fd #include <netinet/in.h>
46.Ft "int"
47.Fn inet6_option_space "int nbytes"
48.Ft "int"
49.Fn inet6_option_init "void *bp" "struct cmsghdr **cmsgp" "int type"
50.Ft "int"
51.Fn inet6_option_append "struct cmsghdr *cmsg" "const u_int8_t *typep" "int multx" "int plusy"
52.Ft "u_int8_t *"
53.Fn inet6_option_alloc "struct cmsghdr *cmsg" "int datalen" "int multx" "int plusy"
54.Ft "int"
55.Fn inet6_option_next "const struct cmsghdr *cmsg" "u_int8_t **tptrp"
56.Ft "int"
57.Fn inet6_option_find "const struct cmsghdr *cmsg" "u_int8_t **tptrp" "int type"
58.\"
59.Sh DESCRIPTION
60.\"
61Building and parsing the Hop-by-Hop and Destination options is
62complicated due to alignment constraints, padding and
63ancillary data manipulation.
64RFC 2292 defines a set of functions to help the application.
65The function prototypes for
66these functions are all in the
67.Aq Pa netinet/in.h
68header.
69.\"
70.Ss inet6_option_space
71.Fn inet6_option_space
72returns the number of bytes required to hold an option when it is stored as
73ancillary data, including the
74.Li cmsghdr
75structure at the beginning,
76and any padding at the end
77.Po
78to make its size a multiple of 8 bytes
79.Pc .
80The argument is the size of the structure defining the option,
81which must include any pad bytes at the beginning
82.Po
83the value
84.Li y
85in the alignment term
86.Dq Li xn + y
87.Pc ,
88the type byte, the length byte, and the option data.
89.Pp
90Note: If multiple options are stored in a single ancillary data
91object, which is the recommended technique, this function
92overestimates the amount of space required by the size of
93.Li N-1
94.Li cmsghdr
95structures,
96where
97.Li N
98is the number of options to be stored in the object.
99This is of little consequence, since it is assumed that most
100Hop-by-Hop option headers and Destination option headers carry only
101one option
102.Pq appendix B of [RFC 2460] .
103.\"
104.Ss inet6_option_init
105.Fn inet6_option_init
106is called once per ancillary data object that will
107contain either Hop-by-Hop or Destination options.
108It returns
109.Li 0
110on success or
111.Li -1
112on an error.
113.Pp
114.Fa bp
115is a pointer to previously allocated space that will contain the
116ancillary data object.
117It must be large enough to contain all the
118individual options to be added by later calls to
119.Fn inet6_option_append
120and
121.Fn inet6_option_alloc .
122.Pp
123.Fa cmsgp
124is a pointer to a pointer to a
125.Li cmsghdr
126structure.
127.Fa *cmsgp
128is initialized by this function to point to the
129.Li cmsghdr
130structure constructed by this function in the buffer pointed to by
131.Fa bp .
132.Pp
133.Fa type
134is either
135.Dv IPV6_HOPOPTS
136or
137.Dv IPV6_DSTOPTS .
138This
139.Fa type
140is stored in the
141.Li cmsg_type
142member of the
143.Li cmsghdr
144structure pointed to by
145.Fa *cmsgp .
146.\"
147.Ss inet6_option_append
148This function appends a Hop-by-Hop option or a Destination option
149into an ancillary data object that has been initialized by
150.Fn inet6_option_init .
151This function returns
152.Li 0
153if it succeeds or
154.Li -1
155on an error.
156.Pp
157.Fa cmsg
158is a pointer to the
159.Li cmsghdr
160structure that must have been
161initialized by
162.Fn inet6_option_init .
163.Pp
164.Fa typep
165is a pointer to the 8-bit option type.
166It is assumed that this
167field is immediately followed by the 8-bit option data length field,
168which is then followed immediately by the option data.
169The caller
170initializes these three fields
171.Pq the type-length-value, or TLV
172before calling this function.
173.Pp
174The option type must have a value from
175.Li 2
176to
177.Li 255 ,
178inclusive.
179.Po
180.Li 0
181and
182.Li 1
183are reserved for the
184.Li Pad1
185and
186.Li PadN
187options, respectively.
188.Pc
189.Pp
190The option data length must have a value between
191.Li 0
192and
193.Li 255 ,
194inclusive, and is the length of the option data that follows.
195.Pp
196.Fa multx
197is the value
198.Li x
199in the alignment term
200.Dq Li xn + y .
201It must have a value of
202.Li 1 ,
203.Li 2 ,
204.Li 4 ,
205or
206.Li 8 .
207.Pp
208.Fa plusy
209is the value
210.Li y
211in the alignment term
212.Dq Li xn + y .
213It must have a value between
214.Li 0
215and
216.Li 7 ,
217inclusive.
218.\"
219.Ss inet6_option_alloc
220This function appends a Hop-by-Hop option or a Destination option
221into an ancillary data object that has been initialized by
222.Fn inet6_option_init .
223This function returns a pointer to the 8-bit
224option type field that starts the option on success, or
225.Dv NULL
226on an error.
227.Pp
228The difference between this function and
229.Fn inet6_option_append
230is that the latter copies the contents of a previously built option into
231the ancillary data object while the current function returns a
232pointer to the space in the data object where the option's TLV must
233then be built by the caller.
234.Pp
235.Fa cmsg
236is a pointer to the
237.Li cmsghdr
238structure that must have been
239initialized by
240.Fn inet6_option_init .
241.Pp
242.Fa datalen
243is the value of the option data length byte for this option.
244This value is required as an argument to allow the function to
245determine if padding must be appended at the end of the option.
246(The
247.Fn inet6_option_append
248function does not need a data length argument
249since the option data length must already be stored by the caller.)
250.Pp
251.Fa multx
252is the value
253.Li x
254in the alignment term
255.Dq Li xn + y .
256It must have a value of
257.Li 1 ,
258.Li 2 ,
259.Li 4 ,
260or
261.Li 8 .
262.Pp
263.Fa plusy
264is the value
265.Li y
266in the alignment term
267.Dq Li xn + y .
268It must have a value between
269.Li 0
270and
271.Li 7 ,
272inclusive.
273.\"
274.Ss inet6_option_next
275This function processes the next Hop-by-Hop option or Destination
276option in an ancillary data object.
277If another option remains to be
278processed, the return value of the function is
279.Li 0
280and
281.Fa *tptrp
282points to
283the 8-bit option type field
284(which is followed by the 8-bit option
285data length, followed by the option data).
286If no more options remain
287to be processed, the return value is
288.Li -1
289and
290.Fa *tptrp
291is
292.Dv NULL .
293If an error occurs, the return value is
294.Li -1
295and
296.Fa *tptrp
297is not
298.Dv NULL .
299.Pp
300.Fa cmsg
301is a pointer to
302.Li cmsghdr
303structure of which
304.Li cmsg_level
305equals
306.Dv IPPROTO_IPV6
307and
308.Li cmsg_type
309equals either
310.Dv IPV6_HOPOPTS
311or
312.Dv IPV6_DSTOPTS .
313.Pp
314.Fa tptrp
315is a pointer to a pointer to an 8-bit byte and
316.Fa *tptrp
317is used
318by the function to remember its place in the ancillary data object
319each time the function is called.
320The first time this function is
321called for a given ancillary data object,
322.Fa *tptrp
323must be set to
324.Dv NULL .
325.Pp
326Each time this function returns success,
327.Fa *tptrp
328points to the 8-bit
329option type field for the next option to be processed.
330.\"
331.Ss inet6_option_find
332This function is similar to the previously described
333.Fn inet6_option_next
334function, except this function lets the caller
335specify the option type to be searched for, instead of always
336returning the next option in the ancillary data object.
337.Fa cmsg
338is a
339pointer to
340.Li cmsghdr
341structure of which
342.Li cmsg_level
343equals
344.Dv IPPROTO_IPV6
345and
346.Li cmsg_type
347equals either
348.Dv IPV6_HOPOPTS
349or
350.Dv IPV6_DSTOPTS .
351.Pp
352.Fa tptrp
353is a pointer to a pointer to an 8-bit byte and
354.Fa *tptrp
355is used
356by the function to remember its place in the ancillary data object
357each time the function is called.
358The first time this function is
359called for a given ancillary data object,
360.Fa *tptrp
361must be set to
362.Dv NULL .
363.Pp
364This function starts searching for an option of the specified type
365beginning after the value of
366.Fa *tptrp .
367If an option of the specified
368type is located, this function returns
369.Li 0
370and
371.Fa *tptrp
372points to the 8-
373bit option type field for the option of the specified type.
374If an
375option of the specified type is not located, the return value is
376.Li -1
377and
378.Fa *tptrp
379is
380.Dv NULL .
381If an error occurs, the return value is
382.Li -1
383and
384.Fa *tptrp
385is not
386.Dv NULL .
387.\"
388.Sh EXAMPLES
389RFC 2292 gives comprehensive examples in chapter 6.
390.\"
391.Sh DIAGNOSTICS
392.Fn inet6_option_init
393and
394.Fn inet6_option_append
395return
396.Li 0
397on success or
398.Li -1
399on an error.
400.Pp
401.Fn inet6_option_alloc
402returns
403.Dv NULL
404on an error.
405.Pp
406On errors,
407.Fn inet6_option_next
408and
409.Fn inet6_option_find
410return
411.Li -1
412setting
413.Fa *tptrp
414to non
415.Dv NULL
416value.
417.\"
418.Sh SEE ALSO
419.Rs
420.%A W. Stevens
421.%A M. Thomas
422.%T "Advanced Sockets API for IPv6"
423.%N RFC 2292
424.%D February 1998
425.Re
426.Rs
427.%A S. Deering
428.%A R. Hinden
429.%T "Internet Protocol, Version 6 (IPv6) Specification"
430.%N RFC 2460
431.%D December 1998
432.Re
433.\"
434.Sh STANDARDS
435The functions
436are documented in
437.Dq Advanced Sockets API for IPv6
438.Pq RFC 2292 .
439.\"
440.Sh HISTORY
441The implementation first appeared in KAME advanced networking kit.
442.\"
443.Sh BUGS
444The text was shamelessly copied from RFC 2292.
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..33b209af4f
--- /dev/null
+++ b/src/lib/libc/net/inet6_rthdr_space.3
@@ -0,0 +1,317 @@
1.\" $OpenBSD: inet6_rthdr_space.3,v 1.13 2003/08/08 09:26:02 jmc 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. Neither the name of the University 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 REGENTS 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 REGENTS 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.Dd December 10, 1999
32.Dt INET6_RTHDR_SPACE 3
33.Os
34.\"
35.Sh NAME
36.Nm inet6_rthdr_space ,
37.Nm inet6_rthdr_init ,
38.Nm inet6_rthdr_add ,
39.Nm inet6_rthdr_lasthop ,
40.Nm inet6_rthdr_reverse ,
41.Nm inet6_rthdr_segments ,
42.Nm inet6_rthdr_getaddr ,
43.Nm inet6_rthdr_getflags
44.Nd IPv6 Routing Header Options manipulation
45.\"
46.Sh SYNOPSIS
47.Fd #include <netinet/in.h>
48.Ft size_t
49.Fn inet6_rthdr_space "int type" "int segments"
50.Ft "struct cmsghdr *"
51.Fn inet6_rthdr_init "void *bp" "int type"
52.Ft int
53.Fn inet6_rthdr_add "struct cmsghdr *cmsg" "const struct in6_addr *addr" "unsigned int flags"
54.Ft int
55.Fn inet6_rthdr_lasthop "struct cmsghdr *cmsg" "unsigned int flags"
56.Ft int
57.Fn inet6_rthdr_reverse "const struct cmsghdr *in" "struct cmsghdr *out"
58.Ft int
59.Fn inet6_rthdr_segments "const struct cmsghdr *cmsg"
60.Ft "struct in6_addr *"
61.Fn inet6_rthdr_getaddr "struct cmsghdr *cmsg" "int index"
62.Ft int
63.Fn inet6_rthdr_getflags "const struct cmsghdr *cmsg" "int index"
64.\"
65.Sh DESCRIPTION
66RFC 2292 IPv6 advanced API defines eight
67functions that the application calls to build and examine a Routing
68header.
69Four functions build a Routing header:
70.Bl -hang
71.It Fn inet6_rthdr_space
72return #bytes required for ancillary data
73.It Fn inet6_rthdr_init
74initialize ancillary data for Routing header
75.It Fn inet6_rthdr_add
76add IPv6 address & flags to Routing header
77.It Fn inet6_rthdr_lasthop
78specify the flags for the final hop
79.El
80.Pp
81Four functions deal with a returned Routing header:
82.Bl -hang
83.It Fn inet6_rthdr_reverse
84reverse a Routing header
85.It Fn inet6_rthdr_segments
86return #segments in a Routing header
87.It Fn inet6_rthdr_getaddr
88fetch one address from a Routing header
89.It Fn inet6_rthdr_getflags
90fetch one flag from a Routing header
91.El
92.Pp
93The function prototypes for these functions are all in the
94.Aq Pa netinet/in.h
95header.
96.\"
97.Ss inet6_rthdr_space
98This function returns the number of bytes required to hold a Routing
99header of the specified
100.Fa type
101containing the specified number of
102.Fa segments
103.Pq addresses .
104For an IPv6 Type 0 Routing header, the number
105of segments must be between 1 and 23, inclusive.
106The return value
107includes the size of the cmsghdr structure that precedes the Routing
108header, and any required padding.
109.Pp
110If the return value is 0, then either the type of the Routing header
111is not supported by this implementation or the number of segments is
112invalid for this type of Routing header.
113.Pp
114Note: This function returns the size but does not allocate the space
115required for the ancillary data.
116This allows an application to
117allocate a larger buffer, if other ancillary data objects are
118desired, since all the ancillary data objects must be specified to
119.Xr sendmsg 2
120as a single
121.Li msg_control
122buffer.
123.\"
124.Ss inet6_rthdr_init
125This function initializes the buffer pointed to by
126.Fa bp
127to contain a
128.Li cmsghdr
129structure followed by a Routing header of the specified
130.Fa type .
131The
132.Li cmsg_len
133member of the
134.Li cmsghdr
135structure is initialized to the
136size of the structure plus the amount of space required by the
137Routing header.
138The
139.Li cmsg_level
140and
141.Li cmsg_type
142members are also initialized as required.
143.Pp
144The caller must allocate the buffer and its size can be determined by
145calling
146.Fn inet6_rthdr_space .
147.Pp
148Upon success the return value is the pointer to the
149.Li cmsghdr
150structure, and this is then used as the first argument to the next
151two functions.
152Upon an error the return value is
153.Dv NULL .
154.\"
155.Ss inet6_rthdr_add
156This function adds the address pointed to by
157.Fa addr
158to the end of the
159Routing header being constructed and sets the type of this hop to the
160value of
161.Fa flags .
162For an IPv6 Type 0 Routing header,
163.Fa flags
164must be
165either
166.Dv IPV6_RTHDR_LOOSE
167or
168.Dv IPV6_RTHDR_STRICT .
169.Pp
170If successful, the
171.Li cmsg_len
172member of the
173.Li cmsghdr
174structure is
175updated to account for the new address in the Routing header and the
176return value of the function is 0.
177Upon an error the return value of
178the function is -1.
179.\"
180.Ss inet6_rthdr_lasthop
181This function specifies the Strict/Loose flag for the final hop of a
182Routing header.
183For an IPv6 Type 0 Routing header,
184.Fa flags
185must be either
186.Dv IPV6_RTHDR_LOOSE
187or
188.Dv IPV6_RTHDR_STRICT .
189.Pp
190The return value of the function is 0 upon success, or -1 upon an error.
191.Pp
192Notice that a Routing header specifying
193.Li N
194intermediate nodes requires
195.Li N+1
196Strict/Loose flags.
197This requires
198.Li N
199calls to
200.Fn inet6_rthdr_add
201followed by one call to
202.Fn inet6_rthdr_lasthop .
203.\"
204.Ss inet6_rthdr_reverse
205This function takes a Routing header that was received as ancillary
206data
207.Po
208pointed to by the first argument,
209.Fa in
210.Pc
211and writes a new Routing
212header that sends datagrams along the reverse of that route.
213Both
214arguments are allowed to point to the same buffer
215.Pq that is, the reversal can occur in place .
216.Pp
217The return value of the function is 0 on success, or -1 upon an
218error.
219.\"
220.Ss inet6_rthdr_segments
221This function returns the number of segments
222.Pq addresses
223contained in
224the Routing header described by
225.Fa cmsg .
226On success the return value is
227between 1 and 23, inclusive.
228The return value of the function is -1 upon an error.
229.\"
230.Ss inet6_rthdr_getaddr
231This function returns a pointer to the IPv6 address specified by
232.Fa index
233(which must have a value between 1 and the value returned by
234.Fn inet6_rthdr_segments )
235in the Routing header described by
236.Fa cmsg .
237An
238application should first call
239.Fn inet6_rthdr_segments
240to obtain the number of segments in the Routing header.
241.Pp
242Upon an error the return value of the function is
243.Dv NULL .
244.\"
245.Ss inet6_rthdr_getflags
246This function returns the flags value specified by
247.Fa index
248(which must
249have a value between 0 and the value returned by
250.Fn inet6_rthdr_segments )
251in the Routing header described by
252.Fa cmsg .
253For an IPv6 Type 0 Routing header the return value will be either
254.Dv IPV6_RTHDR_LOOSE
255or
256.Dv IPV6_RTHDR_STRICT .
257.Pp
258Upon an error the return value of the function is -1.
259.Pp
260Note: Addresses are indexed starting at 1, and flags starting at 0,
261to maintain consistency with the terminology and figures in RFC 2460.
262.\"
263.Sh EXAMPLES
264RFC 2292 gives comprehensive examples in chapter 8.
265.\"
266.Sh DIAGNOSTICS
267.Fn inet6_rthdr_space
268returns 0 on errors.
269.Pp
270.Fn inet6_rthdr_add ,
271.Fn inet6_rthdr_lasthop
272and
273.Fn inet6_rthdr_reverse
274return 0 on success, and returns -1 on error.
275.Pp
276.Fn inet6_rthdr_init
277and
278.Fn inet6_rthdr_getaddr
279return
280.Dv NULL
281on error.
282.Pp
283.Fn inet6_rthdr_segments
284and
285.Fn inet6_rthdr_getflags
286return -1 on error.
287.\"
288.Sh SEE ALSO
289.Rs
290.%A W. Stevens
291.%A M. Thomas
292.%T "Advanced Sockets API for IPv6"
293.%N RFC 2292
294.%D February 1998
295.Re
296.Rs
297.%A S. Deering
298.%A R. Hinden
299.%T "Internet Protocol, Version 6 (IPv6) Specification"
300.%N RFC 2460
301.%D December 1998
302.Re
303.\"
304.Sh STANDARDS
305The functions
306are documented in
307.Dq Advanced Sockets API for IPv6
308.Pq RFC 2292 .
309.\"
310.Sh HISTORY
311The implementation first appeared in KAME advanced networking kit.
312.\"
313.Sh BUGS
314The text was shamelessly copied from RFC 2292.
315.Pp
316.Fn inet6_rthdr_reverse
317is not implemented yet.
diff --git a/src/lib/libc/net/inet_addr.c b/src/lib/libc/net/inet_addr.c
index b5b9d8302f..716dcb6f80 100644
--- a/src/lib/libc/net/inet_addr.c
+++ b/src/lib/libc/net/inet_addr.c
@@ -1,9 +1,11 @@
1/* $NetBSD: inet_addr.c,v 1.5 1995/02/25 06:20:41 cgd Exp $ */ 1/* $OpenBSD: inet_addr.c,v 1.7 2003/06/02 20:18:35 millert Exp $ */
2 2
3/* 3/*
4 * ++Copyright++ 1983, 1990, 1993
5 * -
4 * Copyright (c) 1983, 1990, 1993 6 * Copyright (c) 1983, 1990, 1993
5 * The Regents of the University of California. All rights reserved. 7 * The Regents of the University of California. All rights reserved.
6 * 8 *
7 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
9 * are met: 11 * are met:
@@ -12,14 +14,10 @@
12 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 15 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 16 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 17 * 3. Neither the name of the University nor the names of its contributors
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 18 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission. 19 * without specific prior written permission.
22 * 20 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -31,16 +29,38 @@
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * 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 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE. 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--
34 */ 52 */
35 53
36#if defined(LIBC_SCCS) && !defined(lint) 54#if defined(LIBC_SCCS) && !defined(lint)
37#if 0 55#if 0
38static char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93"; 56static char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93";
57static char rcsid[] = "$From: inet_addr.c,v 8.5 1996/08/05 08:31:35 vixie Exp $";
39#else 58#else
40static char rcsid[] = "$NetBSD: inet_addr.c,v 1.5 1995/02/25 06:20:41 cgd Exp $"; 59static char rcsid[] = "$OpenBSD: inet_addr.c,v 1.7 2003/06/02 20:18:35 millert Exp $";
41#endif 60#endif
42#endif /* LIBC_SCCS and not lint */ 61#endif /* LIBC_SCCS and not lint */
43 62
63#include <sys/types.h>
44#include <sys/param.h> 64#include <sys/param.h>
45#include <netinet/in.h> 65#include <netinet/in.h>
46#include <arpa/inet.h> 66#include <arpa/inet.h>
@@ -50,7 +70,7 @@ static char rcsid[] = "$NetBSD: inet_addr.c,v 1.5 1995/02/25 06:20:41 cgd Exp $"
50 * Ascii internet address interpretation routine. 70 * Ascii internet address interpretation routine.
51 * The value returned is in network order. 71 * The value returned is in network order.
52 */ 72 */
53u_long 73in_addr_t
54inet_addr(cp) 74inet_addr(cp)
55 register const char *cp; 75 register const char *cp;
56{ 76{
@@ -73,56 +93,58 @@ inet_aton(cp, addr)
73 register const char *cp; 93 register const char *cp;
74 struct in_addr *addr; 94 struct in_addr *addr;
75{ 95{
76 register u_long val; 96 register in_addr_t val;
77 register int base, n; 97 register int base, n;
78 register char c; 98 register char c;
79 u_int parts[4]; 99 u_int parts[4];
80 register u_int *pp = parts; 100 register u_int *pp = parts;
81 101
102 c = *cp;
82 for (;;) { 103 for (;;) {
83 /* 104 /*
84 * Collect number up to ``.''. 105 * Collect number up to ``.''.
85 * Values are specified as for C: 106 * Values are specified as for C:
86 * 0x=hex, 0=octal, other=decimal. 107 * 0x=hex, 0=octal, isdigit=decimal.
87 */ 108 */
109 if (!isdigit(c))
110 return (0);
88 val = 0; base = 10; 111 val = 0; base = 10;
89 if (*cp == '0') { 112 if (c == '0') {
90 if (*++cp == 'x' || *cp == 'X') 113 c = *++cp;
91 base = 16, cp++; 114 if (c == 'x' || c == 'X')
115 base = 16, c = *++cp;
92 else 116 else
93 base = 8; 117 base = 8;
94 } 118 }
95 while ((c = *cp) != '\0') { 119 for (;;) {
96 if (isascii(c) && isdigit(c)) { 120 if (isascii(c) && isdigit(c)) {
97 val = (val * base) + (c - '0'); 121 val = (val * base) + (c - '0');
98 cp++; 122 c = *++cp;
99 continue; 123 } else if (base == 16 && isascii(c) && isxdigit(c)) {
100 } 124 val = (val << 4) |
101 if (base == 16 && isascii(c) && isxdigit(c)) {
102 val = (val << 4) +
103 (c + 10 - (islower(c) ? 'a' : 'A')); 125 (c + 10 - (islower(c) ? 'a' : 'A'));
104 cp++; 126 c = *++cp;
105 continue; 127 } else
106 } 128 break;
107 break;
108 } 129 }
109 if (*cp == '.') { 130 if (c == '.') {
110 /* 131 /*
111 * Internet format: 132 * Internet format:
112 * a.b.c.d 133 * a.b.c.d
113 * a.b.c (with c treated as 16-bits) 134 * a.b.c (with c treated as 16 bits)
114 * a.b (with b treated as 24 bits) 135 * a.b (with b treated as 24 bits)
115 */ 136 */
116 if (pp >= parts + 3 || val > 0xff) 137 if (pp >= parts + 3)
117 return (0); 138 return (0);
118 *pp++ = val, cp++; 139 *pp++ = val;
140 c = *++cp;
119 } else 141 } else
120 break; 142 break;
121 } 143 }
122 /* 144 /*
123 * Check for trailing characters. 145 * Check for trailing characters.
124 */ 146 */
125 if (*cp && (!isascii(*cp) || !isspace(*cp))) 147 if (c != '\0' && (!isascii(c) || !isspace(c)))
126 return (0); 148 return (0);
127 /* 149 /*
128 * Concoct the address according to 150 * Concoct the address according to
@@ -131,23 +153,26 @@ inet_aton(cp, addr)
131 n = pp - parts + 1; 153 n = pp - parts + 1;
132 switch (n) { 154 switch (n) {
133 155
156 case 0:
157 return (0); /* initial nondigit */
158
134 case 1: /* a -- 32 bits */ 159 case 1: /* a -- 32 bits */
135 break; 160 break;
136 161
137 case 2: /* a.b -- 8.24 bits */ 162 case 2: /* a.b -- 8.24 bits */
138 if (val > 0xffffff) 163 if ((val > 0xffffff) || (parts[0] > 0xff))
139 return (0); 164 return (0);
140 val |= parts[0] << 24; 165 val |= parts[0] << 24;
141 break; 166 break;
142 167
143 case 3: /* a.b.c -- 8.8.16 bits */ 168 case 3: /* a.b.c -- 8.8.16 bits */
144 if (val > 0xffff) 169 if ((val > 0xffff) || (parts[0] > 0xff) || (parts[1] > 0xff))
145 return (0); 170 return (0);
146 val |= (parts[0] << 24) | (parts[1] << 16); 171 val |= (parts[0] << 24) | (parts[1] << 16);
147 break; 172 break;
148 173
149 case 4: /* a.b.c.d -- 8.8.8.8 bits */ 174 case 4: /* a.b.c.d -- 8.8.8.8 bits */
150 if (val > 0xff) 175 if ((val > 0xff) || (parts[0] > 0xff) || (parts[1] > 0xff) || (parts[2] > 0xff))
151 return (0); 176 return (0);
152 val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); 177 val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
153 break; 178 break;
diff --git a/src/lib/libc/net/inet_lnaof.c b/src/lib/libc/net/inet_lnaof.c
index ce1257bf68..c1e9780cda 100644
--- a/src/lib/libc/net/inet_lnaof.c
+++ b/src/lib/libc/net/inet_lnaof.c
@@ -1,5 +1,3 @@
1/* $NetBSD: inet_lnaof.c,v 1.4 1995/02/25 06:20:42 cgd Exp $ */
2
3/* 1/*
4 * Copyright (c) 1983, 1993 2 * Copyright (c) 1983, 1993
5 * The Regents of the University of California. All rights reserved. 3 * The Regents of the University of California. All rights reserved.
@@ -12,11 +10,7 @@
12 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission. 15 * without specific prior written permission.
22 * 16 *
@@ -34,11 +28,7 @@
34 */ 28 */
35 29
36#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
37#if 0 31static char rcsid[] = "$OpenBSD: inet_lnaof.c,v 1.4 2003/06/02 20:18:35 millert Exp $";
38static char sccsid[] = "@(#)inet_lnaof.c 8.1 (Berkeley) 6/4/93";
39#else
40static char rcsid[] = "$NetBSD: inet_lnaof.c,v 1.4 1995/02/25 06:20:42 cgd Exp $";
41#endif
42#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
43 33
44#include <sys/param.h> 34#include <sys/param.h>
@@ -50,11 +40,11 @@ static char rcsid[] = "$NetBSD: inet_lnaof.c,v 1.4 1995/02/25 06:20:42 cgd Exp $
50 * internet address; handles class a/b/c network 40 * internet address; handles class a/b/c network
51 * number formats. 41 * number formats.
52 */ 42 */
53u_long 43in_addr_t
54inet_lnaof(in) 44inet_lnaof(in)
55 struct in_addr in; 45 struct in_addr in;
56{ 46{
57 register u_long i = ntohl(in.s_addr); 47 register in_addr_t i = ntohl(in.s_addr);
58 48
59 if (IN_CLASSA(i)) 49 if (IN_CLASSA(i))
60 return ((i)&IN_CLASSA_HOST); 50 return ((i)&IN_CLASSA_HOST);
diff --git a/src/lib/libc/net/inet_makeaddr.c b/src/lib/libc/net/inet_makeaddr.c
index 84d366e03a..a6b59707fa 100644
--- a/src/lib/libc/net/inet_makeaddr.c
+++ b/src/lib/libc/net/inet_makeaddr.c
@@ -1,5 +1,3 @@
1/* $NetBSD: inet_makeaddr.c,v 1.4 1995/02/25 06:20:42 cgd Exp $ */
2
3/* 1/*
4 * Copyright (c) 1983, 1993 2 * Copyright (c) 1983, 1993
5 * The Regents of the University of California. All rights reserved. 3 * The Regents of the University of California. All rights reserved.
@@ -12,11 +10,7 @@
12 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission. 15 * without specific prior written permission.
22 * 16 *
@@ -34,11 +28,7 @@
34 */ 28 */
35 29
36#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
37#if 0 31static char rcsid[] = "$OpenBSD: inet_makeaddr.c,v 1.4 2003/06/02 20:18:35 millert Exp $";
38static char sccsid[] = "@(#)inet_makeaddr.c 8.1 (Berkeley) 6/4/93";
39#else
40static char rcsid[] = "$NetBSD: inet_makeaddr.c,v 1.4 1995/02/25 06:20:42 cgd Exp $";
41#endif
42#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
43 33
44#include <sys/param.h> 34#include <sys/param.h>
@@ -51,9 +41,9 @@ static char rcsid[] = "$NetBSD: inet_makeaddr.c,v 1.4 1995/02/25 06:20:42 cgd Ex
51 */ 41 */
52struct in_addr 42struct in_addr
53inet_makeaddr(net, host) 43inet_makeaddr(net, host)
54 u_long net, host; 44 in_addr_t net, host;
55{ 45{
56 u_long addr; 46 in_addr_t addr;
57 47
58 if (net < 128) 48 if (net < 128)
59 addr = (net << IN_CLASSA_NSHIFT) | (host & IN_CLASSA_HOST); 49 addr = (net << IN_CLASSA_NSHIFT) | (host & IN_CLASSA_HOST);
diff --git a/src/lib/libc/net/inet_net.3 b/src/lib/libc/net/inet_net.3
new file mode 100644
index 0000000000..c14fa52e38
--- /dev/null
+++ b/src/lib/libc/net/inet_net.3
@@ -0,0 +1,181 @@
1.\" $OpenBSD: inet_net.3,v 1.10 2003/05/01 19:17:37 jmc 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
85Caution:
86The
87.Fa dst
88field should be zeroed before calling
89.Fn inet_net_pton
90as the function will only fill the number of bytes necessary to
91encode the network number in network byte order.
92.Pp
93The only value for
94.Fa af
95currently supported is
96.Dv AF_INET .
97.Fa size
98is the size of the result buffer
99.Fa dst .
100.Sh NETWORK NUMBERS (IP VERSION 4)
101The external representation of Internet network numbers may be specified in
102one of the following forms:
103.Bd -literal -offset indent
104a
105a.b
106a.b.c
107a.b.c.d
108.Ed
109.Pp
110Any of the above four forms may have
111.Dq Li /bits
112appended where
113.Dq Li bits
114is in the range
115.Li 0-32
116and is used to explicitly specify the number of bits in the network address.
117When
118.Dq Li /bits
119is not specified the number of bits in the network address is calculated
120as the larger of the number of bits in the class to which the address
121belongs and the number of bits provided rounded up modulo 8.
122Examples:
123.Bl -tag -width 10.1.2.3/24
124.It Li 10
125an 8 bit network number (class A), value
126.Li 10.0.0.0 .
127.It Li 192
128a 24 bit network number (class C), value
129.Li 192.0.0.0 .
130.It Li 10.10
131a 16 bit network number, value
132.Li 10.10.0.0 .
133.It Li 10.1.2
134a 24 bit network number, value
135.Li 10.1.2.0 .
136.It Li 10.1.2.3
137a 32 bit network number, value
138.Li 10.1.2.3 .
139.It Li 10.1.2.3/24
140a 24 bit network number (explicit), value
141.Li 10.1.2.3 .
142.El
143.Pp
144Note that when the number of bits is specified using
145.Dq Li /bits
146notation, the value of the address still includes all bits suplied
147in the external representation, even those bits which are the host
148part of an internet address.
149Also, unlike
150.Xr inet_pton 3
151where the external representation is assumed to be an internet address, the
152external representation for
153.Fn inet_net_pton
154is assumed to be a network address.
155Thus
156.Dq Li 10.1
157is assumed to be
158.Dq Li 10.1.0.0
159not
160.Dq Li 10.0.0.1
161.Pp
162All numbers supplied as
163.Dq parts
164in a
165.Ql \&.
166notation
167may be decimal, octal, or hexadecimal, as specified
168in the C language (i.e., a leading 0x or 0X implies
169hexadecimal; otherwise, a leading 0 implies octal;
170otherwise, the number is interpreted as decimal).
171.Sh SEE ALSO
172.Xr byteorder 3 ,
173.Xr inet 3 ,
174.Xr inet_pton 3 ,
175.Xr networks 5
176.Sh HISTORY
177The
178.Nm inet_net_ntop
179and
180.Nm inet_net_pton
181functions 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..3c72efac6b
--- /dev/null
+++ b/src/lib/libc/net/inet_net_pton.c
@@ -0,0 +1,206 @@
1/* $OpenBSD: inet_net_pton.c,v 1.3 2003/04/25 19:40:25 henning 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.3 2003/04/25 19:40:25 henning 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 < ((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
index 02f52ca318..58be2d05cd 100644
--- a/src/lib/libc/net/inet_netof.c
+++ b/src/lib/libc/net/inet_netof.c
@@ -1,5 +1,3 @@
1/* $NetBSD: inet_netof.c,v 1.4 1995/02/25 06:20:43 cgd Exp $ */
2
3/* 1/*
4 * Copyright (c) 1983, 1993 2 * Copyright (c) 1983, 1993
5 * The Regents of the University of California. All rights reserved. 3 * The Regents of the University of California. All rights reserved.
@@ -12,11 +10,7 @@
12 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission. 15 * without specific prior written permission.
22 * 16 *
@@ -34,11 +28,7 @@
34 */ 28 */
35 29
36#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
37#if 0 31static char rcsid[] = "$OpenBSD: inet_netof.c,v 1.4 2003/06/02 20:18:35 millert Exp $";
38static char sccsid[] = "@(#)inet_netof.c 8.1 (Berkeley) 6/4/93";
39#else
40static char rcsid[] = "$NetBSD: inet_netof.c,v 1.4 1995/02/25 06:20:43 cgd Exp $";
41#endif
42#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
43 33
44#include <sys/param.h> 34#include <sys/param.h>
@@ -49,11 +39,11 @@ static char rcsid[] = "$NetBSD: inet_netof.c,v 1.4 1995/02/25 06:20:43 cgd Exp $
49 * Return the network number from an internet 39 * Return the network number from an internet
50 * address; handles class a/b/c network #'s. 40 * address; handles class a/b/c network #'s.
51 */ 41 */
52u_long 42in_addr_t
53inet_netof(in) 43inet_netof(in)
54 struct in_addr in; 44 struct in_addr in;
55{ 45{
56 register u_long i = ntohl(in.s_addr); 46 register in_addr_t i = ntohl(in.s_addr);
57 47
58 if (IN_CLASSA(i)) 48 if (IN_CLASSA(i))
59 return (((i)&IN_CLASSA_NET) >> IN_CLASSA_NSHIFT); 49 return (((i)&IN_CLASSA_NET) >> IN_CLASSA_NSHIFT);
diff --git a/src/lib/libc/net/inet_network.c b/src/lib/libc/net/inet_network.c
index 35105fa75a..5e36f78069 100644
--- a/src/lib/libc/net/inet_network.c
+++ b/src/lib/libc/net/inet_network.c
@@ -1,5 +1,3 @@
1/* $NetBSD: inet_network.c,v 1.4 1995/02/25 06:20:45 cgd Exp $ */
2
3/* 1/*
4 * Copyright (c) 1983, 1993 2 * Copyright (c) 1983, 1993
5 * The Regents of the University of California. All rights reserved. 3 * The Regents of the University of California. All rights reserved.
@@ -12,11 +10,7 @@
12 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission. 15 * without specific prior written permission.
22 * 16 *
@@ -34,11 +28,7 @@
34 */ 28 */
35 29
36#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
37#if 0 31static char rcsid[] = "$OpenBSD: inet_network.c,v 1.8 2003/06/02 20:18:35 millert Exp $";
38static char sccsid[] = "@(#)inet_network.c 8.1 (Berkeley) 6/4/93";
39#else
40static char rcsid[] = "$NetBSD: inet_network.c,v 1.4 1995/02/25 06:20:45 cgd Exp $";
41#endif
42#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
43 33
44#include <sys/types.h> 34#include <sys/types.h>
@@ -51,13 +41,13 @@ static char rcsid[] = "$NetBSD: inet_network.c,v 1.4 1995/02/25 06:20:45 cgd Exp
51 * The library routines call this routine to interpret 41 * The library routines call this routine to interpret
52 * network numbers. 42 * network numbers.
53 */ 43 */
54u_long 44in_addr_t
55inet_network(cp) 45inet_network(cp)
56 register const char *cp; 46 register const char *cp;
57{ 47{
58 register u_long val, base, n; 48 register in_addr_t val, base, n;
59 register char c; 49 register char c;
60 u_long parts[4], *pp = parts; 50 in_addr_t parts[4], *pp = parts;
61 register int i; 51 register int i;
62 52
63again: 53again:
@@ -66,7 +56,7 @@ again:
66 base = 8, cp++; 56 base = 8, cp++;
67 if (*cp == 'x' || *cp == 'X') 57 if (*cp == 'x' || *cp == 'X')
68 base = 16, cp++; 58 base = 16, cp++;
69 while (c = *cp) { 59 while ((c = *cp)) {
70 if (isdigit(c)) { 60 if (isdigit(c)) {
71 val = (val * base) + (c - '0'); 61 val = (val * base) + (c - '0');
72 cp++; 62 cp++;
@@ -80,7 +70,7 @@ again:
80 break; 70 break;
81 } 71 }
82 if (*cp == '.') { 72 if (*cp == '.') {
83 if (pp >= parts + 4) 73 if (pp >= parts + 3)
84 return (INADDR_NONE); 74 return (INADDR_NONE);
85 *pp++ = val, cp++; 75 *pp++ = val, cp++;
86 goto again; 76 goto again;
@@ -89,11 +79,10 @@ again:
89 return (INADDR_NONE); 79 return (INADDR_NONE);
90 *pp++ = val; 80 *pp++ = val;
91 n = pp - parts; 81 n = pp - parts;
92 if (n > 4) 82 for (val = 0, i = 0; i < 4; i++) {
93 return (INADDR_NONE);
94 for (val = 0, i = 0; i < n; i++) {
95 val <<= 8; 83 val <<= 8;
96 val |= parts[i] & 0xff; 84 if (i < n)
85 val |= parts[i] & 0xff;
97 } 86 }
98 return (val); 87 return (val);
99} 88}
diff --git a/src/lib/libc/net/inet_ntoa.c b/src/lib/libc/net/inet_ntoa.c
index 2da0ab00ff..bd3fd98b09 100644
--- a/src/lib/libc/net/inet_ntoa.c
+++ b/src/lib/libc/net/inet_ntoa.c
@@ -1,5 +1,3 @@
1/* $NetBSD: inet_ntoa.c,v 1.4 1995/02/25 06:20:46 cgd Exp $ */
2
3/* 1/*
4 * Copyright (c) 1983, 1993 2 * Copyright (c) 1983, 1993
5 * The Regents of the University of California. All rights reserved. 3 * The Regents of the University of California. All rights reserved.
@@ -12,11 +10,7 @@
12 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission. 15 * without specific prior written permission.
22 * 16 *
@@ -34,11 +28,7 @@
34 */ 28 */
35 29
36#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
37#if 0 31static char rcsid[] = "$OpenBSD: inet_ntoa.c,v 1.4 2003/06/02 20:18:35 millert Exp $";
38static char sccsid[] = "@(#)inet_ntoa.c 8.1 (Berkeley) 6/4/93";
39#else
40static char rcsid[] = "$NetBSD: inet_ntoa.c,v 1.4 1995/02/25 06:20:46 cgd Exp $";
41#endif
42#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
43 33
44/* 34/*
@@ -60,6 +50,6 @@ inet_ntoa(in)
60 p = (char *)&in; 50 p = (char *)&in;
61#define UC(b) (((int)b)&0xff) 51#define UC(b) (((int)b)&0xff)
62 (void)snprintf(b, sizeof(b), 52 (void)snprintf(b, sizeof(b),
63 "%d.%d.%d.%d", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3])); 53 "%u.%u.%u.%u", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3]));
64 return (b); 54 return (b);
65} 55}
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..64f6028db0
--- /dev/null
+++ b/src/lib/libc/net/ipx.3
@@ -0,0 +1,123 @@
1.\" $OpenBSD: ipx.3,v 1.10 2003/06/02 20:18:35 millert 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. Neither the name of the University nor the names of its contributors
15.\" may be used to endorse or promote products derived from this software
16.\" without specific prior written permission.
17.\"
18.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28.\" SUCH DAMAGE.
29.\"
30.Dd June 4, 1993
31.Dt IPX 3
32.Os
33.Sh NAME
34.Nm ipx_addr ,
35.Nm ipx_ntoa
36.Nd IPX address conversion routines
37.Sh SYNOPSIS
38.Fd #include <sys/types.h>
39.Fd #include <netipx/ipx.h>
40.Ft struct ipx_addr
41.Fn ipx_addr "const char *cp"
42.Ft char *
43.Fn ipx_ntoa "struct ipx_addr ipx"
44.Sh DESCRIPTION
45The routine
46.Fn ipx_addr
47interprets character strings representing
48.Tn IPX
49addresses, returning binary information suitable
50for use in system calls.
51The routine
52.Fn ipx_ntoa
53takes
54.Tn IPX
55addresses and returns
56.Tn ASCII
57strings representing the address in a
58notation in common use:
59.Bd -filled -offset indent
60<network number>.<host number>.<port number>
61.Ed
62.Pp
63Trailing zero fields are suppressed, and each number is printed in hexadecimal,
64in a format suitable for input to
65.Fn ipx_addr .
66Any fields lacking super-decimal digits will have a
67trailing
68.Sq H
69appended.
70.Pp
71An effort has been made to ensure that
72.Fn ipx_addr
73be compatible with most formats in common use.
74It will first separate an address into 1 to 3 fields using a single delimiter
75chosen from
76period
77.Pq Ql \&. ,
78colon
79.Pq Ql \&: ,
80or pound-sign
81.Pq Ql # .
82Each field is then examined for byte separators (colon or period).
83If there are byte separators, each subfield separated is taken to be
84a small hexadecimal number, and the entirety is taken as a network-byte-ordered
85quantity to be zero extended in the high-network-order bytes.
86Next, the field is inspected for hyphens, in which case
87the field is assumed to be a number in decimal notation
88with hyphens separating the millenia.
89Next, the field is assumed to be a number:
90It is interpreted
91as hexadecimal if there is a leading
92.Ql 0x
93(as in C),
94a trailing
95.Sq H
96(as in Mesa), or there are any super-decimal digits present.
97It is interpreted as octal if there is a leading
98.Ql 0
99and there are no super-octal digits.
100Otherwise, it is converted as a decimal number.
101.Sh RETURN VALUES
102None.
103(See
104.Sx BUGS . )
105.Sh SEE ALSO
106.Xr ns 4 ,
107.Xr hosts 5 ,
108.Xr networks 5
109.Sh HISTORY
110The precursor
111.Fn ns_addr
112and
113.Fn ns_ntoa
114functions appeared in
115.Bx 4.3 .
116.Sh BUGS
117The string returned by
118.Fn ipx_ntoa
119resides in a static memory area.
120The function
121.Fn ipx_addr
122should diagnose improperly formed input, and there should be an unambiguous
123way 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..371ac7c917
--- /dev/null
+++ b/src/lib/libc/net/ipx_addr.c
@@ -0,0 +1,224 @@
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. 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 * from @(#)ipx_addr.c
33 */
34
35#if defined(LIBC_SCCS) && !defined(lint)
36static char rcsid[] = "$OpenBSD: ipx_addr.c,v 1.6 2003/06/02 20:18:35 millert Exp $";
37#endif /* LIBC_SCCS and not lint */
38
39#include <sys/param.h>
40#include <netipx/ipx.h>
41#include <stdio.h>
42#include <string.h>
43
44static struct ipx_addr addr, zero_addr;
45
46static void Field(), cvtbase();
47
48struct ipx_addr
49ipx_addr(name)
50 const char *name;
51{
52 char separator;
53 char *hostname, *socketname, *cp;
54 char buf[50];
55
56 strlcpy(buf, name, sizeof(buf));
57
58 /*
59 * First, figure out what he intends as a field separtor.
60 * Despite the way this routine is written, the prefered
61 * form 2-272.AA001234H.01777, i.e. XDE standard.
62 * Great efforts are made to insure backward compatibility.
63 */
64 if ((hostname = strchr(buf, '#')))
65 separator = '#';
66 else {
67 hostname = strchr(buf, '.');
68 if ((cp = strchr(buf, ':')) &&
69 ((hostname && cp < hostname) || (hostname == 0))) {
70 hostname = cp;
71 separator = ':';
72 } else
73 separator = '.';
74 }
75 if (hostname)
76 *hostname++ = 0;
77
78 addr = zero_addr;
79 Field(buf, addr.ipx_net.c_net, 4);
80 if (hostname == 0)
81 return (addr); /* No separator means net only */
82
83 socketname = strchr(hostname, separator);
84 if (socketname) {
85 *socketname++ = 0;
86 Field(socketname, (u_char *)&addr.ipx_port, 2);
87 }
88
89 Field(hostname, addr.ipx_host.c_host, 6);
90
91 return (addr);
92}
93
94static void
95Field(buf, out, len)
96 char *buf;
97 u_char *out;
98 int len;
99{
100 register char *bp = buf;
101 int i, ibase, base16 = 0, base10 = 0, clen = 0;
102 int hb[6], *hp;
103 char *fmt;
104
105 /*
106 * first try 2-273#2-852-151-014#socket
107 */
108 if ((*buf != '-') &&
109 (1 < (i = sscanf(buf, "%d-%d-%d-%d-%d",
110 &hb[0], &hb[1], &hb[2], &hb[3], &hb[4])))) {
111 cvtbase(1000L, 256, hb, i, out, len);
112 return;
113 }
114 /*
115 * try form 8E1#0.0.AA.0.5E.E6#socket
116 */
117 if (1 < (i = sscanf(buf,"%x.%x.%x.%x.%x.%x",
118 &hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) {
119 cvtbase(256L, 256, hb, i, out, len);
120 return;
121 }
122 /*
123 * try form 8E1#0:0:AA:0:5E:E6#socket
124 */
125 if (1 < (i = sscanf(buf,"%x:%x:%x:%x:%x:%x",
126 &hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) {
127 cvtbase(256L, 256, hb, i, out, len);
128 return;
129 }
130 /*
131 * This is REALLY stretching it but there was a
132 * comma notation separting shorts -- definitely non standard
133 */
134 if (1 < (i = sscanf(buf,"%x,%x,%x",
135 &hb[0], &hb[1], &hb[2]))) {
136 hb[0] = htons(hb[0]); hb[1] = htons(hb[1]);
137 hb[2] = htons(hb[2]);
138 cvtbase(65536L, 256, hb, i, out, len);
139 return;
140 }
141
142 /* Need to decide if base 10, 16 or 8 */
143 while (*bp) switch (*bp++) {
144
145 case '0': case '1': case '2': case '3': case '4': case '5':
146 case '6': case '7': case '-':
147 break;
148
149 case '8': case '9':
150 base10 = 1;
151 break;
152
153 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
154 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
155 base16 = 1;
156 break;
157
158 case 'x': case 'X':
159 *--bp = '0';
160 base16 = 1;
161 break;
162
163 case 'h': case 'H':
164 base16 = 1;
165 /* fall into */
166
167 default:
168 *--bp = 0; /* Ends Loop */
169 }
170 if (base16) {
171 fmt = "%3x";
172 ibase = 4096;
173 } else if (base10 == 0 && *buf == '0') {
174 fmt = "%3o";
175 ibase = 512;
176 } else {
177 fmt = "%3d";
178 ibase = 1000;
179 }
180
181 for (bp = buf; *bp++; ) clen++;
182 if (clen == 0) clen++;
183 if (clen > 18) clen = 18;
184 i = ((clen - 1) / 3) + 1;
185 bp = clen + buf - 3;
186 hp = hb + i - 1;
187
188 while (hp > hb) {
189 (void)sscanf(bp, fmt, hp);
190 bp[0] = 0;
191 hp--;
192 bp -= 3;
193 }
194 (void)sscanf(buf, fmt, hp);
195 cvtbase((long)ibase, 256, hb, i, out, len);
196}
197
198static void
199cvtbase(oldbase,newbase,input,inlen,result,reslen)
200 long oldbase;
201 int newbase;
202 int input[];
203 int inlen;
204 unsigned char result[];
205 int reslen;
206{
207 int d, e;
208 long sum;
209
210 e = 1;
211 while (e > 0 && reslen > 0) {
212 d = 0; e = 0; sum = 0;
213 /* long division: input=input/newbase */
214 while (d < inlen) {
215 sum = sum*oldbase + (long) input[d];
216 e += (sum > 0);
217 input[d++] = sum / newbase;
218 sum %= newbase;
219 }
220 result[--reslen] = sum; /* accumulate remainder */
221 }
222 for (d=0; d < reslen; d++)
223 result[d] = 0;
224}
diff --git a/src/lib/libc/net/ipx_ntoa.c b/src/lib/libc/net/ipx_ntoa.c
new file mode 100644
index 0000000000..64ba146b31
--- /dev/null
+++ b/src/lib/libc/net/ipx_ntoa.c
@@ -0,0 +1,49 @@
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. Neither the name of the University nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#if defined(LIBC_SCCS) && !defined(lint)
31static char rcsid[] = "$OpenBSD: ipx_ntoa.c,v 1.5 2003/09/26 06:19:25 deraadt Exp $";
32#endif /* LIBC_SCCS and not lint */
33
34#include <sys/param.h>
35#include <netipx/ipx.h>
36#include <stdio.h>
37
38char *
39ipx_ntoa(struct ipx_addr addr)
40{
41 static char obuf[] = "xxxxxxxxH.xx:xx:xx:xx:xx:xx.uuuuu";
42
43 snprintf(obuf, sizeof obuf, "%8xH.%02x:%02x:%02x:%02x:%02x:%02x.%u",
44 ntohl(addr.ipx_net.l_net), addr.ipx_host.c_host[0],
45 addr.ipx_host.c_host[1], addr.ipx_host.c_host[2],
46 addr.ipx_host.c_host[3], addr.ipx_host.c_host[4],
47 addr.ipx_host.c_host[5], ntohs(addr.ipx_port));
48 return (obuf);
49}
diff --git a/src/lib/libc/net/iso_addr.3 b/src/lib/libc/net/iso_addr.3
index 95c136e5fc..896f769482 100644
--- a/src/lib/libc/net/iso_addr.3
+++ b/src/lib/libc/net/iso_addr.3
@@ -1,4 +1,4 @@
1.\" $NetBSD: iso_addr.3,v 1.2 1995/02/25 06:20:46 cgd Exp $ 1.\" $OpenBSD: iso_addr.3,v 1.5 2003/06/02 20:18:35 millert Exp $
2.\" 2.\"
3.\" Copyright (c) 1993 3.\" Copyright (c) 1993
4.\" The Regents of the University of California. All rights reserved. 4.\" The Regents of the University of California. All rights reserved.
@@ -11,11 +11,7 @@
11.\" 2. Redistributions in binary form must reproduce the above copyright 11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the 12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution. 13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software 14.\" 3. Neither the name of the University nor the names of its contributors
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 15.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission. 16.\" without specific prior written permission.
21.\" 17.\"
@@ -31,15 +27,13 @@
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE. 28.\" SUCH DAMAGE.
33.\" 29.\"
34.\" @(#)iso_addr.3 8.1 (Berkeley) 6/4/93
35.\"
36.Dd June 4, 1993 30.Dd June 4, 1993
37.Dt ISO_ADDR 3 31.Dt ISO_ADDR 3
38.Os 32.Os
39.Sh NAME 33.Sh NAME
40.Nm iso_addr , 34.Nm iso_addr ,
41.Nm iso_ntoa 35.Nm iso_ntoa
42.Nd "elementary network address conversion routines for Open System Interconnection 36.Nd "network address conversion routines for Open System Interconnection"
43.Sh SYNOPSIS 37.Sh SYNOPSIS
44.Fd #include <sys/types.h> 38.Fd #include <sys/types.h>
45.Fd #include <netiso/iso.h> 39.Fd #include <netiso/iso.h>
@@ -62,7 +56,7 @@ addresses and returns
62.Tn ASCII 56.Tn ASCII
63strings representing NSAPs (network service 57strings representing NSAPs (network service
64access points) in a 58access points) in a
65notation inverse to that accepted by 59notation inverse to that accepted by
66.Fn iso_addr . 60.Fn iso_addr .
67.Pp 61.Pp
68Unfortunately, no universal standard exists for representing 62Unfortunately, no universal standard exists for representing
@@ -90,7 +84,8 @@ to have its higher order bits filled with zeros.
90.Fn iso_ntoa 84.Fn iso_ntoa
91always returns a null terminated string. 85always returns a null terminated string.
92.Fn iso_addr 86.Fn iso_addr
93always returns a pointer to a struct iso_addr. 87always returns a pointer to a
88.Li struct iso_addr .
94(See 89(See
95.Sx BUGS . ) 90.Sx BUGS . )
96.Sh SEE ALSO 91.Sh SEE ALSO
@@ -100,7 +95,7 @@ The
100.Fn iso_addr 95.Fn iso_addr
101and 96and
102.Fn iso_ntoa 97.Fn iso_ntoa
103functions appeared in 98functions appeared in
104.Bx 4.3 Reno . 99.Bx 4.3 Reno .
105.Sh BUGS 100.Sh BUGS
106The returned values 101The returned values
diff --git a/src/lib/libc/net/iso_addr.c b/src/lib/libc/net/iso_addr.c
index c26ec1a64a..f0f8444325 100644
--- a/src/lib/libc/net/iso_addr.c
+++ b/src/lib/libc/net/iso_addr.c
@@ -1,5 +1,3 @@
1/* $NetBSD: iso_addr.c,v 1.4 1995/02/25 06:20:47 cgd Exp $ */
2
3/* 1/*
4 * Copyright (c) 1989, 1993 2 * Copyright (c) 1989, 1993
5 * The Regents of the University of California. All rights reserved. 3 * The Regents of the University of California. All rights reserved.
@@ -12,11 +10,7 @@
12 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission. 15 * without specific prior written permission.
22 * 16 *
@@ -34,11 +28,7 @@
34 */ 28 */
35 29
36#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
37#if 0 31static char rcsid[] = "$OpenBSD: iso_addr.c,v 1.3 2003/06/02 20:18:35 millert Exp $";
38static char sccsid[] = "@(#)iso_addr.c 8.1 (Berkeley) 6/4/93";
39#else
40static char rcsid[] = "$NetBSD: iso_addr.c,v 1.4 1995/02/25 06:20:47 cgd Exp $";
41#endif
42#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
43 33
44#include <sys/types.h> 34#include <sys/types.h>
diff --git a/src/lib/libc/net/linkaddr.3 b/src/lib/libc/net/link_addr.3
index 1a2af9b30d..929db4e1d6 100644
--- a/src/lib/libc/net/linkaddr.3
+++ b/src/lib/libc/net/link_addr.3
@@ -1,4 +1,4 @@
1.\" $NetBSD: linkaddr.3,v 1.2 1995/02/25 06:20:48 cgd Exp $ 1.\" $OpenBSD: link_addr.3,v 1.8 2003/06/02 20:18:35 millert Exp $
2.\" 2.\"
3.\" Copyright (c) 1993 3.\" Copyright (c) 1993
4.\" The Regents of the University of California. All rights reserved. 4.\" The Regents of the University of California. All rights reserved.
@@ -14,11 +14,7 @@
14.\" 2. Redistributions in binary form must reproduce the above copyright 14.\" 2. Redistributions in binary form must reproduce the above copyright
15.\" notice, this list of conditions and the following disclaimer in the 15.\" notice, this list of conditions and the following disclaimer in the
16.\" documentation and/or other materials provided with the distribution. 16.\" documentation and/or other materials provided with the distribution.
17.\" 3. All advertising materials mentioning features or use of this software 17.\" 3. Neither the name of the University nor the names of its contributors
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 18.\" may be used to endorse or promote products derived from this software
23.\" without specific prior written permission. 19.\" without specific prior written permission.
24.\" 20.\"
@@ -34,11 +30,9 @@
34.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35.\" SUCH DAMAGE. 31.\" SUCH DAMAGE.
36.\" 32.\"
37.\" @(#)linkaddr.3 8.1 (Berkeley) 7/28/93
38.\"
39.Dd July 28, 1993 33.Dd July 28, 1993
40.Dt LINK_ADDR 3 34.Dt LINK_ADDR 3
41.Os BSD 4.4 35.Os
42.Sh NAME 36.Sh NAME
43.Nm link_addr , 37.Nm link_addr ,
44.Nm link_ntoa 38.Nm link_ntoa
@@ -52,12 +46,11 @@
52.Ft char * 46.Ft char *
53.Fn link_ntoa "const struct sockaddr_dl *sdl" 47.Fn link_ntoa "const struct sockaddr_dl *sdl"
54.Sh DESCRIPTION 48.Sh DESCRIPTION
55The routine 49The
56.Fn link_addr 50.Fn link_addr
57interprets character strings representing 51function interprets character strings representing
58link-level addresses, returning binary information suitable 52link-level addresses, returning binary information suitable
59for use in system calls. 53for use in system calls.
60The routine
61.Fn link_ntoa 54.Fn link_ntoa
62takes 55takes
63a link-level 56a link-level
@@ -75,9 +68,9 @@ the string
75.Fa addr 68.Fa addr
76may contain 69may contain
77an optional network interface identifier of the form 70an optional network interface identifier of the form
78.Dq "name unit-number" , 71.Dq name unit-number ,
79suitable for the first argument to 72suitable for the first argument to
80.Xr ifconfig 4 , 73.Xr ifconfig 8 ,
81followed in all cases by a colon and 74followed in all cases by a colon and
82an interface address in the form of 75an interface address in the form of
83groups of hexadecimal digits 76groups of hexadecimal digits
@@ -93,24 +86,25 @@ low order bytes through high order bytes.
93.\" .Pp 86.\" .Pp
94Thus 87Thus
95.Li le0:8.0.9.13.d.30 88.Li le0:8.0.9.13.d.30
96represents an ethernet address 89represents an Ethernet address
97to be transmitted on the first Lance ethernet interface. 90to be transmitted on the first Lance Ethernet interface.
98.Sh RETURN VALUES 91.Sh RETURN VALUES
99.Fn link_ntoa 92.Fn link_ntoa
100always returns a null terminated string. 93always returns a null-terminated string.
101.Fn link_addr 94.Fn link_addr
102has no return value. 95has no return value.
103(See 96(See
104.Sx BUGS . ) 97.Sx BUGS . )
105.Sh SEE ALSO 98.Sh SEE ALSO
106.Xr iso 4 , 99.Xr iso 4 ,
100.Xr ifconfig 8
107.Sh HISTORY 101.Sh HISTORY
108The 102The
109.Fn link_addr 103.Fn link_addr
110and 104and
111.Fn link_ntoa 105.Fn link_ntoa
112functions appeared in 106functions appeared in
113.Bx 4.3 Reno . 107.Bx 4.3 Reno .
114.Sh BUGS 108.Sh BUGS
115The returned values for link_ntoa 109The returned values for link_ntoa
116reside in a static memory area. 110reside in a static memory area.
@@ -121,7 +115,7 @@ should diagnose improperly formed input, and there should be an unambiguous
121way to recognize this. 115way to recognize this.
122.Pp 116.Pp
123If the 117If the
124.Va sdl_len 118.Fa sdl_len
125field of the link socket address 119field of the link socket address
126.Fa sdl 120.Fa sdl
127is 0, 121is 0,
diff --git a/src/lib/libc/net/linkaddr.c b/src/lib/libc/net/linkaddr.c
index 19a0de3abd..ee45ff767d 100644
--- a/src/lib/libc/net/linkaddr.c
+++ b/src/lib/libc/net/linkaddr.c
@@ -1,5 +1,3 @@
1/* $NetBSD: linkaddr.c,v 1.5 1995/02/25 06:20:49 cgd Exp $ */
2
3/*- 1/*-
4 * Copyright (c) 1990, 1993 2 * Copyright (c) 1990, 1993
5 * The Regents of the University of California. All rights reserved. 3 * The Regents of the University of California. All rights reserved.
@@ -12,11 +10,7 @@
12 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission. 15 * without specific prior written permission.
22 * 16 *
@@ -34,11 +28,7 @@
34 */ 28 */
35 29
36#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
37#if 0 31static char rcsid[] = "$OpenBSD: linkaddr.c,v 1.3 2003/06/02 20:18:35 millert Exp $";
38static char sccsid[] = "@(#)linkaddr.c 8.1 (Berkeley) 6/4/93";
39#else
40static char rcsid[] = "$NetBSD: linkaddr.c,v 1.5 1995/02/25 06:20:49 cgd Exp $";
41#endif
42#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
43 33
44#include <sys/types.h> 34#include <sys/types.h>
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
index f89b4fe042..9c7aeab312 100644
--- a/src/lib/libc/net/ns.3
+++ b/src/lib/libc/net/ns.3
@@ -1,4 +1,4 @@
1.\" $NetBSD: ns.3,v 1.3 1995/02/25 06:20:50 cgd Exp $ 1.\" $OpenBSD: ns.3,v 1.9 2003/06/02 20:18:35 millert Exp $
2.\" 2.\"
3.\" Copyright (c) 1986, 1991, 1993 3.\" Copyright (c) 1986, 1991, 1993
4.\" The Regents of the University of California. All rights reserved. 4.\" The Regents of the University of California. All rights reserved.
@@ -11,11 +11,7 @@
11.\" 2. Redistributions in binary form must reproduce the above copyright 11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the 12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution. 13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software 14.\" 3. Neither the name of the University nor the names of its contributors
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 15.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission. 16.\" without specific prior written permission.
21.\" 17.\"
@@ -31,11 +27,9 @@
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE. 28.\" SUCH DAMAGE.
33.\" 29.\"
34.\" @(#)ns.3 8.1 (Berkeley) 6/4/93
35.\"
36.Dd June 4, 1993 30.Dd June 4, 1993
37.Dt NS 3 31.Dt NS 3
38.Os BSD 4.3 32.Os
39.Sh NAME 33.Sh NAME
40.Nm ns_addr , 34.Nm ns_addr ,
41.Nm ns_ntoa 35.Nm ns_ntoa
@@ -45,7 +39,7 @@ address conversion routines
45.Sh SYNOPSIS 39.Sh SYNOPSIS
46.Fd #include <sys/types.h> 40.Fd #include <sys/types.h>
47.Fd #include <netns/ns.h> 41.Fd #include <netns/ns.h>
48.Ft struct ns_addr 42.Ft struct ns_addr
49.Fn ns_addr "char *cp" 43.Fn ns_addr "char *cp"
50.Ft char * 44.Ft char *
51.Fn ns_ntoa "struct ns_addr ns" 45.Fn ns_ntoa "struct ns_addr ns"
@@ -69,27 +63,27 @@ notation in common use in the Xerox Development Environment:
69.Ed 63.Ed
70.Pp 64.Pp
71Trailing zero fields are suppressed, and each number is printed in hexadecimal, 65Trailing zero fields are suppressed, and each number is printed in hexadecimal,
72in a format suitable for input to 66in a format suitable for input to
73.Fn ns_addr . 67.Fn ns_addr .
74Any fields lacking super-decimal digits will have a 68Any fields lacking super-decimal digits will have a
75trailing 69trailing
76.Ql H 70.Sq H
77appended. 71appended.
78.Pp 72.Pp
79Unfortunately, no universal standard exists for representing 73Unfortunately, no universal standard exists for representing
80.Tn XNS 74.Tn XNS
81addresses. 75addresses.
82An effort has been made to insure that 76An effort has been made to ensure that
83.Fn ns_addr 77.Fn ns_addr
84be compatible with most formats in common use. 78be compatible with most formats in common use.
85It will first separate an address into 1 to 3 fields using a single delimiter 79It will first separate an address into 1 to 3 fields using a single delimiter
86chosen from 80chosen from
87period 81period
88.Ql \&. , 82.Pq Ql \&. ,
89colon 83colon
90.Ql \&: 84.Pq Ql \&: ,
91or pound-sign 85or pound-sign
92.Ql \&# . 86.Ql # .
93Each field is then examined for byte separators (colon or period). 87Each field is then examined for byte separators (colon or period).
94If there are byte separators, each subfield separated is taken to be 88If there are byte separators, each subfield separated is taken to be
95a small hexadecimal number, and the entirety is taken as a network-byte-ordered 89a small hexadecimal number, and the entirety is taken as a network-byte-ordered
@@ -103,24 +97,25 @@ as hexadecimal if there is a leading
103.Ql 0x 97.Ql 0x
104(as in C), 98(as in C),
105a trailing 99a trailing
106.Ql H 100.Sq H
107(as in Mesa), or there are any super-decimal digits present. 101(as in Mesa), or there are any super-decimal digits present.
108It is interpreted as octal is there is a leading 102It is interpreted as octal if there is a leading
109.Ql 0 103.Ql 0
110and there are no super-octal digits. 104and there are no super-octal digits.
111Otherwise, it is converted as a decimal number. 105Otherwise, it is converted as a decimal number.
112.Sh RETURN VALUES 106.Sh RETURN VALUES
113None. (See 107None.
108(See
114.Sx BUGS . ) 109.Sx BUGS . )
115.Sh SEE ALSO 110.Sh SEE ALSO
116.Xr hosts 5 , 111.Xr hosts 5 ,
117.Xr networks 5 , 112.Xr networks 5
118.Sh HISTORY 113.Sh HISTORY
119The 114The
120.Fn ns_addr 115.Fn ns_addr
121and 116and
122.Fn ns_toa 117.Fn ns_toa
123functions appeared in 118functions appeared in
124.Bx 4.3 . 119.Bx 4.3 .
125.Sh BUGS 120.Sh BUGS
126The string returned by 121The string returned by
diff --git a/src/lib/libc/net/ns_addr.c b/src/lib/libc/net/ns_addr.c
index f75ddb23b7..0f8feda55c 100644
--- a/src/lib/libc/net/ns_addr.c
+++ b/src/lib/libc/net/ns_addr.c
@@ -1,5 +1,3 @@
1/* $NetBSD: ns_addr.c,v 1.5 1995/02/25 06:20:51 cgd Exp $ */
2
3/* 1/*
4 * Copyright (c) 1986, 1993 2 * Copyright (c) 1986, 1993
5 * The Regents of the University of California. All rights reserved. 3 * The Regents of the University of California. All rights reserved.
@@ -15,11 +13,7 @@
15 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software 16 * 3. Neither the name of the University nor the names of its contributors
19 * must display the following acknowledgement:
20 * This product includes software developed by the University of
21 * California, Berkeley and its contributors.
22 * 4. Neither the name of the University nor the names of its contributors
23 * may be used to endorse or promote products derived from this software 17 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission. 18 * without specific prior written permission.
25 * 19 *
@@ -37,11 +31,7 @@
37 */ 31 */
38 32
39#if defined(LIBC_SCCS) && !defined(lint) 33#if defined(LIBC_SCCS) && !defined(lint)
40#if 0 34static char rcsid[] = "$OpenBSD: ns_addr.c,v 1.8 2003/06/02 20:18:35 millert Exp $";
41static char sccsid[] = "@(#)ns_addr.c 8.1 (Berkeley) 6/7/93";
42#else
43static char rcsid[] = "$NetBSD: ns_addr.c,v 1.5 1995/02/25 06:20:51 cgd Exp $";
44#endif
45#endif /* LIBC_SCCS and not lint */ 35#endif /* LIBC_SCCS and not lint */
46 36
47#include <sys/param.h> 37#include <sys/param.h>
@@ -51,7 +41,8 @@ static char rcsid[] = "$NetBSD: ns_addr.c,v 1.5 1995/02/25 06:20:51 cgd Exp $";
51 41
52static struct ns_addr addr, zero_addr; 42static struct ns_addr addr, zero_addr;
53 43
54static void Field(), cvtbase(); 44static void Field(char *, u_int8_t *, int);
45static void cvtbase(long, int, int[], int, u_int8_t[], int);
55 46
56struct ns_addr 47struct ns_addr
57ns_addr(name) 48ns_addr(name)
@@ -61,16 +52,15 @@ ns_addr(name)
61 char *hostname, *socketname, *cp; 52 char *hostname, *socketname, *cp;
62 char buf[50]; 53 char buf[50];
63 54
64 (void)strncpy(buf, name, sizeof(buf) - 1); 55 strlcpy(buf, name, sizeof(buf));
65 buf[sizeof(buf) - 1] = '\0';
66 56
67 /* 57 /*
68 * First, figure out what he intends as a field separtor. 58 * First, figure out what he intends as a field separtor.
69 * Despite the way this routine is written, the prefered 59 * Despite the way this routine is written, the prefered
70 * form 2-272.AA001234H.01777, i.e. XDE standard. 60 * form 2-272.AA001234H.01777, i.e. XDE standard.
71 * Great efforts are made to insure backward compatability. 61 * Great efforts are made to insure backward compatibility.
72 */ 62 */
73 if (hostname = strchr(buf, '#')) 63 if ((hostname = strchr(buf, '#')))
74 separator = '#'; 64 separator = '#';
75 else { 65 else {
76 hostname = strchr(buf, '.'); 66 hostname = strchr(buf, '.');
@@ -95,7 +85,7 @@ ns_addr(name)
95 Field(socketname, (u_char *)&addr.x_port, 2); 85 Field(socketname, (u_char *)&addr.x_port, 2);
96 } 86 }
97 87
98 Field(hostname, addr.x_host.c_host, 6); 88 Field(hostname, (u_char *)addr.x_host.c_host, 6);
99 89
100 return (addr); 90 return (addr);
101} 91}
diff --git a/src/lib/libc/net/ns_ntoa.c b/src/lib/libc/net/ns_ntoa.c
index ad3265399b..fd67e459da 100644
--- a/src/lib/libc/net/ns_ntoa.c
+++ b/src/lib/libc/net/ns_ntoa.c
@@ -1,5 +1,3 @@
1/* $NetBSD: ns_ntoa.c,v 1.4 1995/02/25 06:20:51 cgd Exp $ */
2
3/* 1/*
4 * Copyright (c) 1986, 1993 2 * Copyright (c) 1986, 1993
5 * The Regents of the University of California. All rights reserved. 3 * The Regents of the University of California. All rights reserved.
@@ -12,11 +10,7 @@
12 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission. 15 * without specific prior written permission.
22 * 16 *
@@ -34,73 +28,79 @@
34 */ 28 */
35 29
36#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
37#if 0 31static char rcsid[] = "$OpenBSD: ns_ntoa.c,v 1.13 2003/09/25 21:14:46 millert Exp $";
38static char sccsid[] = "@(#)ns_ntoa.c 8.1 (Berkeley) 6/4/93";
39#else
40static char rcsid[] = "$NetBSD: ns_ntoa.c,v 1.4 1995/02/25 06:20:51 cgd Exp $";
41#endif
42#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
43 33
44#include <sys/param.h> 34#include <sys/param.h>
45#include <netns/ns.h> 35#include <netns/ns.h>
46#include <stdio.h> 36#include <stdio.h>
47 37
38static char *spectHex(char *);
39
48char * 40char *
49ns_ntoa(addr) 41ns_ntoa(struct ns_addr addr)
50 struct ns_addr addr;
51{ 42{
52 static char obuf[40]; 43 static char obuf[40];
53 union { union ns_net net_e; u_long long_e; } net; 44 union { union ns_net net_e; u_int32_t long_e; } net;
54 u_short port = htons(addr.x_port); 45 in_port_t port = htons(addr.x_port);
55 register char *cp; 46 char *cp, *cp2;
56 char *cp2; 47 u_char *up = addr.x_host.c_host;
57 register u_char *up = addr.x_host.c_host;
58 u_char *uplim = up + 6; 48 u_char *uplim = up + 6;
59 static char *spectHex(); 49 size_t rem;
60 50
61 net.net_e = addr.x_net; 51 net.net_e = addr.x_net;
62 sprintf(obuf, "%lx", ntohl(net.long_e)); 52 snprintf(obuf, sizeof obuf, "%x", ntohl(net.long_e));
63 cp = spectHex(obuf); 53 cp = spectHex(obuf);
54 rem = sizeof(obuf) - (cp - obuf);
64 cp2 = cp + 1; 55 cp2 = cp + 1;
65 while (*up==0 && up < uplim) up++; 56 while (up < uplim && *up==0)
57 up++;
66 if (up == uplim) { 58 if (up == uplim) {
67 if (port) { 59 if (port) {
68 sprintf(cp, ".0"); 60 snprintf(cp, rem, ".0");
69 cp += 2; 61 cp += 2;
62 rem -= 2;
70 } 63 }
71 } else { 64 } else {
72 sprintf(cp, ".%x", *up++); 65 snprintf(cp, rem, ".%x", *up++);
73 while (up < uplim) { 66 while (up < uplim) {
74 while (*cp) cp++; 67 while (*cp) {
75 sprintf(cp, "%02x", *up++); 68 cp++;
69 rem--;
70 }
71 snprintf(cp, rem, "%02x", *up++);
76 } 72 }
77 cp = spectHex(cp2); 73 cp = spectHex(cp2);
74 rem = sizeof(obuf) - (cp - obuf);
78 } 75 }
79 if (port) { 76 if (port) {
80 sprintf(cp, ".%x", port); 77 snprintf(cp, rem, ".%x", port);
81 spectHex(cp + 1); 78 spectHex(cp + 1);
82 } 79 }
83 return (obuf); 80 return (obuf);
84} 81}
85 82
86static char * 83static char *
87spectHex(p0) 84spectHex(char *p0)
88 char *p0;
89{ 85{
90 int ok = 0; 86 int ok = 0, nonzero = 0;
91 int nonzero = 0; 87 char *p = p0;
92 register char *p = p0;
93 for (; *p; p++) switch (*p) {
94 88
95 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': 89 for (; *p; p++) {
96 *p += ('A' - 'a'); 90 switch (*p) {
97 /* fall into . . . */ 91 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
98 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': 92 *p += ('A' - 'a');
99 ok = 1; 93 /* fall into . . . */
100 case '1': case '2': case '3': case '4': case '5': 94 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
101 case '6': case '7': case '8': case '9': 95 ok = 1;
102 nonzero = 1; 96 case '1': case '2': case '3': case '4': case '5':
97 case '6': case '7': case '8': case '9':
98 nonzero = 1;
99 }
100 }
101 if (nonzero && !ok) {
102 *p++ = 'H';
103 *p = 0;
103 } 104 }
104 if (nonzero && !ok) { *p++ = 'H'; *p = 0; }
105 return (p); 105 return (p);
106} 106}
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
index 05b7f4c9a3..7d3e227e60 100644
--- a/src/lib/libc/net/ntohl.c
+++ b/src/lib/libc/net/ntohl.c
@@ -1,29 +1,25 @@
1/* $NetBSD: ntohl.c,v 1.5 1995/04/28 23:25:21 jtc Exp $ */
2
3/* 1/*
4 * Written by J.T. Conklin <jtc@netbsd.org>. 2 * Written by J.T. Conklin <jtc@netbsd.org>.
5 * Public domain. 3 * Public domain.
6 */ 4 */
7 5
8#if defined(LIBC_SCCS) && !defined(lint) 6#if defined(LIBC_SCCS) && !defined(lint)
9static char *rcsid = "$NetBSD: ntohl.c,v 1.5 1995/04/28 23:25:21 jtc Exp $"; 7static char *rcsid = "$OpenBSD: ntohl.c,v 1.4 1996/12/12 03:19:56 tholo Exp $";
10#endif 8#endif /* LIBC_SCCS and not lint */
11 9
12#include <sys/types.h> 10#include <sys/types.h>
13#include <machine/endian.h> 11#include <machine/endian.h>
14 12
15#undef ntohl 13#undef ntohl
16 14
17unsigned long 15u_int32_t
18ntohl(x) 16ntohl(x)
19 unsigned long x; 17 u_int32_t x;
20{ 18{
21 u_int32_t y = x;
22
23#if BYTE_ORDER == LITTLE_ENDIAN 19#if BYTE_ORDER == LITTLE_ENDIAN
24 u_char *s = (u_char *)&y; 20 u_char *s = (u_char *)&x;
25 return s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]; 21 return (u_int32_t)(s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]);
26#else 22#else
27 return y; 23 return x;
28#endif 24#endif
29} 25}
diff --git a/src/lib/libc/net/ntohs.c b/src/lib/libc/net/ntohs.c
index 93ab83ee4d..4c3ab33f31 100644
--- a/src/lib/libc/net/ntohs.c
+++ b/src/lib/libc/net/ntohs.c
@@ -1,26 +1,23 @@
1/* $NetBSD: ntohs.c,v 1.5 1995/04/28 23:25:23 jtc Exp $ */
2
3/* 1/*
4 * Written by J.T. Conklin <jtc@netbsd.org>. 2 * Written by J.T. Conklin <jtc@netbsd.org>.
5 * Public domain. 3 * Public domain.
6 */ 4 */
7 5
8#if defined(LIBC_SCCS) && !defined(lint) 6#if defined(LIBC_SCCS) && !defined(lint)
9static char *rcsid = "$NetBSD: ntohs.c,v 1.5 1995/04/28 23:25:23 jtc Exp $"; 7static char *rcsid = "$OpenBSD: ntohs.c,v 1.7 2002/02/19 19:39:36 millert Exp $";
10#endif 8#endif /* LIBC_SCCS and not lint */
11 9
12#include <sys/types.h> 10#include <sys/types.h>
13#include <machine/endian.h> 11#include <machine/endian.h>
14 12
15#undef ntohs 13#undef ntohs
16 14
17unsigned short 15u_int16_t
18ntohs(x) 16ntohs(u_int16_t x)
19 unsigned short x;
20{ 17{
21#if BYTE_ORDER == LITTLE_ENDIAN 18#if BYTE_ORDER == LITTLE_ENDIAN
22 u_char *s = (u_char *) &x; 19 u_char *s = (u_char *) &x;
23 return s[0] << 8 | s[1]; 20 return (u_int16_t)(s[0] << 8 | s[1]);
24#else 21#else
25 return x; 22 return x;
26#endif 23#endif
diff --git a/src/lib/libc/net/rcmd.3 b/src/lib/libc/net/rcmd.3
index 4db847c392..df31a60b63 100644
--- a/src/lib/libc/net/rcmd.3
+++ b/src/lib/libc/net/rcmd.3
@@ -1,4 +1,4 @@
1.\" $NetBSD: rcmd.3,v 1.8 1995/02/25 06:20:52 cgd Exp $ 1.\" $OpenBSD: rcmd.3,v 1.26 2003/06/02 20:18:35 millert Exp $
2.\" 2.\"
3.\" Copyright (c) 1983, 1991, 1993 3.\" Copyright (c) 1983, 1991, 1993
4.\" The Regents of the University of California. All rights reserved. 4.\" The Regents of the University of California. All rights reserved.
@@ -11,11 +11,7 @@
11.\" 2. Redistributions in binary form must reproduce the above copyright 11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the 12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution. 13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software 14.\" 3. Neither the name of the University nor the names of its contributors
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 15.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission. 16.\" without specific prior written permission.
21.\" 17.\"
@@ -31,38 +27,67 @@
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE. 28.\" SUCH DAMAGE.
33.\" 29.\"
34.\" @(#)rcmd.3 8.1 (Berkeley) 6/4/93
35.\"
36.Dd June 4, 1993 30.Dd June 4, 1993
37.Dt RCMD 3 31.Dt RCMD 3
38.Os BSD 4.2 32.Os
39.Sh NAME 33.Sh NAME
40.Nm rcmd , 34.Nm rcmd ,
35.Nm rcmd_af ,
41.Nm rresvport , 36.Nm rresvport ,
37.Nm rresvport_af ,
42.Nm iruserok , 38.Nm iruserok ,
43.Nm ruserok 39.Nm ruserok ,
40.Nm iruserok_sa
44.Nd routines for returning a stream to a remote command 41.Nd routines for returning a stream to a remote command
45.Sh SYNOPSIS 42.Sh SYNOPSIS
46.Fd #include <unistd.h> 43.Fd #include <unistd.h>
47.Ft int 44.Ft int
48.Fn rcmd "char **ahost" "int inport" "const char *locuser" "const char *remuser" "const char *cmd" "int *fd2p" 45.Fn rcmd "char **ahost" "int inport" "const char *locuser" "const char *remuser" "const char *cmd" "int *fd2p"
49.Ft int 46.Ft int
47.Fn rcmd_af "char **ahost" "int inport" "const char *locuser" "const char *remuser" "const char *cmd" "int *fd2p" "int af"
48.Ft int
50.Fn rresvport "int *port" 49.Fn rresvport "int *port"
51.Ft int 50.Ft int
52.Fn iruserok "u_long raddr" "int superuser" "const char *ruser" "const char *luser" 51.Fn rresvport_af "int *port" "int af"
52.Ft int
53.Fn iruserok "u_int32_t raddr" "int superuser" "const char *ruser" "const char *luser"
53.Ft int 54.Ft int
54.Fn ruserok "const char *rhost" "int superuser" "const char *ruser" "const char *luser" 55.Fn ruserok "const char *rhost" "int superuser" "const char *ruser" "const char *luser"
56.Ft int
57.Fn iruserok_sa "const void *sa" "int salen" "int superuser" "const char *ruser" "const char *luser"
55.Sh DESCRIPTION 58.Sh DESCRIPTION
56The 59The
57.Fn rcmd 60.Fn rcmd
58function 61function is used by the superuser to execute a command on a remote
59is used by the super-user to execute a command on 62machine using an authentication scheme based on reserved
60a remote machine using an authentication scheme based 63port numbers.
61on reserved port numbers. 64If the calling process is not setuid, the
65.Ev RSH
66environment variable is set, and
67.Fa inport
68is
69.Dq shell/tcp ,
70.Xr rcmdsh 3
71is called instead with the value of
72.Ev RSH .
73Alternately, if the user is not the superuser,
74.Fn rcmd
75will invoke
76.Xr rcmdsh 3
77to run the command via
78.Xr rsh 1 .
79While
80.Fn rcmd
81can handle IPv4 cases only,
82the
83.Fn rcmd_af
84function can handle other cases as well.
85.Pp
62The 86The
63.Fn rresvport 87.Fn rresvport
64function 88and
65returns a descriptor to a socket 89.Fn rresvport_af
90functions return a descriptor to a socket
66with an address in the privileged port space. 91with an address in the privileged port space.
67The 92The
68.Fn iruserok 93.Fn iruserok
@@ -75,11 +100,13 @@ All four functions are present in the same file and are used
75by the 100by the
76.Xr rshd 8 101.Xr rshd 8
77server (among others). 102server (among others).
103.Fn iruserok_sa
104is an address family independent variant of
105.Fn iruserok .
78.Pp 106.Pp
79The 107The
80.Fn rcmd 108.Fn rcmd
81function 109function looks up the host
82looks up the host
83.Fa *ahost 110.Fa *ahost
84using 111using
85.Xr gethostbyname 3 , 112.Xr gethostbyname 3 ,
@@ -90,15 +117,15 @@ is set to the standard name of the host
90and a connection is established to a server 117and a connection is established to a server
91residing at the well-known Internet port 118residing at the well-known Internet port
92.Fa inport . 119.Fa inport .
120If the user is not the superuser, the only valid port is
121.Dq shell/tcp
122(usually port 514).
93.Pp 123.Pp
94If the connection succeeds, 124If the connection succeeds,
95a socket in the Internet domain of type 125a socket in the Internet domain of type
96.Dv SOCK_STREAM 126.Dv SOCK_STREAM
97is returned to the caller, and given to the remote 127is returned to the caller, and given to the remote
98command as 128command as stdin and stdout.
99.Em stdin
100and
101.Em stdout .
102If 129If
103.Fa fd2p 130.Fa fd2p
104is non-zero, then an auxiliary channel to a control 131is non-zero, then an auxiliary channel to a control
@@ -113,27 +140,46 @@ signal numbers, to be
113forwarded to the process group of the command. 140forwarded to the process group of the command.
114If 141If
115.Fa fd2p 142.Fa fd2p
116is 0, then the 143is
117.Em stderr 144.Va NULL ,
118(unit 2 of the remote 145then the standard error (unit 2 of the remote command) will be made
119command) will be made the same as the 146the same as the standard output and no provision is made for sending
120.Em stdout 147arbitrary signals to the remote process, although you may be able to
121and no 148get its attention by using out-of-band data.
122provision is made for sending arbitrary signals to the remote process, 149Note that if the user is not the superuser,
123although you may be able to get its attention by using out-of-band data. 150.Fa fd2p
151must be
152.Va NULL .
153.Pp
154.Fn rcmd_af
155takes address family in the last argument.
156If the last argument is
157.Dv PF_UNSPEC ,
158interpretation of
159.Fa *ahost
160will obey the underlying address resolution like DNS.
124.Pp 161.Pp
125The protocol is described in detail in 162The protocol is described in detail in
126.Xr rshd 8 . 163.Xr rshd 8 .
127.Pp 164.Pp
128The 165The
129.Fn rresvport 166.Fn rresvport
130function is used to obtain a socket with a privileged 167and
131address bound to it. This socket is suitable for use 168.Fn rresvport_af
132by 169functions are used to obtain a socket with a privileged
170address bound to it.
171This socket is suitable for use by
133.Fn rcmd 172.Fn rcmd
134and several other functions. Privileged Internet ports are those 173and several other functions.
135in the range 0 to 1023. Only the super-user 174Privileged Internet ports are those in the range 0 to
136is allowed to bind an address of this sort to a socket. 175.Va IPPORT_RESERVED - 1 ,
176which happens to be 1023.
177Only the superuser is allowed to bind an address of this sort to a socket.
178.Fn rresvport
179and
180.Fn rresvport_af
181need to be seeded with a port number; if that port
182is not available these functions will find another.
137.Pp 183.Pp
138The 184The
139.Fn iruserok 185.Fn iruserok
@@ -141,10 +187,10 @@ and
141.Fn ruserok 187.Fn ruserok
142functions take a remote host's IP address or name, respectively, 188functions take a remote host's IP address or name, respectively,
143two user names and a flag indicating whether the local user's 189two user names and a flag indicating whether the local user's
144name is that of the super-user. 190name is that of the superuser.
145Then, if the user is 191Then, if the user is
146.Em NOT 192.Em not
147the super-user, it checks the 193the superuser, it checks the
148.Pa /etc/hosts.equiv 194.Pa /etc/hosts.equiv
149file. 195file.
150If that lookup is not done, or is unsuccessful, the 196If that lookup is not done, or is unsuccessful, the
@@ -153,19 +199,19 @@ in the local user's home directory is checked to see if the request for
153service is allowed. 199service is allowed.
154.Pp 200.Pp
155If this file does not exist, is not a regular file, is owned by anyone 201If this file does not exist, is not a regular file, is owned by anyone
156other than the user or the super-user, or is writeable by anyone other 202other than the user or the superuser, or is writeable by anyone other
157than the owner, the check automatically fails. 203than the owner, the check automatically fails.
158Zero is returned if the machine name is listed in the 204Zero is returned if the machine name is listed in the
159.Dq Pa hosts.equiv 205.Pa hosts.equiv
160file, or the host and remote user name are found in the 206file, or the host and remote user name are found in the
161.Dq Pa .rhosts 207.Pa .rhosts
162file; otherwise 208file; otherwise
163.Fn iruserok 209.Fn iruserok
164and 210and
165.Fn ruserok 211.Fn ruserok
166return \-1. 212return \-1.
167If the local domain (as obtained from 213If the local domain (as obtained from
168.Xr gethostname 2 ) 214.Xr gethostname 3 )
169is the same as the remote domain, only the machine name need be specified. 215is the same as the remote domain, only the machine name need be specified.
170.Pp 216.Pp
171If the IP address of the remote host is known, 217If the IP address of the remote host is known,
@@ -173,32 +219,48 @@ If the IP address of the remote host is known,
173should be used in preference to 219should be used in preference to
174.Fn ruserok , 220.Fn ruserok ,
175as it does not require trusting the DNS server for the remote host's domain. 221as it does not require trusting the DNS server for the remote host's domain.
222.Pp
223While
224.Fn iruserok
225can handle IPv4 addresses only,
226.Fn iruserok_sa
227and
228.Fn ruserok
229can handle other address families as well, like IPv6.
230The first argument of
231.Fn iruserok_sa
232is typed as
233.Li "void *"
234to avoid dependency between
235.Aq Pa unistd.h
236and
237.Aq Pa sys/socket.h .
176.Sh DIAGNOSTICS 238.Sh DIAGNOSTICS
177The 239The
178.Fn rcmd 240.Fn rcmd
179function 241function returns a valid socket descriptor on success.
180returns a valid socket descriptor on success.
181It returns \-1 on error and prints a diagnostic message on the standard error. 242It returns \-1 on error and prints a diagnostic message on the standard error.
182.Pp 243.Pp
183The 244The
184.Fn rresvport 245.Fn rresvport
185function 246and
186returns a valid, bound socket descriptor on success. 247.Fn rresvport_af
248functions return a valid, bound socket descriptor on success.
187It returns \-1 on error with the global value 249It returns \-1 on error with the global value
188.Va errno 250.Va errno
189set according to the reason for failure. 251set according to the reason for failure.
190The error code 252The error code
191.Dv EAGAIN 253.Er EAGAIN
192is overloaded to mean ``All network ports in use.'' 254is overloaded to mean
255.Dq all network ports in use .
193.Sh SEE ALSO 256.Sh SEE ALSO
194.Xr rlogin 1 ,
195.Xr rsh 1 , 257.Xr rsh 1 ,
196.Xr intro 2 , 258.Xr intro 2 ,
197.Xr rexec 3 , 259.Xr bindresvport 3 ,
198.Xr rexecd 8 , 260.Xr bindresvport_sa 3 ,
199.Xr rlogind 8 , 261.Xr rcmdsh 3 ,
200.Xr rshd 8 262.Xr rshd 8
201.Sh HISTORY 263.Sh HISTORY
202These 264These
203functions appeared in 265functions appeared in
204.Bx 4.2 . 266.Bx 4.2 .
diff --git a/src/lib/libc/net/rcmd.c b/src/lib/libc/net/rcmd.c
index e0310031b0..769e85e0a4 100644
--- a/src/lib/libc/net/rcmd.c
+++ b/src/lib/libc/net/rcmd.c
@@ -1,6 +1,5 @@
1/* $NetBSD: rcmd.c,v 1.12 1995/06/03 22:33:34 mycroft Exp $ */
2
3/* 1/*
2 * Copyright (c) 1995, 1996, 1998 Theo de Raadt. All rights reserved.
4 * Copyright (c) 1983, 1993, 1994 3 * Copyright (c) 1983, 1993, 1994
5 * The Regents of the University of California. All rights reserved. 4 * The Regents of the University of California. All rights reserved.
6 * 5 *
@@ -12,11 +11,7 @@
12 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 14 * 3. Neither the name of the University nor the names of its contributors
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 15 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission. 16 * without specific prior written permission.
22 * 17 *
@@ -34,11 +29,7 @@
34 */ 29 */
35 30
36#if defined(LIBC_SCCS) && !defined(lint) 31#if defined(LIBC_SCCS) && !defined(lint)
37#if 0 32static char *rcsid = "$OpenBSD: rcmd.c,v 1.48 2003/09/25 21:14:46 millert Exp $";
38static char sccsid[] = "@(#)rcmd.c 8.3 (Berkeley) 3/26/94";
39#else
40static char *rcsid = "$NetBSD: rcmd.c,v 1.12 1995/06/03 22:33:34 mycroft Exp $";
41#endif
42#endif /* LIBC_SCCS and not lint */ 33#endif /* LIBC_SCCS and not lint */
43 34
44#include <sys/param.h> 35#include <sys/param.h>
@@ -57,35 +48,90 @@ static char *rcsid = "$NetBSD: rcmd.c,v 1.12 1995/06/03 22:33:34 mycroft Exp $";
57#include <stdio.h> 48#include <stdio.h>
58#include <ctype.h> 49#include <ctype.h>
59#include <string.h> 50#include <string.h>
51#include <syslog.h>
52#include <stdlib.h>
53#include <netgroup.h>
60 54
61int __ivaliduser __P((FILE *, u_long, const char *, const char *)); 55int __ivaliduser(FILE *, in_addr_t, const char *, const char *);
62static int __icheckhost __P((u_long, const char *)); 56int __ivaliduser_sa(FILE *, struct sockaddr *, socklen_t,
57 const char *, const char *);
58static int __icheckhost(struct sockaddr *, socklen_t, const char *);
59static char *__gethostloop(struct sockaddr *, socklen_t);
63 60
64int 61int
65rcmd(ahost, rport, locuser, remuser, cmd, fd2p) 62rcmd(ahost, rport, locuser, remuser, cmd, fd2p)
66 char **ahost; 63 char **ahost;
67 u_short rport; 64 in_port_t rport;
65 const char *locuser, *remuser, *cmd;
66 int *fd2p;
67{
68 return rcmd_af(ahost, rport, locuser, remuser, cmd, fd2p, AF_INET);
69}
70
71int
72rcmd_af(ahost, rport, locuser, remuser, cmd, fd2p, af)
73 char **ahost;
74 in_port_t rport;
68 const char *locuser, *remuser, *cmd; 75 const char *locuser, *remuser, *cmd;
69 int *fd2p; 76 int *fd2p;
77 int af;
70{ 78{
71 struct hostent *hp; 79 static char hbuf[MAXHOSTNAMELEN];
72 struct sockaddr_in sin, from; 80 char pbuf[NI_MAXSERV];
73 fd_set reads; 81 struct addrinfo hints, *res, *r;
74 long oldmask; 82 int error;
83 struct sockaddr_storage from;
84 fd_set *readsp = NULL;
85 sigset_t oldmask, mask;
75 pid_t pid; 86 pid_t pid;
76 int s, lport, timo; 87 int s, lport, timo;
77 char c; 88 char c, *p;
89 int refused;
90
91 /* call rcmdsh() with specified remote shell if appropriate. */
92 if (!issetugid() && (p = getenv("RSH")) && *p) {
93 struct servent *sp = getservbyname("shell", "tcp");
94
95 if (sp && sp->s_port == rport)
96 return (rcmdsh(ahost, rport, locuser, remuser,
97 cmd, p));
98 }
99
100 /* use rsh(1) if non-root and remote port is shell. */
101 if (geteuid()) {
102 struct servent *sp = getservbyname("shell", "tcp");
103
104 if (sp && sp->s_port == rport)
105 return (rcmdsh(ahost, rport, locuser, remuser,
106 cmd, NULL));
107 }
78 108
79 pid = getpid(); 109 pid = getpid();
80 hp = gethostbyname(*ahost); 110 snprintf(pbuf, sizeof(pbuf), "%u", ntohs(rport));
81 if (hp == NULL) { 111 memset(&hints, 0, sizeof(hints));
82 herror(*ahost); 112 hints.ai_family = af;
113 hints.ai_socktype = SOCK_STREAM;
114 hints.ai_flags = AI_CANONNAME;
115 error = getaddrinfo(*ahost, pbuf, &hints, &res);
116 if (error) {
117#if 0
118 warnx("%s: %s", *ahost, gai_strerror(error));
119#endif
83 return (-1); 120 return (-1);
84 } 121 }
85 *ahost = hp->h_name; 122 if (res->ai_canonname) {
86 oldmask = sigblock(sigmask(SIGURG)); 123 strlcpy(hbuf, res->ai_canonname, sizeof(hbuf));
124 *ahost = hbuf;
125 } else
126 ; /*XXX*/
127
128 r = res;
129 refused = 0;
130 sigemptyset(&mask);
131 sigaddset(&mask, SIGURG);
132 oldmask = sigprocmask(SIG_BLOCK, &mask, &oldmask);
87 for (timo = 1, lport = IPPORT_RESERVED - 1;;) { 133 for (timo = 1, lport = IPPORT_RESERVED - 1;;) {
88 s = rresvport(&lport); 134 s = rresvport_af(&lport, r->ai_family);
89 if (s < 0) { 135 if (s < 0) {
90 if (errno == EAGAIN) 136 if (errno == EAGAIN)
91 (void)fprintf(stderr, 137 (void)fprintf(stderr,
@@ -93,54 +139,86 @@ rcmd(ahost, rport, locuser, remuser, cmd, fd2p)
93 else 139 else
94 (void)fprintf(stderr, "rcmd: socket: %s\n", 140 (void)fprintf(stderr, "rcmd: socket: %s\n",
95 strerror(errno)); 141 strerror(errno));
96 sigsetmask(oldmask); 142 if (r->ai_next) {
97 return (-1); 143 r = r->ai_next;
144 continue;
145 } else {
146 sigprocmask(SIG_SETMASK, &oldmask, NULL);
147 freeaddrinfo(res);
148 return (-1);
149 }
98 } 150 }
99 fcntl(s, F_SETOWN, pid); 151 fcntl(s, F_SETOWN, pid);
100 sin.sin_len = sizeof(struct sockaddr_in); 152 if (connect(s, r->ai_addr, r->ai_addrlen) >= 0)
101 sin.sin_family = hp->h_addrtype;
102 sin.sin_port = rport;
103 bcopy(hp->h_addr_list[0], &sin.sin_addr, hp->h_length);
104 if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0)
105 break; 153 break;
106 (void)close(s); 154 (void)close(s);
107 if (errno == EADDRINUSE) { 155 if (errno == EADDRINUSE) {
108 lport--; 156 lport--;
109 continue; 157 continue;
110 } 158 }
111 if (errno == ECONNREFUSED && timo <= 16) { 159 if (errno == ECONNREFUSED)
112 (void)sleep(timo); 160 refused++;
113 timo *= 2; 161 if (r->ai_next) {
114 continue;
115 }
116 if (hp->h_addr_list[1] != NULL) {
117 int oerrno = errno; 162 int oerrno = errno;
163 char hbuf[NI_MAXHOST];
164#ifdef NI_WITHSCOPEID
165 const int niflags = NI_NUMERICHOST | NI_WITHSCOPEID;
166#else
167 const int niflags = NI_NUMERICHOST;
168#endif
118 169
119 (void)fprintf(stderr, "connect to address %s: ", 170 hbuf[0] = '\0';
120 inet_ntoa(sin.sin_addr)); 171 if (getnameinfo(r->ai_addr, r->ai_addrlen,
172 hbuf, sizeof(hbuf), NULL, 0, niflags) != 0)
173 strlcpy(hbuf, "(invalid)", sizeof hbuf);
174 (void)fprintf(stderr, "connect to address %s: ", hbuf);
121 errno = oerrno; 175 errno = oerrno;
122 perror(0); 176 perror(0);
123 hp->h_addr_list++; 177 r = r->ai_next;
124 bcopy(hp->h_addr_list[0], &sin.sin_addr, hp->h_length); 178 hbuf[0] = '\0';
125 (void)fprintf(stderr, "Trying %s...\n", 179 if (getnameinfo(r->ai_addr, r->ai_addrlen,
126 inet_ntoa(sin.sin_addr)); 180 hbuf, sizeof(hbuf), NULL, 0, niflags) != 0)
181 strlcpy(hbuf, "(invalid)", sizeof hbuf);
182 (void)fprintf(stderr, "Trying %s...\n", hbuf);
183 continue;
184 }
185 if (refused && timo <= 16) {
186 (void)sleep(timo);
187 timo *= 2;
188 r = res;
189 refused = 0;
127 continue; 190 continue;
128 } 191 }
129 (void)fprintf(stderr, "%s: %s\n", hp->h_name, strerror(errno)); 192 (void)fprintf(stderr, "%s: %s\n", res->ai_canonname,
130 sigsetmask(oldmask); 193 strerror(errno));
194 sigprocmask(SIG_SETMASK, &oldmask, NULL);
195 freeaddrinfo(res);
131 return (-1); 196 return (-1);
132 } 197 }
198 /* given "af" can be PF_UNSPEC, we need the real af for "s" */
199 af = r->ai_family;
200 freeaddrinfo(res);
201#if 0
202 /*
203 * try to rresvport() to the same port. This will make rresvport()
204 * fail it's first bind, resulting in it choosing a random port.
205 */
133 lport--; 206 lport--;
207#endif
134 if (fd2p == 0) { 208 if (fd2p == 0) {
135 write(s, "", 1); 209 write(s, "", 1);
136 lport = 0; 210 lport = 0;
137 } else { 211 } else {
138 char num[8]; 212 char num[8];
139 int s2 = rresvport(&lport), s3; 213 int s2 = rresvport_af(&lport, af), s3;
140 int len = sizeof(from); 214 socklen_t len = sizeof(from);
215 int fdssize = howmany(MAX(s, s2)+1, NFDBITS) * sizeof(fd_mask);
141 216
142 if (s2 < 0) 217 if (s2 < 0)
143 goto bad; 218 goto bad;
219 readsp = (fd_set *)malloc(fdssize);
220 if (readsp == NULL)
221 goto bad;
144 listen(s2, 1); 222 listen(s2, 1);
145 (void)snprintf(num, sizeof(num), "%d", lport); 223 (void)snprintf(num, sizeof(num), "%d", lport);
146 if (write(s, num, strlen(num)+1) != strlen(num)+1) { 224 if (write(s, num, strlen(num)+1) != strlen(num)+1) {
@@ -150,12 +228,13 @@ rcmd(ahost, rport, locuser, remuser, cmd, fd2p)
150 (void)close(s2); 228 (void)close(s2);
151 goto bad; 229 goto bad;
152 } 230 }
153 FD_ZERO(&reads); 231again:
154 FD_SET(s, &reads); 232 bzero(readsp, fdssize);
155 FD_SET(s2, &reads); 233 FD_SET(s, readsp);
234 FD_SET(s2, readsp);
156 errno = 0; 235 errno = 0;
157 if (select(MAX(s, s2) + 1, &reads, 0, 0, 0) < 1 || 236 if (select(MAX(s, s2) + 1, readsp, 0, 0, 0) < 1 ||
158 !FD_ISSET(s2, &reads)) { 237 !FD_ISSET(s2, readsp)) {
159 if (errno != 0) 238 if (errno != 0)
160 (void)fprintf(stderr, 239 (void)fprintf(stderr,
161 "rcmd: select (setting up stderr): %s\n", 240 "rcmd: select (setting up stderr): %s\n",
@@ -167,6 +246,23 @@ rcmd(ahost, rport, locuser, remuser, cmd, fd2p)
167 goto bad; 246 goto bad;
168 } 247 }
169 s3 = accept(s2, (struct sockaddr *)&from, &len); 248 s3 = accept(s2, (struct sockaddr *)&from, &len);
249 /*
250 * XXX careful for ftp bounce attacks. If discovered, shut them
251 * down and check for the real auxiliary channel to connect.
252 */
253 switch (from.ss_family) {
254 case AF_INET:
255 case AF_INET6:
256 if (getnameinfo((struct sockaddr *)&from, len,
257 NULL, 0, num, sizeof(num), NI_NUMERICSERV) == 0 &&
258 atoi(num) != 20) {
259 break;
260 }
261 close(s3);
262 goto again;
263 default:
264 break;
265 }
170 (void)close(s2); 266 (void)close(s2);
171 if (s3 < 0) { 267 if (s3 < 0) {
172 (void)fprintf(stderr, 268 (void)fprintf(stderr,
@@ -175,13 +271,20 @@ rcmd(ahost, rport, locuser, remuser, cmd, fd2p)
175 goto bad; 271 goto bad;
176 } 272 }
177 *fd2p = s3; 273 *fd2p = s3;
178 from.sin_port = ntohs(from.sin_port); 274 switch (from.ss_family) {
179 if (from.sin_family != AF_INET || 275 case AF_INET:
180 from.sin_port >= IPPORT_RESERVED || 276 case AF_INET6:
181 from.sin_port < IPPORT_RESERVED / 2) { 277 if (getnameinfo((struct sockaddr *)&from, len,
182 (void)fprintf(stderr, 278 NULL, 0, num, sizeof(num), NI_NUMERICSERV) != 0 ||
183 "socket: protocol failure in circuit setup.\n"); 279 (atoi(num) >= IPPORT_RESERVED ||
184 goto bad2; 280 atoi(num) < IPPORT_RESERVED / 2)) {
281 (void)fprintf(stderr,
282 "socket: protocol failure in circuit setup.\n");
283 goto bad2;
284 }
285 break;
286 default:
287 break;
185 } 288 }
186 } 289 }
187 (void)write(s, locuser, strlen(locuser)+1); 290 (void)write(s, locuser, strlen(locuser)+1);
@@ -200,47 +303,20 @@ rcmd(ahost, rport, locuser, remuser, cmd, fd2p)
200 } 303 }
201 goto bad2; 304 goto bad2;
202 } 305 }
203 sigsetmask(oldmask); 306 sigprocmask(SIG_SETMASK, &oldmask, NULL);
307 free(readsp);
204 return (s); 308 return (s);
205bad2: 309bad2:
206 if (lport) 310 if (lport)
207 (void)close(*fd2p); 311 (void)close(*fd2p);
208bad: 312bad:
313 if (readsp)
314 free(readsp);
209 (void)close(s); 315 (void)close(s);
210 sigsetmask(oldmask); 316 sigprocmask(SIG_SETMASK, &oldmask, NULL);
211 return (-1); 317 return (-1);
212} 318}
213 319
214int
215rresvport(alport)
216 int *alport;
217{
218 struct sockaddr_in sin;
219 int s;
220
221 sin.sin_len = sizeof(struct sockaddr_in);
222 sin.sin_family = AF_INET;
223 sin.sin_addr.s_addr = INADDR_ANY;
224 s = socket(AF_INET, SOCK_STREAM, 0);
225 if (s < 0)
226 return (-1);
227 for (;;) {
228 sin.sin_port = htons((u_short)*alport);
229 if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0)
230 return (s);
231 if (errno != EADDRINUSE) {
232 (void)close(s);
233 return (-1);
234 }
235 (*alport)--;
236 if (*alport == IPPORT_RESERVED/2) {
237 (void)close(s);
238 errno = EAGAIN; /* close */
239 return (-1);
240 }
241 }
242}
243
244int __check_rhosts_file = 1; 320int __check_rhosts_file = 1;
245char *__rcmd_errstr; 321char *__rcmd_errstr;
246 322
@@ -249,21 +325,24 @@ ruserok(rhost, superuser, ruser, luser)
249 const char *rhost, *ruser, *luser; 325 const char *rhost, *ruser, *luser;
250 int superuser; 326 int superuser;
251{ 327{
252 struct hostent *hp; 328 struct addrinfo hints, *res, *r;
253 char **ap; 329 int error;
254 int i; 330
255#define MAXADDRS 35 331 memset(&hints, 0, sizeof(hints));
256 u_long addrs[MAXADDRS + 1]; 332 hints.ai_family = PF_UNSPEC;
257 333 hints.ai_socktype = SOCK_DGRAM; /*dummy*/
258 if ((hp = gethostbyname(rhost)) == NULL) 334 error = getaddrinfo(rhost, "0", &hints, &res);
335 if (error)
259 return (-1); 336 return (-1);
260 for (i = 0, ap = hp->h_addr_list; *ap && i < MAXADDRS; ++ap, ++i)
261 bcopy(*ap, &addrs[i], sizeof(addrs[i]));
262 addrs[i] = 0;
263 337
264 for (i = 0; i < MAXADDRS && addrs[i]; i++) 338 for (r = res; r; r = r->ai_next) {
265 if (iruserok(addrs[i], superuser, ruser, luser) == 0) 339 if (iruserok_sa(r->ai_addr, r->ai_addrlen, superuser, ruser,
340 luser) == 0) {
341 freeaddrinfo(res);
266 return (0); 342 return (0);
343 }
344 }
345 freeaddrinfo(res);
267 return (-1); 346 return (-1);
268} 347}
269 348
@@ -278,10 +357,28 @@ ruserok(rhost, superuser, ruser, luser)
278 */ 357 */
279int 358int
280iruserok(raddr, superuser, ruser, luser) 359iruserok(raddr, superuser, ruser, luser)
281 u_long raddr; 360 u_int32_t raddr;
282 int superuser; 361 int superuser;
283 const char *ruser, *luser; 362 const char *ruser, *luser;
284{ 363{
364 struct sockaddr_in sin;
365
366 memset(&sin, 0, sizeof(sin));
367 sin.sin_family = AF_INET;
368 sin.sin_len = sizeof(struct sockaddr_in);
369 memcpy(&sin.sin_addr, &raddr, sizeof(sin.sin_addr));
370 return iruserok_sa(&sin, sizeof(struct sockaddr_in), superuser, ruser,
371 luser);
372}
373
374int
375iruserok_sa(raddr, rlen, superuser, ruser, luser)
376 const void *raddr;
377 int rlen;
378 int superuser;
379 const char *ruser, *luser;
380{
381 struct sockaddr *sa;
285 register char *cp; 382 register char *cp;
286 struct stat sbuf; 383 struct stat sbuf;
287 struct passwd *pwd; 384 struct passwd *pwd;
@@ -290,11 +387,12 @@ iruserok(raddr, superuser, ruser, luser)
290 int first; 387 int first;
291 char pbuf[MAXPATHLEN]; 388 char pbuf[MAXPATHLEN];
292 389
390 sa = (struct sockaddr *)raddr;
293 first = 1; 391 first = 1;
294 hostf = superuser ? NULL : fopen(_PATH_HEQUIV, "r"); 392 hostf = superuser ? NULL : fopen(_PATH_HEQUIV, "r");
295again: 393again:
296 if (hostf) { 394 if (hostf) {
297 if (__ivaliduser(hostf, raddr, luser, ruser) == 0) { 395 if (__ivaliduser_sa(hostf, sa, rlen, luser, ruser) == 0) {
298 (void)fclose(hostf); 396 (void)fclose(hostf);
299 return (0); 397 return (0);
300 } 398 }
@@ -304,8 +402,7 @@ again:
304 first = 0; 402 first = 0;
305 if ((pwd = getpwnam(luser)) == NULL) 403 if ((pwd = getpwnam(luser)) == NULL)
306 return (-1); 404 return (-1);
307 (void)strcpy(pbuf, pwd->pw_dir); 405 snprintf(pbuf, sizeof pbuf, "%s/.rhosts", pwd->pw_dir);
308 (void)strcat(pbuf, "/.rhosts");
309 406
310 /* 407 /*
311 * Change effective uid while opening .rhosts. If root and 408 * Change effective uid while opening .rhosts. If root and
@@ -333,7 +430,7 @@ again:
333 else if (sbuf.st_uid && sbuf.st_uid != pwd->pw_uid) 430 else if (sbuf.st_uid && sbuf.st_uid != pwd->pw_uid)
334 cp = "bad .rhosts owner"; 431 cp = "bad .rhosts owner";
335 else if (sbuf.st_mode & (S_IWGRP|S_IWOTH)) 432 else if (sbuf.st_mode & (S_IWGRP|S_IWOTH))
336 cp = ".rhosts writeable by other than owner"; 433 cp = ".rhosts writable by other than owner";
337 /* If there were any problems, quit. */ 434 /* If there were any problems, quit. */
338 if (cp) { 435 if (cp) {
339 __rcmd_errstr = cp; 436 __rcmd_errstr = cp;
@@ -352,41 +449,63 @@ again:
352 * Returns 0 if ok, -1 if not ok. 449 * Returns 0 if ok, -1 if not ok.
353 */ 450 */
354int 451int
355__ivaliduser(hostf, raddr, luser, ruser) 452__ivaliduser(hostf, raddrl, luser, ruser)
453 FILE *hostf;
454 in_addr_t raddrl;
455 const char *luser, *ruser;
456{
457 struct sockaddr_in sin;
458
459 memset(&sin, 0, sizeof(sin));
460 sin.sin_family = AF_INET;
461 sin.sin_len = sizeof(struct sockaddr_in);
462 memcpy(&sin.sin_addr, &raddrl, sizeof(sin.sin_addr));
463 return __ivaliduser_sa(hostf, (struct sockaddr *)&sin, sin.sin_len,
464 luser, ruser);
465}
466
467int
468__ivaliduser_sa(hostf, raddr, salen, luser, ruser)
356 FILE *hostf; 469 FILE *hostf;
357 u_long raddr; 470 struct sockaddr *raddr;
471 socklen_t salen;
358 const char *luser, *ruser; 472 const char *luser, *ruser;
359{ 473{
360 register char *user, *p; 474 register char *user, *p;
361 int ch; 475 char *buf;
362 char buf[MAXHOSTNAMELEN + 128]; /* host + login */
363 const char *auser, *ahost; 476 const char *auser, *ahost;
364 int hostok, userok; 477 int hostok, userok;
365 char rhost[MAXHOSTNAMELEN]; 478 char *rhost = (char *)-1;
366 struct hostent *hp;
367 char domain[MAXHOSTNAMELEN]; 479 char domain[MAXHOSTNAMELEN];
480 size_t buflen;
368 481
369 getdomainname(domain, sizeof(domain)); 482 getdomainname(domain, sizeof(domain));
370 483
371 while (fgets(buf, sizeof(buf), hostf)) { 484 while ((buf = fgetln(hostf, &buflen))) {
372 p = buf; 485 p = buf;
373 /* Skip lines that are too long. */ 486 if (*p == '#')
374 if (strchr(p, '\n') == NULL) {
375 while ((ch = getc(hostf)) != '\n' && ch != EOF);
376 continue; 487 continue;
377 } 488 while (p < buf + buflen && *p != '\n' && *p != ' ' && *p != '\t') {
378 while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') { 489 if (!isprint(*p))
490 goto bail;
379 *p = isupper(*p) ? tolower(*p) : *p; 491 *p = isupper(*p) ? tolower(*p) : *p;
380 p++; 492 p++;
381 } 493 }
494 if (p >= buf + buflen)
495 continue;
382 if (*p == ' ' || *p == '\t') { 496 if (*p == ' ' || *p == '\t') {
383 *p++ = '\0'; 497 *p++ = '\0';
384 while (*p == ' ' || *p == '\t') 498 while (p < buf + buflen && (*p == ' ' || *p == '\t'))
385 p++; 499 p++;
500 if (p >= buf + buflen)
501 continue;
386 user = p; 502 user = p;
387 while (*p != '\n' && *p != ' ' && 503 while (p < buf + buflen && *p != '\n' && *p != ' ' &&
388 *p != '\t' && *p != '\0') 504 *p != '\t') {
505 if (!isprint(*p))
506 goto bail;
389 p++; 507 p++;
508 }
390 } else 509 } else
391 user = p; 510 user = p;
392 *p = '\0'; 511 *p = '\0';
@@ -397,27 +516,29 @@ __ivaliduser(hostf, raddr, luser, ruser)
397 auser = *user ? user : luser; 516 auser = *user ? user : luser;
398 ahost = buf; 517 ahost = buf;
399 518
400 if ((hp = gethostbyaddr((char *) &raddr, 519 if (strlen(ahost) >= MAXHOSTNAMELEN)
401 sizeof(raddr), AF_INET)) == NULL) { 520 continue;
402 abort();
403 return -1;
404 }
405 (void) strncpy(rhost, hp->h_name, sizeof(rhost));
406 rhost[sizeof(rhost) - 1] = '\0';
407 521
522 /*
523 * innetgr() must lookup a hostname (we do not attempt
524 * to change the semantics so that netgroups may have
525 * #.#.#.# addresses in the list.)
526 */
408 if (ahost[0] == '+') 527 if (ahost[0] == '+')
409 switch (ahost[1]) { 528 switch (ahost[1]) {
410 case '\0': 529 case '\0':
411 hostok = 1; 530 hostok = 1;
412 break; 531 break;
413
414 case '@': 532 case '@':
415 hostok = innetgr(&ahost[2], rhost, NULL, 533 if (rhost == (char *)-1)
416 domain); 534 rhost = __gethostloop(raddr, salen);
535 hostok = 0;
536 if (rhost)
537 hostok = innetgr(&ahost[2], rhost,
538 NULL, domain);
417 break; 539 break;
418
419 default: 540 default:
420 hostok = __icheckhost(raddr, &ahost[1]); 541 hostok = __icheckhost(raddr, salen, &ahost[1]);
421 break; 542 break;
422 } 543 }
423 else if (ahost[0] == '-') 544 else if (ahost[0] == '-')
@@ -425,18 +546,20 @@ __ivaliduser(hostf, raddr, luser, ruser)
425 case '\0': 546 case '\0':
426 hostok = -1; 547 hostok = -1;
427 break; 548 break;
428
429 case '@': 549 case '@':
430 hostok = -innetgr(&ahost[2], rhost, NULL, 550 if (rhost == (char *)-1)
431 domain); 551 rhost = __gethostloop(raddr, salen);
552 hostok = 0;
553 if (rhost)
554 hostok = -innetgr(&ahost[2], rhost,
555 NULL, domain);
432 break; 556 break;
433
434 default: 557 default:
435 hostok = -__icheckhost(raddr, &ahost[1]); 558 hostok = -__icheckhost(raddr, salen, &ahost[1]);
436 break; 559 break;
437 } 560 }
438 else 561 else
439 hostok = __icheckhost(raddr, ahost); 562 hostok = __icheckhost(raddr, salen, ahost);
440 563
441 564
442 if (auser[0] == '+') 565 if (auser[0] == '+')
@@ -444,14 +567,12 @@ __ivaliduser(hostf, raddr, luser, ruser)
444 case '\0': 567 case '\0':
445 userok = 1; 568 userok = 1;
446 break; 569 break;
447
448 case '@': 570 case '@':
449 userok = innetgr(&auser[2], NULL, ruser, 571 userok = innetgr(&auser[2], NULL, ruser,
450 domain); 572 domain);
451 break; 573 break;
452
453 default: 574 default:
454 userok = strcmp(ruser, &auser[1]) == 0; 575 userok = strcmp(ruser, &auser[1]) ? 0 : 1;
455 break; 576 break;
456 } 577 }
457 else if (auser[0] == '-') 578 else if (auser[0] == '-')
@@ -459,59 +580,149 @@ __ivaliduser(hostf, raddr, luser, ruser)
459 case '\0': 580 case '\0':
460 userok = -1; 581 userok = -1;
461 break; 582 break;
462
463 case '@': 583 case '@':
464 userok = -innetgr(&auser[2], NULL, ruser, 584 userok = -innetgr(&auser[2], NULL, ruser,
465 domain); 585 domain);
466 break; 586 break;
467
468 default: 587 default:
469 userok = -(strcmp(ruser, &auser[1]) == 0); 588 userok = strcmp(ruser, &auser[1]) ? 0 : -1;
470 break; 589 break;
471 } 590 }
472 else 591 else
473 userok = strcmp(ruser, auser) == 0; 592 userok = strcmp(ruser, auser) ? 0 : 1;
474 593
475 /* Check if one component did not match */ 594 /* Check if one component did not match */
476 if (hostok == 0 || userok == 0) 595 if (hostok == 0 || userok == 0)
477 continue; 596 continue;
478 597
479 /* Check if we got a forbidden pair */ 598 /* Check if we got a forbidden pair */
480 if (userok == -1 || hostok == -1) 599 if (userok <= -1 || hostok <= -1)
481 return -1; 600 return (-1);
482 601
483 /* Check if we got a valid pair */ 602 /* Check if we got a valid pair */
484 if (hostok == 1 && userok == 1) 603 if (hostok >= 1 && userok >= 1)
485 return 0; 604 return (0);
486 } 605 }
487 return -1; 606bail:
607 return (-1);
488} 608}
489 609
490/* 610/*
491 * Returns "true" if match, 0 if no match. 611 * Returns "true" if match, 0 if no match. If we do not find any
612 * semblance of an A->PTR->A loop, allow a simple #.#.#.# match to work.
613 *
614 * NI_WITHSCOPEID is useful for comparing sin6_scope_id portion
615 * if af == AF_INET6.
492 */ 616 */
493static int 617static int
494__icheckhost(raddr, lhost) 618__icheckhost(raddr, salen, lhost)
495 u_long raddr; 619 struct sockaddr *raddr;
620 socklen_t salen;
496 const char *lhost; 621 const char *lhost;
497{ 622{
498 register struct hostent *hp; 623 struct addrinfo hints, *res, *r;
499 register u_long laddr; 624 char h1[NI_MAXHOST], h2[NI_MAXHOST];
500 register char **pp; 625 int error;
626#ifdef NI_WITHSCOPEID
627 const int niflags = NI_NUMERICHOST | NI_WITHSCOPEID;
628#else
629 const int niflags = NI_NUMERICHOST;
630#endif
501 631
502 /* Try for raw ip address first. */ 632 h1[0] = '\0';
503 if (isdigit(*lhost) && (long)(laddr = inet_addr(lhost)) != -1) 633 if (getnameinfo(raddr, salen, h1, sizeof(h1), NULL, 0,
504 return (raddr == laddr); 634 niflags) != 0)
635 return (0);
505 636
506 /* Better be a hostname. */ 637 /* Resolve laddr into sockaddr */
507 if ((hp = gethostbyname(lhost)) == NULL) 638 memset(&hints, 0, sizeof(hints));
639 hints.ai_family = raddr->sa_family;
640 hints.ai_socktype = SOCK_DGRAM; /*dummy*/
641 res = NULL;
642 error = getaddrinfo(lhost, "0", &hints, &res);
643 if (error)
508 return (0); 644 return (0);
509 645
510 /* Spin through ip addresses. */ 646 /*
511 for (pp = hp->h_addr_list; *pp; ++pp) 647 * Try string comparisons between raddr and laddr.
512 if (!bcmp(&raddr, *pp, sizeof(u_long))) 648 */
649 for (r = res; r; r = r->ai_next) {
650 h2[0] = '\0';
651 if (getnameinfo(r->ai_addr, r->ai_addrlen, h2, sizeof(h2),
652 NULL, 0, niflags) != 0)
653 continue;
654 if (strcmp(h1, h2) == 0) {
655 freeaddrinfo(res);
513 return (1); 656 return (1);
657 }
658 }
514 659
515 /* No match. */ 660 /* No match. */
661 freeaddrinfo(res);
516 return (0); 662 return (0);
517} 663}
664
665/*
666 * Return the hostname associated with the supplied address.
667 * Do a reverse lookup as well for security. If a loop cannot
668 * be found, pack the result of inet_ntoa() into the string.
669 *
670 * NI_WITHSCOPEID is useful for comparing sin6_scope_id portion
671 * if af == AF_INET6.
672 */
673static char *
674__gethostloop(raddr, salen)
675 struct sockaddr *raddr;
676 socklen_t salen;
677{
678 static char remotehost[NI_MAXHOST];
679 char h1[NI_MAXHOST], h2[NI_MAXHOST];
680 struct addrinfo hints, *res, *r;
681 int error;
682#ifdef NI_WITHSCOPEID
683 const int niflags = NI_NUMERICHOST | NI_WITHSCOPEID;
684#else
685 const int niflags = NI_NUMERICHOST;
686#endif
687
688 h1[0] = remotehost[0] = '\0';
689 if (getnameinfo(raddr, salen, remotehost, sizeof(remotehost),
690 NULL, 0, NI_NAMEREQD) != 0)
691 return (NULL);
692 if (getnameinfo(raddr, salen, h1, sizeof(h1), NULL, 0,
693 niflags) != 0)
694 return (NULL);
695
696 /*
697 * Look up the name and check that the supplied
698 * address is in the list
699 */
700 memset(&hints, 0, sizeof(hints));
701 hints.ai_family = raddr->sa_family;
702 hints.ai_socktype = SOCK_DGRAM; /*dummy*/
703 hints.ai_flags = AI_CANONNAME;
704 res = NULL;
705 error = getaddrinfo(remotehost, "0", &hints, &res);
706 if (error)
707 return (NULL);
708
709 for (r = res; r; r = r->ai_next) {
710 h2[0] = '\0';
711 if (getnameinfo(r->ai_addr, r->ai_addrlen, h2, sizeof(h2),
712 NULL, 0, niflags) != 0)
713 continue;
714 if (strcmp(h1, h2) == 0) {
715 freeaddrinfo(res);
716 return (remotehost);
717 }
718 }
719
720 /*
721 * either the DNS adminstrator has made a configuration
722 * mistake, or someone has attempted to spoof us
723 */
724 syslog(LOG_NOTICE, "rcmd: address %s not listed for host %s",
725 h1, res->ai_canonname ? res->ai_canonname : remotehost);
726 freeaddrinfo(res);
727 return (NULL);
728}
diff --git a/src/lib/libc/net/rcmdsh.3 b/src/lib/libc/net/rcmdsh.3
new file mode 100644
index 0000000000..be566f09ca
--- /dev/null
+++ b/src/lib/libc/net/rcmdsh.3
@@ -0,0 +1,96 @@
1.\" $OpenBSD: rcmdsh.3,v 1.11 2003/06/02 20:18:35 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. Neither the name of the University nor the names of its contributors
15.\" may be used to endorse or promote products derived from this software
16.\" without specific prior written permission.
17.\"
18.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28.\" SUCH DAMAGE.
29.\"
30.Dd May 5, 2003
31.Dt RCMDSH 3
32.Os
33.Sh NAME
34.Nm rcmdsh
35.Nd return a stream to a remote command without superuser
36.Sh SYNOPSIS
37.Fd #include <unistd.h>
38.Ft int
39.Fn rcmdsh "char **ahost" "int inport" "const char *locuser" "const char *remuser" "const char *cmd" "char *rshprog"
40.Sh DESCRIPTION
41The
42.Fn rcmdsh
43function is used by normal users to execute a command on a remote machine
44using an authentication scheme based on reserved port numbers using
45.Xr rsh 1
46or the value of
47.Fa rshprog
48(if non-null).
49.Fa rshprog
50may be a fully-qualified path, a non-qualified command, or a command containing
51space-separated command line arguments.
52.Pp
53The
54.Fn rcmdsh
55function looks up the host
56.Fa *ahost
57using
58.Xr gethostbyname 3 ,
59returning \-1 if the host does not exist.
60Otherwise
61.Fa *ahost
62is set to the standard name of the host and a connection is established to
63a server residing at the well-known Internet port
64.Li shell/tcp
65(or whatever port is used by
66.Fa rshprog ) .
67The parameter
68.Fa inport
69is ignored; it is only included to provide an interface similar to
70.Xr rcmd 3 .
71.Pp
72If the connection succeeds, a socket in the
73.Tn UNIX
74domain of type
75.Dv SOCK_STREAM
76is returned to the caller, and given to the remote
77command as stdin and stdout, and stderr.
78.Sh DIAGNOSTICS
79The
80.Fn rcmdsh
81function returns a valid socket descriptor on success.
82It returns \-1 on error and prints a diagnostic message on the standard error.
83.Sh SEE ALSO
84.Xr rsh 1 ,
85.Xr socketpair 2 ,
86.Xr rcmd 3 ,
87.Xr rshd 8
88.Sh HISTORY
89The
90.Fn rcmdsh
91function first appeared in
92.Ox 2.0 .
93.Sh BUGS
94If
95.Xr rsh 1
96encounters an error, a file descriptor is still returned instead of \-1.
diff --git a/src/lib/libc/net/rcmdsh.c b/src/lib/libc/net/rcmdsh.c
new file mode 100644
index 0000000000..3ec97e4763
--- /dev/null
+++ b/src/lib/libc/net/rcmdsh.c
@@ -0,0 +1,193 @@
1/* $OpenBSD: rcmdsh.c,v 1.9 2004/04/01 04:14:29 marc 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.9 2004/04/01 04:14:29 marc 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 <stdlib.h>
48#include <string.h>
49#include <pwd.h>
50#include <paths.h>
51#include <unistd.h>
52
53/*
54 * This is a replacement rcmd() function that uses the rsh(1)
55 * program in place of a direct rcmd(3) function call so as to
56 * avoid having to be root. Note that rport is ignored.
57 */
58/* ARGSUSED */
59int
60rcmdsh(ahost, rport, locuser, remuser, cmd, rshprog)
61 char **ahost;
62 int rport;
63 const char *locuser, *remuser, *cmd;
64 char *rshprog;
65{
66 struct hostent *hp;
67 int sp[2];
68 pid_t cpid;
69 char *p;
70 struct passwd *pw;
71
72 /* What rsh/shell to use. */
73 if (rshprog == NULL)
74 rshprog = _PATH_RSH;
75
76 /* locuser must exist on this host. */
77 if ((pw = getpwnam(locuser)) == NULL) {
78 (void) fprintf(stderr, "rcmdsh: unknown user: %s\n", locuser);
79 return(-1);
80 }
81
82 /* Validate remote hostname. */
83 if (strcmp(*ahost, "localhost") != 0) {
84 if (((hp = gethostbyname2(*ahost, AF_INET)) == NULL) &&
85 ((hp = gethostbyname2(*ahost, AF_INET6)) == NULL)) {
86 herror(*ahost);
87 return(-1);
88 }
89 *ahost = hp->h_name;
90 }
91
92 /* Get a socketpair we'll use for stdin and stdout. */
93 if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, sp) < 0) {
94 perror("rcmdsh: socketpair");
95 return(-1);
96 }
97
98 cpid = fork();
99 if (cpid < 0) {
100 perror("rcmdsh: fork failed");
101 return(-1);
102 } else if (cpid == 0) {
103 /*
104 * Child. We use sp[1] to be stdin/stdout, and close sp[0].
105 */
106 (void) close(sp[0]);
107 if (dup2(sp[1], 0) < 0 || dup2(0, 1) < 0) {
108 perror("rcmdsh: dup2 failed");
109 _exit(255);
110 }
111 /* Fork again to lose parent. */
112 cpid = fork();
113 if (cpid < 0) {
114 perror("rcmdsh: fork to lose parent failed");
115 _exit(255);
116 }
117 if (cpid > 0)
118 _exit(0);
119
120 /* In grandchild here. Become local user for rshprog. */
121 if (setuid(pw->pw_uid)) {
122 (void) fprintf(stderr, "rcmdsh: setuid(%u): %s\n",
123 pw->pw_uid, strerror(errno));
124 _exit(255);
125 }
126
127 /*
128 * If remote host is "localhost" and local and remote user
129 * are the same, avoid running remote shell for efficiency.
130 */
131 if (!strcmp(*ahost, "localhost") && !strcmp(locuser, remuser)) {
132 char *argv[4];
133 if (pw->pw_shell[0] == '\0')
134 rshprog = _PATH_BSHELL;
135 else
136 rshprog = pw->pw_shell;
137 p = strrchr(rshprog, '/');
138 argv[0] = p ? p + 1 : rshprog;
139 argv[1] = "-c";
140 argv[2] = (char *)cmd;
141 argv[3] = NULL;
142 execvp(rshprog, argv);
143 } else if ((p = strchr(rshprog, ' ')) == NULL) {
144 /* simple case */
145 char *argv[6];
146 p = strrchr(rshprog, '/');
147 argv[0] = p ? p + 1 : rshprog;
148 argv[1] = "-l";
149 argv[2] = (char *)remuser;
150 argv[3] = *ahost;
151 argv[4] = (char *)cmd;
152 argv[5] = NULL;
153 execvp(rshprog, argv);
154 } else {
155 /* must pull args out of rshprog and dyn alloc argv */
156 char **argv, **ap;
157 int n;
158 for (n = 7; (p = strchr(++p, ' ')) != NULL; n++)
159 continue;
160 rshprog = strdup(rshprog);
161 ap = argv = malloc(sizeof(char *) * n);
162 if (rshprog == NULL || argv == NULL) {
163 perror("rcmdsh");
164 _exit(255);
165 }
166 while ((p = strsep(&rshprog, " ")) != NULL) {
167 if (*p == '\0')
168 continue;
169 *ap++ = p;
170 }
171 if (ap != argv) /* all spaces?!? */
172 rshprog = argv[0];
173 if ((p = strrchr(argv[0], '/')) != NULL)
174 argv[0] = p + 1;
175 *ap++ = "-l";
176 *ap++ = (char *)remuser;
177 *ap++ = *ahost;
178 *ap++ = (char *)cmd;
179 *ap++ = NULL;
180 execvp(rshprog, argv);
181 }
182 (void) fprintf(stderr, "rcmdsh: execvp %s failed: %s\n",
183 rshprog, strerror(errno));
184 _exit(255);
185 } else {
186 /* Parent. close sp[1], return sp[0]. */
187 (void) close(sp[1]);
188 /* Reap child. */
189 (void) wait(NULL);
190 return(sp[0]);
191 }
192 /* NOTREACHED */
193}
diff --git a/src/lib/libc/net/recv.c b/src/lib/libc/net/recv.c
index 44296378cb..0947465377 100644
--- a/src/lib/libc/net/recv.c
+++ b/src/lib/libc/net/recv.c
@@ -1,5 +1,3 @@
1/* $NetBSD: recv.c,v 1.6 1995/02/25 06:20:54 cgd Exp $ */
2
3/* 1/*
4 * Copyright (c) 1988, 1993 2 * Copyright (c) 1988, 1993
5 * The Regents of the University of California. All rights reserved. 3 * The Regents of the University of California. All rights reserved.
@@ -12,11 +10,7 @@
12 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission. 15 * without specific prior written permission.
22 * 16 *
@@ -34,11 +28,7 @@
34 */ 28 */
35 29
36#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
37#if 0 31static char rcsid[] = "$OpenBSD: recv.c,v 1.3 2003/06/02 20:18:35 millert Exp $";
38static char sccsid[] = "@(#)recv.c 8.2 (Berkeley) 2/21/94";
39#else
40static char rcsid[] = "$NetBSD: recv.c,v 1.6 1995/02/25 06:20:54 cgd Exp $";
41#endif
42#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
43 33
44#include <sys/types.h> 34#include <sys/types.h>
diff --git a/src/lib/libc/net/res_comp.c b/src/lib/libc/net/res_comp.c
index 9d7bbecdda..c10eb52931 100644
--- a/src/lib/libc/net/res_comp.c
+++ b/src/lib/libc/net/res_comp.c
@@ -1,9 +1,11 @@
1/* $NetBSD: res_comp.c,v 1.6 1995/02/25 06:20:55 cgd Exp $ */ 1/* $OpenBSD: res_comp.c,v 1.11 2003/06/02 20:18:36 millert Exp $ */
2 2
3/*- 3/*
4 * ++Copyright++ 1985, 1993
5 * -
4 * Copyright (c) 1985, 1993 6 * Copyright (c) 1985, 1993
5 * The Regents of the University of California. All rights reserved. 7 * The Regents of the University of California. All rights reserved.
6 * 8 *
7 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
9 * are met: 11 * are met:
@@ -12,14 +14,10 @@
12 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 15 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 16 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 17 * 3. Neither the name of the University nor the names of its contributors
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 18 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission. 19 * without specific prior written permission.
22 * 20 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -56,19 +54,25 @@
56#if defined(LIBC_SCCS) && !defined(lint) 54#if defined(LIBC_SCCS) && !defined(lint)
57#if 0 55#if 0
58static char sccsid[] = "@(#)res_comp.c 8.1 (Berkeley) 6/4/93"; 56static char sccsid[] = "@(#)res_comp.c 8.1 (Berkeley) 6/4/93";
59static char rcsid[] = "$Id: res_comp.c,v 4.9.1.1 1993/05/02 22:43:03 vixie Rel "; 57static char rcsid[] = "$From: res_comp.c,v 8.11 1996/12/02 09:17:22 vixie Exp $";
60#else 58#else
61static char rcsid[] = "$NetBSD: res_comp.c,v 1.6 1995/02/25 06:20:55 cgd Exp $"; 59static char rcsid[] = "$OpenBSD: res_comp.c,v 1.11 2003/06/02 20:18:36 millert Exp $";
62#endif 60#endif
63#endif /* LIBC_SCCS and not lint */ 61#endif /* LIBC_SCCS and not lint */
64 62
63#include <sys/types.h>
65#include <sys/param.h> 64#include <sys/param.h>
66#include <arpa/nameser.h>
67#include <netinet/in.h> 65#include <netinet/in.h>
68#include <resolv.h> 66#include <arpa/nameser.h>
67
69#include <stdio.h> 68#include <stdio.h>
69#include <resolv.h>
70#include <ctype.h>
71
72#include <unistd.h>
73#include <string.h>
70 74
71static int dn_find(); 75static int dn_find(u_char *, u_char *, u_char **, u_char **);
72 76
73/* 77/*
74 * Expand compressed domain name 'comp_dn' to full domain name. 78 * Expand compressed domain name 'comp_dn' to full domain name.
@@ -77,23 +81,27 @@ static int dn_find();
77 * 'exp_dn' is a pointer to a buffer of size 'length' for the result. 81 * 'exp_dn' is a pointer to a buffer of size 'length' for the result.
78 * Return size of compressed name or -1 if there was an error. 82 * Return size of compressed name or -1 if there was an error.
79 */ 83 */
84int
80dn_expand(msg, eomorig, comp_dn, exp_dn, length) 85dn_expand(msg, eomorig, comp_dn, exp_dn, length)
81 const u_char *msg, *eomorig, *comp_dn; 86 const u_char *msg, *eomorig, *comp_dn;
82 u_char *exp_dn; 87 char *exp_dn;
83 int length; 88 int length;
84{ 89{
85 register u_char *cp, *dn; 90 register const u_char *cp;
91 register char *dn;
86 register int n, c; 92 register int n, c;
87 u_char *eom; 93 char *eom;
88 int len = -1, checked = 0; 94 int len = -1, checked = 0;
89 95
90 dn = exp_dn; 96 dn = exp_dn;
91 cp = (u_char *)comp_dn; 97 cp = comp_dn;
98 if (length > MAXHOSTNAMELEN-1)
99 length = MAXHOSTNAMELEN-1;
92 eom = exp_dn + length; 100 eom = exp_dn + length;
93 /* 101 /*
94 * fetch next label in domain name 102 * fetch next label in domain name
95 */ 103 */
96 while (n = *cp++) { 104 while ((n = *cp++)) {
97 /* 105 /*
98 * Check for indirection 106 * Check for indirection
99 */ 107 */
@@ -108,23 +116,23 @@ dn_expand(msg, eomorig, comp_dn, exp_dn, length)
108 return (-1); 116 return (-1);
109 checked += n + 1; 117 checked += n + 1;
110 while (--n >= 0) { 118 while (--n >= 0) {
111 if ((c = *cp++) == '.') { 119 if (((c = *cp++) == '.') || (c == '\\')) {
112 if (dn + n + 2 >= eom) 120 if (dn + n + 2 >= eom)
113 return (-1); 121 return (-1);
114 *dn++ = '\\'; 122 *dn++ = '\\';
115 } 123 }
116 *dn++ = c; 124 *dn++ = c;
117 if (cp >= eomorig) /* out of range */ 125 if (cp >= eomorig) /* out of range */
118 return(-1); 126 return (-1);
119 } 127 }
120 break; 128 break;
121 129
122 case INDIR_MASK: 130 case INDIR_MASK:
123 if (len < 0) 131 if (len < 0)
124 len = cp - comp_dn + 1; 132 len = cp - comp_dn + 1;
125 cp = (u_char *)msg + (((n & 0x3f) << 8) | (*cp & 0xff)); 133 cp = msg + (((n & 0x3f) << 8) | (*cp & 0xff));
126 if (cp < msg || cp >= eomorig) /* out of range */ 134 if (cp < msg || cp >= eomorig) /* out of range */
127 return(-1); 135 return (-1);
128 checked += 2; 136 checked += 2;
129 /* 137 /*
130 * Check for loops in the compressed name; 138 * Check for loops in the compressed name;
@@ -157,8 +165,9 @@ dn_expand(msg, eomorig, comp_dn, exp_dn, length)
157 * If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr' 165 * If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr'
158 * is NULL, we don't update the list. 166 * is NULL, we don't update the list.
159 */ 167 */
168int
160dn_comp(exp_dn, comp_dn, length, dnptrs, lastdnptr) 169dn_comp(exp_dn, comp_dn, length, dnptrs, lastdnptr)
161 const u_char *exp_dn; 170 const char *exp_dn;
162 u_char *comp_dn, **dnptrs, **lastdnptr; 171 u_char *comp_dn, **dnptrs, **lastdnptr;
163 int length; 172 int length;
164{ 173{
@@ -170,6 +179,7 @@ dn_comp(exp_dn, comp_dn, length, dnptrs, lastdnptr)
170 dn = (u_char *)exp_dn; 179 dn = (u_char *)exp_dn;
171 cp = comp_dn; 180 cp = comp_dn;
172 eob = cp + length; 181 eob = cp + length;
182 lpp = cpp = NULL;
173 if (dnptrs != NULL) { 183 if (dnptrs != NULL) {
174 if ((msg = *dnptrs++) != NULL) { 184 if ((msg = *dnptrs++) != NULL) {
175 for (cpp = dnptrs; *cpp != NULL; cpp++) 185 for (cpp = dnptrs; *cpp != NULL; cpp++)
@@ -235,13 +245,14 @@ dn_comp(exp_dn, comp_dn, length, dnptrs, lastdnptr)
235/* 245/*
236 * Skip over a compressed domain name. Return the size or -1. 246 * Skip over a compressed domain name. Return the size or -1.
237 */ 247 */
248int
238__dn_skipname(comp_dn, eom) 249__dn_skipname(comp_dn, eom)
239 const u_char *comp_dn, *eom; 250 const u_char *comp_dn, *eom;
240{ 251{
241 register u_char *cp; 252 register const u_char *cp;
242 register int n; 253 register int n;
243 254
244 cp = (u_char *)comp_dn; 255 cp = comp_dn;
245 while (cp < eom && (n = *cp++)) { 256 while (cp < eom && (n = *cp++)) {
246 /* 257 /*
247 * check for indirection 258 * check for indirection
@@ -259,10 +270,19 @@ __dn_skipname(comp_dn, eom)
259 break; 270 break;
260 } 271 }
261 if (cp > eom) 272 if (cp > eom)
262 return -1; 273 return (-1);
263 return (cp - comp_dn); 274 return (cp - comp_dn);
264} 275}
265 276
277static int
278mklower(ch)
279 register int ch;
280{
281 if (isascii(ch) && isupper(ch))
282 return (tolower(ch));
283 return (ch);
284}
285
266/* 286/*
267 * Search for expanded name from a list of previously compressed names. 287 * Search for expanded name from a list of previously compressed names.
268 * Return the offset from msg if found or -1. 288 * Return the offset from msg if found or -1.
@@ -281,7 +301,7 @@ dn_find(exp_dn, msg, dnptrs, lastdnptr)
281 for (cpp = dnptrs; cpp < lastdnptr; cpp++) { 301 for (cpp = dnptrs; cpp < lastdnptr; cpp++) {
282 dn = exp_dn; 302 dn = exp_dn;
283 sp = cp = *cpp; 303 sp = cp = *cpp;
284 while (n = *cp++) { 304 while ((n = *cp++)) {
285 /* 305 /*
286 * check for indirection 306 * check for indirection
287 */ 307 */
@@ -292,7 +312,7 @@ dn_find(exp_dn, msg, dnptrs, lastdnptr)
292 goto next; 312 goto next;
293 if (*dn == '\\') 313 if (*dn == '\\')
294 dn++; 314 dn++;
295 if (*dn++ != *cp++) 315 if (mklower(*dn++) != mklower(*cp++))
296 goto next; 316 goto next;
297 } 317 }
298 if ((n = *dn++) == '\0' && *cp == '\0') 318 if ((n = *dn++) == '\0' && *cp == '\0')
@@ -301,11 +321,12 @@ dn_find(exp_dn, msg, dnptrs, lastdnptr)
301 continue; 321 continue;
302 goto next; 322 goto next;
303 323
304 default: /* illegal type */
305 return (-1);
306
307 case INDIR_MASK: /* indirection */ 324 case INDIR_MASK: /* indirection */
308 cp = msg + (((n & 0x3f) << 8) | *cp); 325 cp = msg + (((n & 0x3f) << 8) | *cp);
326 break;
327
328 default: /* illegal type */
329 return (-1);
309 } 330 }
310 } 331 }
311 if (*dn == '\0') 332 if (*dn == '\0')
@@ -316,16 +337,124 @@ dn_find(exp_dn, msg, dnptrs, lastdnptr)
316} 337}
317 338
318/* 339/*
319 * Routines to insert/extract short/long's. Must account for byte 340 * Verify that a domain name uses an acceptable character set.
320 * order and non-alignment problems. This code at least has the 341 */
321 * advantage of being portable. 342
322 * 343/*
323 * used by sendmail. 344 * Note the conspicuous absence of ctype macros in these definitions. On
345 * non-ASCII hosts, we can't depend on string literals or ctype macros to
346 * tell us anything about network-format data. The rest of the BIND system
347 * is not careful about this, but for some reason, we're doing it right here.
324 */ 348 */
349#define PERIOD 0x2e
350#define hyphenchar(c) ((c) == 0x2d)
351#define bslashchar(c) ((c) == 0x5c)
352#define periodchar(c) ((c) == PERIOD)
353#define asterchar(c) ((c) == 0x2a)
354#define alphachar(c) (((c) >= 0x41 && (c) <= 0x5a) \
355 || ((c) >= 0x61 && (c) <= 0x7a))
356#define digitchar(c) ((c) >= 0x30 && (c) <= 0x39)
357
358#define borderchar(c) (alphachar(c) || digitchar(c))
359#define middlechar(c) (borderchar(c) || hyphenchar(c))
360#define domainchar(c) ((c) > 0x20 && (c) < 0x7f)
361
362int
363res_hnok(dn)
364 const char *dn;
365{
366 int pch = PERIOD, ch = *dn++;
325 367
326u_short 368 while (ch != '\0') {
369 int nch = *dn++;
370
371 if (periodchar(ch)) {
372 ;
373 } else if (periodchar(pch)) {
374 if (!borderchar(ch))
375 return (0);
376 } else if (periodchar(nch) || nch == '\0') {
377 if (!borderchar(ch))
378 return (0);
379 } else {
380 if (!middlechar(ch))
381 return (0);
382 }
383 pch = ch, ch = nch;
384 }
385 return (1);
386}
387
388/*
389 * hostname-like (A, MX, WKS) owners can have "*" as their first label
390 * but must otherwise be as a host name.
391 */
392int
393res_ownok(dn)
394 const char *dn;
395{
396 if (asterchar(dn[0])) {
397 if (periodchar(dn[1]))
398 return (res_hnok(dn+2));
399 if (dn[1] == '\0')
400 return (1);
401 }
402 return (res_hnok(dn));
403}
404
405/*
406 * SOA RNAMEs and RP RNAMEs can have any printable character in their first
407 * label, but the rest of the name has to look like a host name.
408 */
409int
410res_mailok(dn)
411 const char *dn;
412{
413 int ch, escaped = 0;
414
415 /* "." is a valid missing representation */
416 if (*dn == '\0')
417 return(1);
418
419 /* otherwise <label>.<hostname> */
420 while ((ch = *dn++) != '\0') {
421 if (!domainchar(ch))
422 return (0);
423 if (!escaped && periodchar(ch))
424 break;
425 if (escaped)
426 escaped = 0;
427 else if (bslashchar(ch))
428 escaped = 1;
429 }
430 if (periodchar(ch))
431 return (res_hnok(dn));
432 return(0);
433}
434
435/*
436 * This function is quite liberal, since RFC 1034's character sets are only
437 * recommendations.
438 */
439int
440res_dnok(dn)
441 const char *dn;
442{
443 int ch;
444
445 while ((ch = *dn++) != '\0')
446 if (!domainchar(ch))
447 return (0);
448 return (1);
449}
450
451/*
452 * Routines to insert/extract short/long's.
453 */
454
455u_int16_t
327_getshort(msgp) 456_getshort(msgp)
328 register u_char *msgp; 457 register const u_char *msgp;
329{ 458{
330 register u_int16_t u; 459 register u_int16_t u;
331 460
@@ -333,9 +462,21 @@ _getshort(msgp)
333 return (u); 462 return (u);
334} 463}
335 464
465#ifdef NeXT
466/*
467 * nExt machines have some funky library conventions, which we must maintain.
468 */
469u_int16_t
470res_getshort(msgp)
471 register const u_char *msgp;
472{
473 return (_getshort(msgp));
474}
475#endif
476
336u_int32_t 477u_int32_t
337_getlong(msgp) 478_getlong(msgp)
338 register u_char *msgp; 479 register const u_char *msgp;
339{ 480{
340 register u_int32_t u; 481 register u_int32_t u;
341 482
@@ -344,13 +485,7 @@ _getlong(msgp)
344} 485}
345 486
346void 487void
347#if defined(__STDC__) || defined(__cplusplus)
348__putshort(register u_int16_t s, register u_char *msgp) 488__putshort(register u_int16_t s, register u_char *msgp)
349#else
350__putshort(s, msgp)
351 register u_int16_t s;
352 register u_char *msgp;
353#endif
354{ 489{
355 PUTSHORT(s, msgp); 490 PUTSHORT(s, msgp);
356} 491}
diff --git a/src/lib/libc/net/res_data.c b/src/lib/libc/net/res_data.c
new file mode 100644
index 0000000000..967264bcb7
--- /dev/null
+++ b/src/lib/libc/net/res_data.c
@@ -0,0 +1,113 @@
1/* $OpenBSD: res_data.c,v 1.2 2003/06/02 20:18:36 millert 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. 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)
55#if 0
56static char rcsid[] = "$From: res_data.c,v 8.2 1996/08/05 08:31:35 vixie Exp $";
57#else
58static char rcsid[] = "$OpenBSD: res_data.c,v 1.2 2003/06/02 20:18:36 millert Exp $";
59#endif
60#endif /* LIBC_SCCS and not lint */
61
62#include <sys/types.h>
63#include <sys/param.h>
64#include <sys/socket.h>
65#include <sys/time.h>
66#include <netinet/in.h>
67#include <arpa/inet.h>
68#include <arpa/nameser.h>
69
70#include <stdio.h>
71#include <ctype.h>
72#include <resolv.h>
73#include <unistd.h>
74#include <stdlib.h>
75#include <string.h>
76
77const char *_res_opcodes[] = {
78 "QUERY",
79 "IQUERY",
80 "CQUERYM",
81 "CQUERYU", /* experimental */
82 "NOTIFY", /* experimental */
83 "5",
84 "6",
85 "7",
86 "8",
87 "UPDATEA",
88 "UPDATED",
89 "UPDATEDA",
90 "UPDATEM",
91 "UPDATEMA",
92 "ZONEINIT",
93 "ZONEREF",
94};
95
96const char *_res_resultcodes[] = {
97 "NOERROR",
98 "FORMERR",
99 "SERVFAIL",
100 "NXDOMAIN",
101 "NOTIMP",
102 "REFUSED",
103 "6",
104 "7",
105 "8",
106 "9",
107 "10",
108 "11",
109 "12",
110 "13",
111 "14",
112 "NOCHANGE",
113};
diff --git a/src/lib/libc/net/res_debug.c b/src/lib/libc/net/res_debug.c
index d841293f18..8f66c7d009 100644
--- a/src/lib/libc/net/res_debug.c
+++ b/src/lib/libc/net/res_debug.c
@@ -1,9 +1,11 @@
1/* $NetBSD: res_debug.c,v 1.7 1995/02/25 06:20:56 cgd Exp $ */ 1/* $OpenBSD: res_debug.c,v 1.17 2003/06/02 20:18:36 millert Exp $ */
2 2
3/*- 3/*
4 * ++Copyright++ 1985, 1990, 1993
5 * -
4 * Copyright (c) 1985, 1990, 1993 6 * Copyright (c) 1985, 1990, 1993
5 * The Regents of the University of California. All rights reserved. 7 * The Regents of the University of California. All rights reserved.
6 * 8 *
7 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
9 * are met: 11 * are met:
@@ -12,11 +14,7 @@
12 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 15 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 16 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 17 * 3. Neither the name of the University nor the names of its contributors
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 18 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission. 19 * without specific prior written permission.
22 * 20 *
@@ -50,174 +48,194 @@
50 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 48 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
51 * SOFTWARE. 49 * SOFTWARE.
52 * - 50 * -
51 * Portions Copyright (c) 1995 by International Business Machines, Inc.
52 *
53 * International Business Machines, Inc. (hereinafter called IBM) grants
54 * permission under its copyrights to use, copy, modify, and distribute this
55 * Software with or without fee, provided that the above copyright notice and
56 * all paragraphs of this notice appear in all copies, and that the name of IBM
57 * not be used in connection with the marketing of any product incorporating
58 * the Software or modifications thereof, without specific, written prior
59 * permission.
60 *
61 * To the extent it has a right to do so, IBM grants an immunity from suit
62 * under its patents, if any, for the use, sale or manufacture of products to
63 * the extent that such products are used for performing Domain Name System
64 * dynamic updates in TCP/IP networks by means of the Software. No immunity is
65 * granted for any product per se or for any other function of any product.
66 *
67 * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
68 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
69 * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
70 * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
71 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
72 * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
53 * --Copyright-- 73 * --Copyright--
54 */ 74 */
55 75
56#if defined(LIBC_SCCS) && !defined(lint) 76#if defined(LIBC_SCCS) && !defined(lint)
57#if 0 77#if 0
58static char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93"; 78static char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93";
79static char rcsid[] = "$From: res_debug.c,v 8.19 1996/11/26 10:11:23 vixie Exp $";
59#else 80#else
60static char rcsid[] = "$NetBSD: res_debug.c,v 1.7 1995/02/25 06:20:56 cgd Exp $"; 81static char rcsid[] = "$OpenBSD: res_debug.c,v 1.17 2003/06/02 20:18:36 millert Exp $";
61#endif 82#endif
62#endif /* LIBC_SCCS and not lint */ 83#endif /* LIBC_SCCS and not lint */
63 84
64#include <sys/param.h> 85#include <sys/param.h>
86#include <sys/types.h>
87#include <sys/socket.h>
65#include <netinet/in.h> 88#include <netinet/in.h>
66#include <arpa/inet.h> 89#include <arpa/inet.h>
67#include <arpa/nameser.h> 90#include <arpa/nameser.h>
91
92#include <ctype.h>
93#include <netdb.h>
68#include <resolv.h> 94#include <resolv.h>
69#include <stdio.h> 95#include <stdio.h>
96#include <time.h>
97
98#include <stdlib.h>
70#include <string.h> 99#include <string.h>
71 100
72void __fp_query(); 101#include "thread_private.h"
73char *__p_class(), *__p_time(), *__p_type();
74char *p_cdname(), *p_fqname(), *p_rr();
75static char *p_option __P((u_int32_t));
76
77char *_res_opcodes[] = {
78 "QUERY",
79 "IQUERY",
80 "CQUERYM",
81 "CQUERYU",
82 "4",
83 "5",
84 "6",
85 "7",
86 "8",
87 "UPDATEA",
88 "UPDATED",
89 "UPDATEDA",
90 "UPDATEM",
91 "UPDATEMA",
92 "ZONEINIT",
93 "ZONEREF",
94};
95 102
96char *_res_resultcodes[] = { 103extern const char *_res_opcodes[];
97 "NOERROR", 104extern const char *_res_resultcodes[];
98 "FORMERR",
99 "SERVFAIL",
100 "NXDOMAIN",
101 "NOTIMP",
102 "REFUSED",
103 "6",
104 "7",
105 "8",
106 "9",
107 "10",
108 "11",
109 "12",
110 "13",
111 "14",
112 "NOCHANGE",
113};
114 105
115static char retbuf[16]; 106static const char *loc_ntoal(const u_char *binary, char *ascii, int ascii_len);
116 107
117static char * 108/* XXX: we should use getservbyport() instead. */
109static const char *
118dewks(wks) 110dewks(wks)
119 int wks; 111 int wks;
120{ 112{
113 static char nbuf[20];
114
121 switch (wks) { 115 switch (wks) {
122 case 5: return("rje"); 116 case 5: return "rje";
123 case 7: return("echo"); 117 case 7: return "echo";
124 case 9: return("discard"); 118 case 9: return "discard";
125 case 11: return("systat"); 119 case 11: return "systat";
126 case 13: return("daytime"); 120 case 13: return "daytime";
127 case 15: return("netstat"); 121 case 15: return "netstat";
128 case 17: return("qotd"); 122 case 17: return "qotd";
129 case 19: return("chargen"); 123 case 19: return "chargen";
130 case 20: return("ftp-data"); 124 case 20: return "ftp-data";
131 case 21: return("ftp"); 125 case 21: return "ftp";
132 case 23: return("telnet"); 126 case 23: return "telnet";
133 case 25: return("smtp"); 127 case 25: return "smtp";
134 case 37: return("time"); 128 case 37: return "time";
135 case 39: return("rlp"); 129 case 39: return "rlp";
136 case 42: return("name"); 130 case 42: return "name";
137 case 43: return("whois"); 131 case 43: return "whois";
138 case 53: return("domain"); 132 case 53: return "domain";
139 case 57: return("apts"); 133 case 57: return "apts";
140 case 59: return("apfs"); 134 case 59: return "apfs";
141 case 67: return("bootps"); 135 case 67: return "bootps";
142 case 68: return("bootpc"); 136 case 68: return "bootpc";
143 case 69: return("tftp"); 137 case 69: return "tftp";
144 case 77: return("rje"); 138 case 77: return "rje";
145 case 79: return("finger"); 139 case 79: return "finger";
146 case 87: return("link"); 140 case 87: return "link";
147 case 95: return("supdup"); 141 case 95: return "supdup";
148 case 100: return("newacct"); 142 case 100: return "newacct";
149 case 101: return("hostnames"); 143 case 101: return "hostnames";
150 case 102: return("iso-tsap"); 144 case 102: return "iso-tsap";
151 case 103: return("x400"); 145 case 103: return "x400";
152 case 104: return("x400-snd"); 146 case 104: return "x400-snd";
153 case 105: return("csnet-ns"); 147 case 105: return "csnet-ns";
154 case 109: return("pop-2"); 148 case 109: return "pop-2";
155 case 111: return("sunrpc"); 149 case 111: return "sunrpc";
156 case 113: return("auth"); 150 case 113: return "auth";
157 case 115: return("sftp"); 151 case 115: return "sftp";
158 case 117: return("uucp-path"); 152 case 117: return "uucp-path";
159 case 119: return("nntp"); 153 case 119: return "nntp";
160 case 121: return("erpc"); 154 case 121: return "erpc";
161 case 123: return("ntp"); 155 case 123: return "ntp";
162 case 133: return("statsrv"); 156 case 133: return "statsrv";
163 case 136: return("profile"); 157 case 136: return "profile";
164 case 144: return("NeWS"); 158 case 144: return "NeWS";
165 case 161: return("snmp"); 159 case 161: return "snmp";
166 case 162: return("snmp-trap"); 160 case 162: return "snmp-trap";
167 case 170: return("print-srv"); 161 case 170: return "print-srv";
168 default: (void) sprintf(retbuf, "%d", wks); return(retbuf); 162 default:
163 (void) snprintf(nbuf, sizeof nbuf, "%d", wks);
164 return (nbuf);
169 } 165 }
170} 166}
171 167
172static char * 168/* XXX: we should use getprotobynumber() instead. */
169static const char *
173deproto(protonum) 170deproto(protonum)
174 int protonum; 171 int protonum;
175{ 172{
173 static char nbuf[20];
174
176 switch (protonum) { 175 switch (protonum) {
177 case 1: return("icmp"); 176 case 1: return "icmp";
178 case 2: return("igmp"); 177 case 2: return "igmp";
179 case 3: return("ggp"); 178 case 3: return "ggp";
180 case 5: return("st"); 179 case 5: return "st";
181 case 6: return("tcp"); 180 case 6: return "tcp";
182 case 7: return("ucl"); 181 case 7: return "ucl";
183 case 8: return("egp"); 182 case 8: return "egp";
184 case 9: return("igp"); 183 case 9: return "igp";
185 case 11: return("nvp-II"); 184 case 11: return "nvp-II";
186 case 12: return("pup"); 185 case 12: return "pup";
187 case 16: return("chaos"); 186 case 16: return "chaos";
188 case 17: return("udp"); 187 case 17: return "udp";
189 default: (void) sprintf(retbuf, "%d", protonum); return(retbuf); 188 default:
189 (void) snprintf(nbuf, sizeof nbuf, "%d", protonum);
190 return (nbuf);
190 } 191 }
191} 192}
192 193
193static char * 194static const u_char *
194do_rrset(msg, cp, cnt, pflag, file, hs) 195do_rrset(msg, len, cp, cnt, pflag, file, hs)
195 int cnt, pflag; 196 int cnt, pflag, len;
196 char *cp,*msg, *hs; 197 const u_char *cp, *msg;
198 const char *hs;
197 FILE *file; 199 FILE *file;
198{ 200{
201 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
199 int n; 202 int n;
200 int sflag; 203 int sflag;
204
201 /* 205 /*
202 * Print answer records 206 * Print answer records.
203 */ 207 */
204 sflag = (_res.pfcode & pflag); 208 sflag = (_resp->pfcode & pflag);
205 if (n = ntohs(cnt)) { 209 if ((n = ntohs(cnt))) {
206 if ((!_res.pfcode) || ((sflag) && (_res.pfcode & RES_PRF_HEAD1))) 210 if ((!_resp->pfcode) ||
207 fprintf(file, hs); 211 ((sflag) && (_resp->pfcode & RES_PRF_HEAD1)))
212 fprintf(file, "%s", hs);
208 while (--n >= 0) { 213 while (--n >= 0) {
209 cp = p_rr(cp, msg, file); 214 if ((!_resp->pfcode) || sflag) {
210 if ((cp-msg) > PACKETSZ) 215 cp = p_rr(cp, msg, file);
216 } else {
217 unsigned int dlen;
218 cp += __dn_skipname(cp, cp + MAXCDNAME);
219 cp += INT16SZ;
220 cp += INT16SZ;
221 cp += INT32SZ;
222 dlen = _getshort((u_char*)cp);
223 cp += INT16SZ;
224 cp += dlen;
225 }
226 if ((cp - msg) > len)
211 return (NULL); 227 return (NULL);
212 } 228 }
213 if ((!_res.pfcode) || ((sflag) && (_res.pfcode & RES_PRF_HEAD1))) 229 if ((!_resp->pfcode) ||
230 ((sflag) && (_resp->pfcode & RES_PRF_HEAD1)))
214 putc('\n', file); 231 putc('\n', file);
215 } 232 }
216 return(cp); 233 return (cp);
217} 234}
218 235
236void
219__p_query(msg) 237__p_query(msg)
220 char *msg; 238 const u_char *msg;
221{ 239{
222 __fp_query(msg, stdout); 240 __fp_query(msg, stdout);
223} 241}
@@ -231,15 +249,14 @@ __fp_resstat(statp, file)
231 struct __res_state *statp; 249 struct __res_state *statp;
232 FILE *file; 250 FILE *file;
233{ 251{
234 int bit; 252 register u_long mask;
235 253
236 fprintf(file, ";; res options:"); 254 fprintf(file, ";; res options:");
237 if (!statp) 255 if (!statp)
238 statp = &_res; 256 statp = &_res;
239 for (bit = 0; bit < 32; bit++) { /* XXX 32 - bad assumption! */ 257 for (mask = 1; mask != 0; mask <<= 1)
240 if (statp->options & (1<<bit)) 258 if (statp->options & mask)
241 fprintf(file, " %s", p_option(1<<bit)); 259 fprintf(file, " %s", p_option(mask));
242 }
243 putc('\n', file); 260 putc('\n', file);
244} 261}
245 262
@@ -248,109 +265,152 @@ __fp_resstat(statp, file)
248 * This is intended to be primarily a debugging routine. 265 * This is intended to be primarily a debugging routine.
249 */ 266 */
250void 267void
251__fp_query(msg,file) 268__fp_nquery(msg, len, file)
252 char *msg; 269 const u_char *msg;
270 int len;
253 FILE *file; 271 FILE *file;
254{ 272{
255 register char *cp; 273 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
256 register HEADER *hp; 274 register const u_char *cp, *endMark;
275 register const HEADER *hp;
257 register int n; 276 register int n;
258 277
278 if ((_resp->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
259 /* 284 /*
260 * Print header fields. 285 * Print header fields.
261 */ 286 */
262 hp = (HEADER *)msg; 287 hp = (HEADER *)msg;
263 cp = msg + sizeof(HEADER); 288 cp = msg + HFIXEDSZ;
264 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX) || hp->rcode) { 289 endMark = msg + len;
265 fprintf(file,";; ->>HEADER<<- opcode: %s, status: %s, id: %d", 290 if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_HEADX) || hp->rcode) {
291 fprintf(file, ";; ->>HEADER<<- opcode: %s, status: %s, id: %u",
266 _res_opcodes[hp->opcode], 292 _res_opcodes[hp->opcode],
267 _res_resultcodes[hp->rcode], 293 _res_resultcodes[hp->rcode],
268 ntohs(hp->id)); 294 ntohs(hp->id));
269 putc('\n', file); 295 putc('\n', file);
270 } 296 }
271 putc(';', file); 297 if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_HEADX))
272 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD2)) { 298 putc(';', file);
273 fprintf(file,"; flags:"); 299 if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_HEAD2)) {
300 fprintf(file, "; flags:");
274 if (hp->qr) 301 if (hp->qr)
275 fprintf(file," qr"); 302 fprintf(file, " qr");
276 if (hp->aa) 303 if (hp->aa)
277 fprintf(file," aa"); 304 fprintf(file, " aa");
278 if (hp->tc) 305 if (hp->tc)
279 fprintf(file," tc"); 306 fprintf(file, " tc");
280 if (hp->rd) 307 if (hp->rd)
281 fprintf(file," rd"); 308 fprintf(file, " rd");
282 if (hp->ra) 309 if (hp->ra)
283 fprintf(file," ra"); 310 fprintf(file, " ra");
284 if (hp->pr) 311 if (hp->unused)
285 fprintf(file," pr"); 312 fprintf(file, " UNUSED-BIT-ON");
313 if (hp->ad)
314 fprintf(file, " ad");
315 if (hp->cd)
316 fprintf(file, " cd");
286 } 317 }
287 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD1)) { 318 if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_HEAD1)) {
288 fprintf(file,"; Ques: %d", ntohs(hp->qdcount)); 319 fprintf(file, "; Ques: %u", ntohs(hp->qdcount));
289 fprintf(file,", Ans: %d", ntohs(hp->ancount)); 320 fprintf(file, ", Ans: %u", ntohs(hp->ancount));
290 fprintf(file,", Auth: %d", ntohs(hp->nscount)); 321 fprintf(file, ", Auth: %u", ntohs(hp->nscount));
291 fprintf(file,", Addit: %d\n", ntohs(hp->arcount)); 322 fprintf(file, ", Addit: %u", ntohs(hp->arcount));
292 } 323 }
293#if 0 324 if ((!_resp->pfcode) || (_resp->pfcode &
294 if (_res.pfcode & (RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1)) { 325 (RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1))) {
295 putc('\n',file); 326 putc('\n',file);
296 } 327 }
297#endif
298 /* 328 /*
299 * Print question records. 329 * Print question records.
300 */ 330 */
301 if (n = ntohs(hp->qdcount)) { 331 if ((n = ntohs(hp->qdcount))) {
302 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) 332 if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_QUES))
303 fprintf(file,";; QUESTIONS:\n"); 333 fprintf(file, ";; QUESTIONS:\n");
304 while (--n >= 0) { 334 while (--n >= 0) {
305 fprintf(file,";;\t"); 335 if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_QUES))
306 cp = p_cdname(cp, msg, file); 336 fprintf(file, ";;\t");
307 if (cp == NULL) 337 TruncTest(cp);
308 return; 338 if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_QUES))
309 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 ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_QUES))
310 fprintf(file, ", type = %s", 353 fprintf(file, ", type = %s",
311 __p_type(_getshort(cp))); 354 __p_type(_getshort((u_char*)cp)));
312 cp += sizeof(u_int16_t); 355 cp += INT16SZ;
313 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) 356 TruncTest(cp);
314 fprintf(file, ", class = %s\n\n", 357 if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_QUES))
315 __p_class(_getshort(cp))); 358 fprintf(file, ", class = %s\n",
316 cp += sizeof(u_int16_t); 359 __p_class(_getshort((u_char*)cp)));
360 cp += INT16SZ;
361 if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_QUES))
362 putc('\n', file);
317 } 363 }
318 } 364 }
319 /* 365 /*
320 * Print authoritative answer records 366 * Print authoritative answer records
321 */ 367 */
322 cp = do_rrset(msg, cp, hp->ancount, RES_PRF_ANS, file, 368 TruncTest(cp);
369 cp = do_rrset(msg, len, cp, hp->ancount, RES_PRF_ANS, file,
323 ";; ANSWERS:\n"); 370 ";; ANSWERS:\n");
324 if (cp == NULL) 371 ErrorTest(cp);
325 return;
326 372
327 /* 373 /*
328 * print name server records 374 * print name server records
329 */ 375 */
330 cp = do_rrset(msg, cp, hp->nscount, RES_PRF_AUTH, file, 376 TruncTest(cp);
377 cp = do_rrset(msg, len, cp, hp->nscount, RES_PRF_AUTH, file,
331 ";; AUTHORITY RECORDS:\n"); 378 ";; AUTHORITY RECORDS:\n");
332 if (!cp) 379 ErrorTest(cp);
333 return;
334 380
381 TruncTest(cp);
335 /* 382 /*
336 * print additional records 383 * print additional records
337 */ 384 */
338 cp = do_rrset(msg, cp, hp->arcount, RES_PRF_ADD, file, 385 cp = do_rrset(msg, len, cp, hp->arcount, RES_PRF_ADD, file,
339 ";; ADDITIONAL RECORDS:\n"); 386 ";; ADDITIONAL RECORDS:\n");
340 if (!cp) 387 ErrorTest(cp);
341 return; 388 return;
389 trunc:
390 fprintf(file, "\n;; ...truncated\n");
391 return;
392 error:
393 fprintf(file, "\n;; ...malformed\n");
342} 394}
343 395
344char * 396void
345p_cdname(cp, msg, file) 397__fp_query(msg, file)
346 char *cp, *msg; 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;
347 FILE *file; 408 FILE *file;
348{ 409{
349 char name[MAXDNAME]; 410 char name[MAXDNAME];
350 int n; 411 int n;
351 412
352 if ((n = dn_expand((u_char *)msg, (u_char *)cp + MAXCDNAME, 413 if ((n = dn_expand(msg, msg + len, cp, name, sizeof name)) < 0)
353 (u_char *)cp, (u_char *)name, sizeof(name))) < 0)
354 return (NULL); 414 return (NULL);
355 if (name[0] == '\0') 415 if (name[0] == '\0')
356 putc('.', file); 416 putc('.', file);
@@ -359,55 +419,96 @@ p_cdname(cp, msg, file)
359 return (cp + n); 419 return (cp + n);
360} 420}
361 421
362char * 422const u_char *
363p_fqname(cp, msg, file) 423__p_cdname(cp, msg, file)
364 char *cp, *msg; 424 const u_char *cp, *msg;
365 FILE *file; 425 FILE *file;
366{ 426{
367 char name[MAXDNAME]; 427 return (p_cdnname(cp, msg, PACKETSZ, file));
368 int n, len; 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;
369 442
370 if ((n = dn_expand((u_char *)msg, (u_char *)cp + MAXCDNAME, 443 if ((n = dn_expand(msg, cp + msglen, cp, name, namelen)) < 0)
371 (u_char *)cp, (u_char *)name, sizeof(name))) < 0)
372 return (NULL); 444 return (NULL);
373 if (name[0] == '\0') { 445 newlen = strlen(name);
374 putc('.', file); 446 if (newlen == 0 || name[newlen - 1] != '.') {
375 } else { 447 if (newlen + 1 >= namelen) /* Lack space for final dot */
376 fputs(name, file); 448 return (NULL);
377 if (name[strlen(name) - 1] != '.') 449 else
378 putc('.', file); 450 strlcpy(name + newlen, ".", namelen - newlen);
379 } 451 }
380 return (cp + n); 452 return (cp + n);
381} 453}
382 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
383/* 473/*
384 * Print resource record fields in human readable form. 474 * Print resource record fields in human readable form.
385 */ 475 */
386char * 476const u_char *
387p_rr(cp, msg, file) 477__p_rr(cp, msg, file)
388 char *cp, *msg; 478 const u_char *cp, *msg;
389 FILE *file; 479 FILE *file;
390{ 480{
481 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
391 int type, class, dlen, n, c; 482 int type, class, dlen, n, c;
392 struct in_addr inaddr; 483 struct in_addr inaddr;
393 char *cp1, *cp2; 484 const u_char *cp1, *cp2;
394 u_int32_t tmpttl, t; 485 u_int32_t tmpttl, t;
395 int lcnt; 486 int lcnt;
487 u_int16_t keyflags;
488 char rrname[MAXDNAME]; /* The fqdn of this RR */
489 char base64_key[MAX_KEY_BASE64];
396 490
397 if ((cp = p_fqname(cp, msg, file)) == NULL) 491 if ((_resp->options & RES_INIT) == 0 && res_init() == -1) {
492 h_errno = NETDB_INTERNAL;
493 return (NULL);
494 }
495 cp = __p_fqnname(cp, msg, MAXCDNAME, rrname, sizeof rrname);
496 if (!cp)
398 return (NULL); /* compression error */ 497 return (NULL); /* compression error */
399 type = _getshort(cp); 498 fputs(rrname, file);
400 cp += sizeof(u_int16_t); 499
401 class = _getshort(cp); 500 type = _getshort((u_char*)cp);
402 cp += sizeof(u_int16_t); 501 cp += INT16SZ;
403 tmpttl = _getlong(cp); 502 class = _getshort((u_char*)cp);
404 cp += sizeof(u_int32_t); 503 cp += INT16SZ;
405 dlen = _getshort(cp); 504 tmpttl = _getlong((u_char*)cp);
406 cp += sizeof(u_int16_t); 505 cp += INT32SZ;
506 dlen = _getshort((u_char*)cp);
507 cp += INT16SZ;
407 cp1 = cp; 508 cp1 = cp;
408 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_TTLID)) 509 if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_TTLID))
409 fprintf(file, "\t%lu", tmpttl); 510 fprintf(file, "\t%lu", (u_long)tmpttl);
410 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_CLASS)) 511 if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_CLASS))
411 fprintf(file, "\t%s", __p_class(class)); 512 fprintf(file, "\t%s", __p_class(class));
412 fprintf(file, "\t%s", __p_type(type)); 513 fprintf(file, "\t%s", __p_type(type));
413 /* 514 /*
@@ -418,22 +519,22 @@ p_rr(cp, msg, file)
418 switch (class) { 519 switch (class) {
419 case C_IN: 520 case C_IN:
420 case C_HS: 521 case C_HS:
421 bcopy(cp, (char *)&inaddr, sizeof(inaddr)); 522 bcopy(cp, (char *)&inaddr, INADDRSZ);
422 if (dlen == 4) { 523 if (dlen == 4) {
423 fprintf(file,"\t%s", inet_ntoa(inaddr)); 524 fprintf(file, "\t%s", inet_ntoa(inaddr));
424 cp += dlen; 525 cp += dlen;
425 } else if (dlen == 7) { 526 } else if (dlen == 7) {
426 char *address; 527 char *address;
427 u_char protocol; 528 u_char protocol;
428 u_short port; 529 in_port_t port;
429 530
430 address = inet_ntoa(inaddr); 531 address = inet_ntoa(inaddr);
431 cp += sizeof(inaddr); 532 cp += INADDRSZ;
432 protocol = *(u_char*)cp; 533 protocol = *(u_char*)cp;
433 cp += sizeof(u_char); 534 cp += sizeof (u_char);
434 port = _getshort(cp); 535 port = _getshort((u_char*)cp);
435 cp += sizeof(u_int16_t); 536 cp += INT16SZ;
436 fprintf(file, "\t%s\t; proto %d, port %d", 537 fprintf(file, "\t%s\t; proto %u, port %u",
437 address, protocol, port); 538 address, protocol, port);
438 } 539 }
439 break; 540 break;
@@ -448,98 +549,205 @@ p_rr(cp, msg, file)
448 case T_NS: 549 case T_NS:
449 case T_PTR: 550 case T_PTR:
450 putc('\t', file); 551 putc('\t', file);
451 cp = p_fqname(cp, msg, file); 552 if ((cp = p_fqname(cp, msg, file)) == NULL)
553 return (NULL);
452 break; 554 break;
453 555
454 case T_HINFO: 556 case T_HINFO:
455 if (n = *cp++) { 557 case T_ISDN:
456 fprintf(file,"\t%.*s", n, cp); 558 cp2 = cp + dlen;
457 cp += n; 559 (void) fputs("\t\"", file);
560 if ((n = (unsigned char) *cp++) != 0) {
561 for (c = n; c > 0 && cp < cp2; c--) {
562 if (strchr("\n\"\\", *cp))
563 (void) putc('\\', file);
564 (void) putc(*cp++, file);
565 }
458 } 566 }
459 if (n = *cp++) { 567 putc('"', file);
460 fprintf(file,"\t%.*s", n, cp); 568 if (cp < cp2 && (n = (unsigned char) *cp++) != 0) {
461 cp += n; 569 (void) fputs ("\t\"", file);
570 for (c = n; c > 0 && cp < cp2; c--) {
571 if (strchr("\n\"\\", *cp))
572 (void) putc('\\', file);
573 (void) putc(*cp++, file);
574 }
575 putc('"', file);
576 } else if (type == T_HINFO) {
577 (void) fputs("\"?\"", file);
578 fprintf(file, "\n;; *** Warning *** OS-type missing");
462 } 579 }
463 break; 580 break;
464 581
465 case T_SOA: 582 case T_SOA:
466 putc('\t', file); 583 putc('\t', file);
467 cp = p_fqname(cp, msg, file); /* origin */ 584 if ((cp = p_fqname(cp, msg, file)) == NULL)
585 return (NULL);
468 putc(' ', file); 586 putc(' ', file);
469 cp = p_fqname(cp, msg, file); /* mail addr */ 587 if ((cp = p_fqname(cp, msg, file)) == NULL)
588 return (NULL);
470 fputs(" (\n", file); 589 fputs(" (\n", file);
471 t = _getlong(cp); cp += sizeof(u_int32_t); 590 t = _getlong((u_char*)cp); cp += INT32SZ;
472 fprintf(file,"\t\t\t%lu\t; serial\n", t); 591 fprintf(file, "\t\t\t%lu\t; serial\n", (u_long)t);
473 t = _getlong(cp); cp += sizeof(u_int32_t); 592 t = _getlong((u_char*)cp); cp += INT32SZ;
474 fprintf(file,"\t\t\t%lu\t; refresh (%s)\n", t, __p_time(t)); 593 fprintf(file, "\t\t\t%lu\t; refresh (%s)\n",
475 t = _getlong(cp); cp += sizeof(u_int32_t); 594 (u_long)t, __p_time(t));
476 fprintf(file,"\t\t\t%lu\t; retry (%s)\n", t, __p_time(t)); 595 t = _getlong((u_char*)cp); cp += INT32SZ;
477 t = _getlong(cp); cp += sizeof(u_int32_t); 596 fprintf(file, "\t\t\t%lu\t; retry (%s)\n",
478 fprintf(file,"\t\t\t%lu\t; expire (%s)\n", t, __p_time(t)); 597 (u_long)t, __p_time(t));
479 t = _getlong(cp); cp += sizeof(u_int32_t); 598 t = _getlong((u_char*)cp); cp += INT32SZ;
480 fprintf(file,"\t\t\t%lu )\t; minimum (%s)", t, __p_time(t)); 599 fprintf(file, "\t\t\t%lu\t; expire (%s)\n",
600 (u_long)t, __p_time(t));
601 t = _getlong((u_char*)cp); cp += INT32SZ;
602 fprintf(file, "\t\t\t%lu )\t; minimum (%s)",
603 (u_long)t, __p_time(t));
481 break; 604 break;
482 605
483 case T_MX: 606 case T_MX:
484 case T_AFSDB: 607 case T_AFSDB:
485 fprintf(file,"\t%d ", _getshort(cp)); 608 case T_RT:
486 cp += sizeof(u_int16_t); 609 fprintf(file, "\t%u ", _getshort((u_char*)cp));
487 cp = p_fqname(cp, msg, file); 610 cp += INT16SZ;
611 if ((cp = p_fqname(cp, msg, file)) == NULL)
612 return (NULL);
488 break; 613 break;
489 614
490 case T_TXT: 615 case T_PX:
616 fprintf(file, "\t%u ", _getshort((u_char*)cp));
617 cp += INT16SZ;
618 if ((cp = p_fqname(cp, msg, file)) == NULL)
619 return (NULL);
620 putc(' ', file);
621 if ((cp = p_fqname(cp, msg, file)) == NULL)
622 return (NULL);
623 break;
624
625 case T_X25:
626 cp2 = cp + dlen;
491 (void) fputs("\t\"", file); 627 (void) fputs("\t\"", file);
628 if ((n = (unsigned char) *cp++) != 0) {
629 for (c = n; c > 0 && cp < cp2; c--) {
630 if (strchr("\n\"\\", *cp))
631 (void) putc('\\', file);
632 (void) putc(*cp++, file);
633 }
634 }
635 putc('"', file);
636 break;
637
638 case T_TXT:
639 (void) putc('\t', file);
492 cp2 = cp1 + dlen; 640 cp2 = cp1 + dlen;
493 while (cp < cp2) { 641 while (cp < cp2) {
494 if (n = (unsigned char) *cp++) { 642 putc('"', file);
495 for (c = n; c > 0 && cp < cp2; c--) 643 if ((n = (unsigned char) *cp++)) {
496 if (*cp == '\n') { 644 for (c = n; c > 0 && cp < cp2; c--) {
497 (void) putc('\\', file); 645 if (strchr("\n\"\\", *cp))
498 (void) putc(*cp++, file); 646 (void) putc('\\', file);
499 } else 647 (void) putc(*cp++, file);
500 (void) putc(*cp++, file); 648 }
501 } 649 }
650 putc('"', file);
651 if (cp < cp2)
652 putc(' ', file);
502 } 653 }
503 putc('"', file); 654 break;
504 break; 655
656 case T_NSAP:
657 (void) fprintf(file, "\t%s", inet_nsap_ntoa(dlen, cp, NULL));
658 cp += dlen;
659 break;
660
661 case T_AAAA: {
662 char t[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
663
664 fprintf(file, "\t%s", inet_ntop(AF_INET6, cp, t, sizeof t));
665 cp += dlen;
666 break;
667 }
668
669 case T_LOC: {
670 char t[255];
671
672 fprintf(file, "\t%s", loc_ntoal(cp, t, sizeof t));
673 cp += dlen;
674 break;
675 }
676
677 case T_NAPTR: {
678 u_int order, preference;
679
680 order = _getshort(cp); cp += INT16SZ;
681 preference = _getshort(cp); cp += INT16SZ;
682 fprintf(file, "\t%u %u ",order, preference);
683 /* Flags */
684 n = *cp++;
685 fprintf(file,"\"%.*s\" ", (int)n, cp);
686 cp += n;
687 /* Service */
688 n = *cp++;
689 fprintf(file,"\"%.*s\" ", (int)n, cp);
690 cp += n;
691 /* Regexp */
692 n = *cp++;
693 fprintf(file,"\"%.*s\" ", (int)n, cp);
694 cp += n;
695 if ((cp = p_fqname(cp, msg, file)) == NULL)
696 return (NULL);
697 break;
698 }
699
700 case T_SRV: {
701 u_int priority, weight, port;
702
703 priority = _getshort(cp); cp += INT16SZ;
704 weight = _getshort(cp); cp += INT16SZ;
705 port = _getshort(cp); cp += INT16SZ;
706 fprintf(file, "\t%u %u %u ", priority, weight, port);
707 if ((cp = p_fqname(cp, msg, file)) == NULL)
708 return (NULL);
709 break;
710 }
505 711
506 case T_MINFO: 712 case T_MINFO:
507 case T_RP: 713 case T_RP:
508 putc('\t', file); 714 putc('\t', file);
509 cp = p_fqname(cp, msg, file); 715 if ((cp = p_fqname(cp, msg, file)) == NULL)
716 return (NULL);
510 putc(' ', file); 717 putc(' ', file);
511 cp = p_fqname(cp, msg, file); 718 if ((cp = p_fqname(cp, msg, file)) == NULL)
719 return (NULL);
512 break; 720 break;
513 721
514 case T_UINFO: 722 case T_UINFO:
515 putc('\t', file); 723 putc('\t', file);
516 fputs(cp, file); 724 fputs((char *)cp, file);
517 cp += dlen; 725 cp += dlen;
518 break; 726 break;
519 727
520 case T_UID: 728 case T_UID:
521 case T_GID: 729 case T_GID:
522 if (dlen == 4) { 730 if (dlen == 4) {
523 fprintf(file,"\t%u", _getlong(cp)); 731 fprintf(file, "\t%u", _getlong((u_char*)cp));
524 cp += sizeof(int32_t); 732 cp += INT32SZ;
525 } 733 }
526 break; 734 break;
527 735
528 case T_WKS: 736 case T_WKS:
529 if (dlen < sizeof(u_int32_t) + 1) 737 if (dlen < INT32SZ + 1)
530 break; 738 break;
531 bcopy(cp, (char *)&inaddr, sizeof(inaddr)); 739 bcopy(cp, (char *)&inaddr, INADDRSZ);
532 cp += sizeof(u_int32_t); 740 cp += INT32SZ;
533 fprintf(file, "\t%s %s ( ", 741 fprintf(file, "\t%s %s ( ",
534 inet_ntoa(inaddr), 742 inet_ntoa(inaddr),
535 deproto((int) *cp)); 743 deproto((int) *cp));
536 cp += sizeof(u_char); 744 cp += sizeof (u_char);
537 n = 0; 745 n = 0;
538 lcnt = 0; 746 lcnt = 0;
539 while (cp < cp1 + dlen) { 747 while (cp < cp1 + dlen) {
540 c = *cp++; 748 c = *cp++;
541 do { 749 do {
542 if (c & 0200) { 750 if (c & 0200) {
543 if (lcnt == 0) { 751 if (lcnt == 0) {
544 fputs("\n\t\t\t", file); 752 fputs("\n\t\t\t", file);
545 lcnt = 5; 753 lcnt = 5;
@@ -548,17 +756,83 @@ p_rr(cp, msg, file)
548 putc(' ', file); 756 putc(' ', file);
549 lcnt--; 757 lcnt--;
550 } 758 }
551 c <<= 1; 759 c <<= 1;
552 } while (++n & 07); 760 } while (++n & 07);
553 } 761 }
554 putc(')', file); 762 putc(')', file);
555 break; 763 break;
556 764
765 case T_KEY:
766 putc('\t', file);
767 keyflags = _getshort(cp);
768 cp += 2;
769 fprintf(file,"0x%04x", keyflags ); /* flags */
770 fprintf(file," %u", *cp++); /* protocol */
771 fprintf(file," %u (", *cp++); /* algorithm */
772
773 n = b64_ntop(cp, (cp1 + dlen) - cp,
774 base64_key, sizeof base64_key);
775 for (c = 0; c < n; ++c) {
776 if (0 == (c & 0x3F))
777 fprintf(file, "\n\t");
778 putc(base64_key[c], file); /* public key data */
779 }
780
781 fprintf(file, " )");
782 if (n < 0)
783 fprintf(file, "\t; BAD BASE64");
784 fflush(file);
785 cp = cp1 + dlen;
786 break;
787
788 case T_SIG:
789 type = _getshort((u_char*)cp);
790 cp += INT16SZ;
791 fprintf(file, " %s", p_type(type));
792 fprintf(file, "\t%u", *cp++); /* algorithm */
793 /* Check label value and print error if wrong. */
794 n = *cp++;
795 c = dn_count_labels (rrname);
796 if (n != c)
797 fprintf(file, "\t; LABELS WRONG (%d should be %d)\n\t",
798 n, c);
799 /* orig ttl */
800 n = _getlong((u_char*)cp);
801 if (n != tmpttl)
802 fprintf(file, " %u", n);
803 cp += INT32SZ;
804 /* sig expire */
805 fprintf(file, " (\n\t%s",
806 __p_secstodate(_getlong((u_char*)cp)));
807 cp += INT32SZ;
808 /* time signed */
809 fprintf(file, " %s", __p_secstodate(_getlong((u_char*)cp)));
810 cp += INT32SZ;
811 /* sig footprint */
812 fprintf(file," %u ", _getshort((u_char*)cp));
813 cp += INT16SZ;
814 /* signer's name */
815 cp = p_fqname(cp, msg, file);
816 n = b64_ntop(cp, (cp1 + dlen) - cp,
817 base64_key, sizeof base64_key);
818 for (c = 0; c < n; c++) {
819 if (0 == (c & 0x3F))
820 fprintf (file, "\n\t");
821 putc(base64_key[c], file); /* signature */
822 }
823 /* Clean up... */
824 fprintf(file, " )");
825 if (n < 0)
826 fprintf(file, "\t; BAD BASE64");
827 fflush(file);
828 cp = cp1+dlen;
829 break;
830
557#ifdef ALLOW_T_UNSPEC 831#ifdef ALLOW_T_UNSPEC
558 case T_UNSPEC: 832 case T_UNSPEC:
559 { 833 {
560 int NumBytes = 8; 834 int NumBytes = 8;
561 char *DataPtr; 835 u_char *DataPtr;
562 int i; 836 int i;
563 837
564 if (dlen < NumBytes) NumBytes = dlen; 838 if (dlen < NumBytes) NumBytes = dlen;
@@ -572,7 +846,7 @@ p_rr(cp, msg, file)
572#endif /* ALLOW_T_UNSPEC */ 846#endif /* ALLOW_T_UNSPEC */
573 847
574 default: 848 default:
575 fprintf(file,"\t?%d?", type); 849 fprintf(file, "\t?%d?", type);
576 cp += dlen; 850 cp += dlen;
577 } 851 }
578#if 0 852#if 0
@@ -581,136 +855,210 @@ p_rr(cp, msg, file)
581 putc('\n', file); 855 putc('\n', file);
582#endif 856#endif
583 if (cp - cp1 != dlen) { 857 if (cp - cp1 != dlen) {
584 fprintf(file,";; packet size error (found %d, dlen was %d)\n", 858 fprintf(file, ";; packet size error (found %ld, dlen was %d)\n",
585 cp - cp1, dlen); 859 (long)(cp - cp1), dlen);
586 cp = NULL; 860 cp = NULL;
587 } 861 }
588 return (cp); 862 return (cp);
589} 863}
590 864
591static char nbuf[40]; 865/*
866 * Names of RR classes and qclasses. Classes and qclasses are the same, except
867 * that C_ANY is a qclass but not a class. (You can ask for records of class
868 * C_ANY, but you can't have any records of that class in the database.)
869 */
870const struct res_sym __p_class_syms[] = {
871 {C_IN, "IN"},
872 {C_CHAOS, "CHAOS"},
873 {C_HS, "HS"},
874 {C_HS, "HESIOD"},
875 {C_ANY, "ANY"},
876 {C_IN, (char *)0}
877};
592 878
593/* 879/*
594 * Return a string for the type 880 * Names of RR types and qtypes. Types and qtypes are the same, except
881 * that T_ANY is a qtype but not a type. (You can ask for records of type
882 * T_ANY, but you can't have any records of that type in the database.)
595 */ 883 */
596char * 884const struct res_sym __p_type_syms[] = {
597__p_type(type) 885 {T_A, "A", "address"},
598 int type; 886 {T_NS, "NS", "name server"},
599{ 887 {T_MD, "MD", "mail destination (deprecated)"},
600 switch (type) { 888 {T_MF, "MF", "mail forwarder (deprecated)"},
601 case T_A: 889 {T_CNAME, "CNAME", "canonical name"},
602 return("A"); 890 {T_SOA, "SOA", "start of authority"},
603 case T_NS: /* authoritative server */ 891 {T_MB, "MB", "mailbox"},
604 return("NS"); 892 {T_MG, "MG", "mail group member"},
605 case T_CNAME: /* canonical name */ 893 {T_MR, "MR", "mail rename"},
606 return("CNAME"); 894 {T_NULL, "NULL", "null"},
607 case T_SOA: /* start of authority zone */ 895 {T_WKS, "WKS", "well-known service (deprecated)"},
608 return("SOA"); 896 {T_PTR, "PTR", "domain name pointer"},
609 case T_MB: /* mailbox domain name */ 897 {T_HINFO, "HINFO", "host information"},
610 return("MB"); 898 {T_MINFO, "MINFO", "mailbox information"},
611 case T_MG: /* mail group member */ 899 {T_MX, "MX", "mail exchanger"},
612 return("MG"); 900 {T_TXT, "TXT", "text"},
613 case T_MR: /* mail rename name */ 901 {T_RP, "RP", "responsible person"},
614 return("MR"); 902 {T_AFSDB, "AFSDB", "DCE or AFS server"},
615 case T_NULL: /* null resource record */ 903 {T_X25, "X25", "X25 address"},
616 return("NULL"); 904 {T_ISDN, "ISDN", "ISDN address"},
617 case T_WKS: /* well known service */ 905 {T_RT, "RT", "router"},
618 return("WKS"); 906 {T_NSAP, "NSAP", "nsap address"},
619 case T_PTR: /* domain name pointer */ 907 {T_NSAP_PTR, "NSAP_PTR", "domain name pointer"},
620 return("PTR"); 908 {T_SIG, "SIG", "signature"},
621 case T_HINFO: /* host information */ 909 {T_KEY, "KEY", "key"},
622 return("HINFO"); 910 {T_PX, "PX", "mapping information"},
623 case T_MINFO: /* mailbox information */ 911 {T_GPOS, "GPOS", "geographical position (withdrawn)"},
624 return("MINFO"); 912 {T_AAAA, "AAAA", "IPv6 address"},
625 case T_MX: /* mail routing info */ 913 {T_LOC, "LOC", "location"},
626 return("MX"); 914 {T_NXT, "NXT", "next valid name (unimplemented)"},
627 case T_TXT: /* text */ 915 {T_EID, "EID", "endpoint identifier (unimplemented)"},
628 return("TXT"); 916 {T_NIMLOC, "NIMLOC", "NIMROD locator (unimplemented)"},
629 case T_RP: /* responsible person */ 917 {T_SRV, "SRV", "server selection"},
630 return("RP"); 918 {T_ATMA, "ATMA", "ATM address (unimplemented)"},
631 case T_AFSDB: /* AFS cell database */ 919 {T_IXFR, "IXFR", "incremental zone transfer"},
632 return("AFSDB"); 920 {T_AXFR, "AXFR", "zone transfer"},
633 case T_AXFR: /* zone transfer */ 921 {T_MAILB, "MAILB", "mailbox-related data (deprecated)"},
634 return("AXFR"); 922 {T_MAILA, "MAILA", "mail agent (deprecated)"},
635 case T_MAILB: /* mail box */ 923 {T_UINFO, "UINFO", "user information (nonstandard)"},
636 return("MAILB"); 924 {T_UID, "UID", "user ID (nonstandard)"},
637 case T_MAILA: /* mail address */ 925 {T_GID, "GID", "group ID (nonstandard)"},
638 return("MAILA"); 926 {T_NAPTR, "NAPTR", "URN Naming Authority"},
639 case T_ANY: /* matches any type */
640 return("ANY");
641 case T_UINFO:
642 return("UINFO");
643 case T_UID:
644 return("UID");
645 case T_GID:
646 return("GID");
647#ifdef ALLOW_T_UNSPEC 927#ifdef ALLOW_T_UNSPEC
648 case T_UNSPEC: 928 {T_UNSPEC, "UNSPEC", "unspecified data (nonstandard)"},
649 return("UNSPEC");
650#endif /* ALLOW_T_UNSPEC */ 929#endif /* ALLOW_T_UNSPEC */
930 {T_ANY, "ANY", "\"any\""},
931 {0, NULL, NULL}
932};
651 933
652 default: 934int
653 (void)sprintf(nbuf, "%d", type); 935__sym_ston(syms, name, success)
654 return(nbuf); 936 const struct res_sym *syms;
937 char *name;
938 int *success;
939{
940 for (; syms->name != 0; syms++) {
941 if (strcasecmp (name, syms->name) == 0) {
942 if (success)
943 *success = 1;
944 return (syms->number);
945 }
946 }
947 if (success)
948 *success = 0;
949 return (syms->number); /* The default value. */
950}
951
952const char *
953__sym_ntos(syms, number, success)
954 const struct res_sym *syms;
955 int number;
956 int *success;
957{
958 static char unname[20];
959
960 for (; syms->name != 0; syms++) {
961 if (number == syms->number) {
962 if (success)
963 *success = 1;
964 return (syms->name);
965 }
966 }
967
968 snprintf(unname, sizeof unname, "%d", number);
969 if (success)
970 *success = 0;
971 return (unname);
972}
973
974
975const char *
976__sym_ntop(syms, number, success)
977 const struct res_sym *syms;
978 int number;
979 int *success;
980{
981 static char unname[20];
982
983 for (; syms->name != 0; syms++) {
984 if (number == syms->number) {
985 if (success)
986 *success = 1;
987 return (syms->humanname);
988 }
655 } 989 }
990 snprintf(unname, sizeof unname, "%d", number);
991 if (success)
992 *success = 0;
993 return (unname);
994}
995
996/*
997 * Return a string for the type
998 */
999const char *
1000__p_type(type)
1001 int type;
1002{
1003 return (__sym_ntos (__p_type_syms, type, (int *)0));
656} 1004}
657 1005
658/* 1006/*
659 * Return a mnemonic for class 1007 * Return a mnemonic for class
660 */ 1008 */
661char * 1009const char *
662__p_class(class) 1010__p_class(class)
663 int class; 1011 int class;
664{ 1012{
665 1013 return (__sym_ntos (__p_class_syms, class, (int *)0));
666 switch (class) {
667 case C_IN: /* internet class */
668 return("IN");
669 case C_HS: /* hesiod class */
670 return("HS");
671 case C_ANY: /* matches any class */
672 return("ANY");
673 default:
674 (void)sprintf(nbuf, "%d", class);
675 return(nbuf);
676 }
677} 1014}
678 1015
679/* 1016/*
680 * Return a mnemonic for an option 1017 * Return a mnemonic for an option
681 */ 1018 */
682static char * 1019const char *
683p_option(option) 1020__p_option(option)
684 u_int32_t option; 1021 u_long option;
685{ 1022{
1023 static char nbuf[40];
1024
686 switch (option) { 1025 switch (option) {
687 case RES_INIT: return "init"; 1026 case RES_INIT: return "init";
688 case RES_DEBUG: return "debug"; 1027 case RES_DEBUG: return "debug";
689 case RES_AAONLY: return "aaonly"; 1028 case RES_AAONLY: return "aaonly(unimpl)";
690 case RES_USEVC: return "usevc"; 1029 case RES_USEVC: return "usevc";
691 case RES_PRIMARY: return "primry"; 1030 case RES_PRIMARY: return "primry(unimpl)";
692 case RES_IGNTC: return "igntc"; 1031 case RES_IGNTC: return "igntc";
693 case RES_RECURSE: return "recurs"; 1032 case RES_RECURSE: return "recurs";
694 case RES_DEFNAMES: return "defnam"; 1033 case RES_DEFNAMES: return "defnam";
695 case RES_STAYOPEN: return "styopn"; 1034 case RES_STAYOPEN: return "styopn";
696 case RES_DNSRCH: return "dnsrch"; 1035 case RES_DNSRCH: return "dnsrch";
697 default: sprintf(nbuf, "?0x%x?", option); return nbuf; 1036 case RES_INSECURE1: return "insecure1";
1037 case RES_INSECURE2: return "insecure2";
1038 case RES_USE_INET6: return "inet6";
1039 case RES_USE_EDNS0: return "edns0";
1040 default:
1041 snprintf(nbuf, sizeof nbuf, "?0x%lx?", (u_long)option);
1042 return (nbuf);
698 } 1043 }
699} 1044}
700 1045
701/* 1046/*
702 * Return a mnemonic for a time to live 1047 * Return a mnemonic for a time to live
703 */ 1048 */
704char * 1049const char *
705__p_time(value) 1050p_time(value)
706 u_int32_t value; 1051 u_int32_t value;
707{ 1052{
1053 static char nbuf[40];
1054 char *ebuf;
708 int secs, mins, hours, days; 1055 int secs, mins, hours, days;
709 register char *p; 1056 register char *p;
1057 int tmp;
710 1058
711 if (value == 0) { 1059 if (value == 0) {
712 strcpy(nbuf, "0 secs"); 1060 strlcpy(nbuf, "0 secs", sizeof nbuf);
713 return(nbuf); 1061 return (nbuf);
714 } 1062 }
715 1063
716 secs = value % 60; 1064 secs = value % 60;
@@ -724,26 +1072,490 @@ __p_time(value)
724 1072
725#define PLURALIZE(x) x, (x == 1) ? "" : "s" 1073#define PLURALIZE(x) x, (x == 1) ? "" : "s"
726 p = nbuf; 1074 p = nbuf;
1075 ebuf = nbuf + sizeof(nbuf);
727 if (days) { 1076 if (days) {
728 (void)sprintf(p, "%d day%s", PLURALIZE(days)); 1077 if ((tmp = snprintf(p, ebuf - p, "%d day%s",
729 while (*++p); 1078 PLURALIZE(days))) >= ebuf - nbuf || tmp < 0)
1079 goto full;
1080 p += tmp;
730 } 1081 }
731 if (hours) { 1082 if (hours) {
732 if (days) 1083 if (days)
733 *p++ = ' '; 1084 *p++ = ' ';
734 (void)sprintf(p, "%d hour%s", PLURALIZE(hours)); 1085 if (p >= ebuf)
735 while (*++p); 1086 goto full;
1087 if ((tmp = snprintf(p, ebuf - p, "%d hour%s",
1088 PLURALIZE(hours))) >= ebuf - nbuf || tmp < 0)
1089 goto full;
1090 p += tmp;
736 } 1091 }
737 if (mins) { 1092 if (mins) {
738 if (days || hours) 1093 if (days || hours)
739 *p++ = ' '; 1094 *p++ = ' ';
740 (void)sprintf(p, "%d min%s", PLURALIZE(mins)); 1095 if (p >= ebuf)
741 while (*++p); 1096 goto full;
1097 if ((tmp = snprintf(p, ebuf - p, "%d min%s",
1098 PLURALIZE(mins))) >= ebuf - nbuf || tmp < 0)
1099 goto full;
1100 p += tmp;
742 } 1101 }
743 if (secs || ! (days || hours || mins)) { 1102 if (secs || ! (days || hours || mins)) {
744 if (days || hours || mins) 1103 if (days || hours || mins)
745 *p++ = ' '; 1104 *p++ = ' ';
746 (void)sprintf(p, "%d sec%s", PLURALIZE(secs)); 1105 if (p >= ebuf)
1106 goto full;
1107 if ((tmp = snprintf(p, ebuf - p, "%d sec%s",
1108 PLURALIZE(secs))) >= ebuf - nbuf || tmp < 0)
1109 goto full;
1110 }
1111 return (nbuf);
1112full:
1113 p = nbuf + sizeof(nbuf) - 4;
1114 *p++ = '.';
1115 *p++ = '.';
1116 *p++ = '.';
1117 *p++ = '\0';
1118 return (nbuf);
1119}
1120
1121/*
1122 * routines to convert between on-the-wire RR format and zone file format.
1123 * Does not contain conversion to/from decimal degrees; divide or multiply
1124 * by 60*60*1000 for that.
1125 */
1126
1127static unsigned int poweroften[10] = {1, 10, 100, 1000, 10000, 100000,
1128 1000000,10000000,100000000,1000000000};
1129
1130/* takes an XeY precision/size value, returns a string representation. */
1131static const char *
1132precsize_ntoa(prec)
1133 u_int8_t prec;
1134{
1135 static char retbuf[sizeof "90000000.00"];
1136 unsigned long val;
1137 int mantissa, exponent;
1138
1139 mantissa = (int)((prec >> 4) & 0x0f) % 10;
1140 exponent = (int)((prec >> 0) & 0x0f) % 10;
1141
1142 val = mantissa * poweroften[exponent];
1143
1144 (void) snprintf(retbuf, sizeof retbuf, "%ld.%.2ld", val/100, val%100);
1145 return (retbuf);
1146}
1147
1148/* converts ascii size/precision X * 10**Y(cm) to 0xXY. moves pointer. */
1149static u_int8_t
1150precsize_aton(strptr)
1151 char **strptr;
1152{
1153 unsigned int mval = 0, cmval = 0;
1154 u_int8_t retval = 0;
1155 register char *cp;
1156 register int exponent;
1157 register int mantissa;
1158
1159 cp = *strptr;
1160
1161 while (isdigit(*cp))
1162 mval = mval * 10 + (*cp++ - '0');
1163
1164 if (*cp == '.') { /* centimeters */
1165 cp++;
1166 if (isdigit(*cp)) {
1167 cmval = (*cp++ - '0') * 10;
1168 if (isdigit(*cp)) {
1169 cmval += (*cp++ - '0');
1170 }
1171 }
1172 }
1173 cmval = (mval * 100) + cmval;
1174
1175 for (exponent = 0; exponent < 9; exponent++)
1176 if (cmval < poweroften[exponent+1])
1177 break;
1178
1179 mantissa = cmval / poweroften[exponent];
1180 if (mantissa > 9)
1181 mantissa = 9;
1182
1183 retval = (mantissa << 4) | exponent;
1184
1185 *strptr = cp;
1186
1187 return (retval);
1188}
1189
1190/* converts ascii lat/lon to unsigned encoded 32-bit number. moves pointer. */
1191static u_int32_t
1192latlon2ul(latlonstrptr,which)
1193 char **latlonstrptr;
1194 int *which;
1195{
1196 register char *cp;
1197 u_int32_t retval;
1198 int deg = 0, min = 0, secs = 0, secsfrac = 0;
1199
1200 cp = *latlonstrptr;
1201
1202 while (isdigit(*cp))
1203 deg = deg * 10 + (*cp++ - '0');
1204
1205 while (isspace(*cp))
1206 cp++;
1207
1208 if (!(isdigit(*cp)))
1209 goto fndhemi;
1210
1211 while (isdigit(*cp))
1212 min = min * 10 + (*cp++ - '0');
1213
1214 while (isspace(*cp))
1215 cp++;
1216
1217 if (!(isdigit(*cp)))
1218 goto fndhemi;
1219
1220 while (isdigit(*cp))
1221 secs = secs * 10 + (*cp++ - '0');
1222
1223 if (*cp == '.') { /* decimal seconds */
1224 cp++;
1225 if (isdigit(*cp)) {
1226 secsfrac = (*cp++ - '0') * 100;
1227 if (isdigit(*cp)) {
1228 secsfrac += (*cp++ - '0') * 10;
1229 if (isdigit(*cp)) {
1230 secsfrac += (*cp++ - '0');
1231 }
1232 }
1233 }
1234 }
1235
1236 while (!isspace(*cp)) /* if any trailing garbage */
1237 cp++;
1238
1239 while (isspace(*cp))
1240 cp++;
1241
1242 fndhemi:
1243 switch (*cp) {
1244 case 'N': case 'n':
1245 case 'E': case 'e':
1246 retval = ((unsigned)1<<31)
1247 + (((((deg * 60) + min) * 60) + secs) * 1000)
1248 + secsfrac;
1249 break;
1250 case 'S': case 's':
1251 case 'W': case 'w':
1252 retval = ((unsigned)1<<31)
1253 - (((((deg * 60) + min) * 60) + secs) * 1000)
1254 - secsfrac;
1255 break;
1256 default:
1257 retval = 0; /* invalid value -- indicates error */
1258 break;
1259 }
1260
1261 switch (*cp) {
1262 case 'N': case 'n':
1263 case 'S': case 's':
1264 *which = 1; /* latitude */
1265 break;
1266 case 'E': case 'e':
1267 case 'W': case 'w':
1268 *which = 2; /* longitude */
1269 break;
1270 default:
1271 *which = 0; /* error */
1272 break;
1273 }
1274
1275 cp++; /* skip the hemisphere */
1276
1277 while (!isspace(*cp)) /* if any trailing garbage */
1278 cp++;
1279
1280 while (isspace(*cp)) /* move to next field */
1281 cp++;
1282
1283 *latlonstrptr = cp;
1284
1285 return (retval);
1286}
1287
1288/* converts a zone file representation in a string to an RDATA on-the-wire
1289 * representation. */
1290int
1291loc_aton(ascii, binary)
1292 const char *ascii;
1293 u_char *binary;
1294{
1295 const char *maxcp;
1296 u_char *bcp;
1297 char *cp;
1298
1299 u_int32_t latit = 0, longit = 0, alt = 0;
1300 u_int32_t lltemp1 = 0, lltemp2 = 0;
1301 int altmeters = 0, altfrac = 0, altsign = 1;
1302 u_int8_t hp = 0x16; /* default = 1e6 cm = 10000.00m = 10km */
1303 u_int8_t vp = 0x13; /* default = 1e3 cm = 10.00m */
1304 u_int8_t siz = 0x12; /* default = 1e2 cm = 1.00m */
1305 int which1 = 0, which2 = 0;
1306
1307 cp = (char *)ascii;
1308 maxcp = cp + strlen(ascii);
1309
1310 lltemp1 = latlon2ul(&cp, &which1);
1311
1312 lltemp2 = latlon2ul(&cp, &which2);
1313
1314 switch (which1 + which2) {
1315 case 3: /* 1 + 2, the only valid combination */
1316 if ((which1 == 1) && (which2 == 2)) { /* normal case */
1317 latit = lltemp1;
1318 longit = lltemp2;
1319 } else if ((which1 == 2) && (which2 == 1)) { /* reversed */
1320 longit = lltemp1;
1321 latit = lltemp2;
1322 } else { /* some kind of brokenness */
1323 return (0);
1324 }
1325 break;
1326 default: /* we didn't get one of each */
1327 return (0);
747 } 1328 }
748 return(nbuf); 1329
1330 /* altitude */
1331 if (*cp == '-') {
1332 altsign = -1;
1333 cp++;
1334 }
1335
1336 if (*cp == '+')
1337 cp++;
1338
1339 while (isdigit(*cp))
1340 altmeters = altmeters * 10 + (*cp++ - '0');
1341
1342 if (*cp == '.') { /* decimal meters */
1343 cp++;
1344 if (isdigit(*cp)) {
1345 altfrac = (*cp++ - '0') * 10;
1346 if (isdigit(*cp)) {
1347 altfrac += (*cp++ - '0');
1348 }
1349 }
1350 }
1351
1352 alt = (10000000 + (altsign * (altmeters * 100 + altfrac)));
1353
1354 while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */
1355 cp++;
1356
1357 while (isspace(*cp) && (cp < maxcp))
1358 cp++;
1359
1360 if (cp >= maxcp)
1361 goto defaults;
1362
1363 siz = precsize_aton(&cp);
1364
1365 while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */
1366 cp++;
1367
1368 while (isspace(*cp) && (cp < maxcp))
1369 cp++;
1370
1371 if (cp >= maxcp)
1372 goto defaults;
1373
1374 hp = precsize_aton(&cp);
1375
1376 while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */
1377 cp++;
1378
1379 while (isspace(*cp) && (cp < maxcp))
1380 cp++;
1381
1382 if (cp >= maxcp)
1383 goto defaults;
1384
1385 vp = precsize_aton(&cp);
1386
1387 defaults:
1388
1389 bcp = binary;
1390 *bcp++ = (u_int8_t) 0; /* version byte */
1391 *bcp++ = siz;
1392 *bcp++ = hp;
1393 *bcp++ = vp;
1394 PUTLONG(latit,bcp);
1395 PUTLONG(longit,bcp);
1396 PUTLONG(alt,bcp);
1397
1398 return (16); /* size of RR in octets */
1399}
1400
1401const char *
1402loc_ntoa(binary, ascii)
1403 const u_char *binary;
1404 char *ascii;
1405{
1406 return loc_ntoal(binary, ascii, 255);
1407}
1408
1409/* takes an on-the-wire LOC RR and formats it in a human readable format. */
1410static const char *
1411loc_ntoal(binary, ascii, ascii_len)
1412 const u_char *binary;
1413 char *ascii;
1414 int ascii_len;
1415{
1416 static char *error = "?";
1417 register const u_char *cp = binary;
1418
1419 int latdeg, latmin, latsec, latsecfrac;
1420 int longdeg, longmin, longsec, longsecfrac;
1421 char northsouth, eastwest;
1422 int altmeters, altfrac, altsign;
1423
1424 const int referencealt = 100000 * 100;
1425
1426 int32_t latval, longval, altval;
1427 u_int32_t templ;
1428 u_int8_t sizeval, hpval, vpval, versionval;
1429
1430 char *sizestr, *hpstr, *vpstr;
1431
1432 versionval = *cp++;
1433
1434 if (versionval) {
1435 snprintf(ascii, ascii_len, "; error: unknown LOC RR version");
1436 return (ascii);
1437 }
1438
1439 sizeval = *cp++;
1440
1441 hpval = *cp++;
1442 vpval = *cp++;
1443
1444 GETLONG(templ, cp);
1445 latval = (templ - ((unsigned)1<<31));
1446
1447 GETLONG(templ, cp);
1448 longval = (templ - ((unsigned)1<<31));
1449
1450 GETLONG(templ, cp);
1451 if (templ < referencealt) { /* below WGS 84 spheroid */
1452 altval = referencealt - templ;
1453 altsign = -1;
1454 } else {
1455 altval = templ - referencealt;
1456 altsign = 1;
1457 }
1458
1459 if (latval < 0) {
1460 northsouth = 'S';
1461 latval = -latval;
1462 } else
1463 northsouth = 'N';
1464
1465 latsecfrac = latval % 1000;
1466 latval = latval / 1000;
1467 latsec = latval % 60;
1468 latval = latval / 60;
1469 latmin = latval % 60;
1470 latval = latval / 60;
1471 latdeg = latval;
1472
1473 if (longval < 0) {
1474 eastwest = 'W';
1475 longval = -longval;
1476 } else
1477 eastwest = 'E';
1478
1479 longsecfrac = longval % 1000;
1480 longval = longval / 1000;
1481 longsec = longval % 60;
1482 longval = longval / 60;
1483 longmin = longval % 60;
1484 longval = longval / 60;
1485 longdeg = longval;
1486
1487 altfrac = altval % 100;
1488 altmeters = (altval / 100) * altsign;
1489
1490 if ((sizestr = strdup(precsize_ntoa(sizeval))) == NULL)
1491 sizestr = error;
1492 if ((hpstr = strdup(precsize_ntoa(hpval))) == NULL)
1493 hpstr = error;
1494 if ((vpstr = strdup(precsize_ntoa(vpval))) == NULL)
1495 vpstr = error;
1496
1497 snprintf(ascii, ascii_len,
1498 "%d %.2d %.2d.%.3d %c %d %.2d %.2d.%.3d %c %d.%.2dm %sm %sm %sm",
1499 latdeg, latmin, latsec, latsecfrac, northsouth,
1500 longdeg, longmin, longsec, longsecfrac, eastwest,
1501 altmeters, altfrac, sizestr, hpstr, vpstr);
1502
1503 if (sizestr != error)
1504 free(sizestr);
1505 if (hpstr != error)
1506 free(hpstr);
1507 if (vpstr != error)
1508 free(vpstr);
1509
1510 return (ascii);
1511}
1512
1513
1514/* Return the number of DNS hierarchy levels in the name. */
1515int
1516__dn_count_labels(name)
1517 char *name;
1518{
1519 int i, len, count;
1520
1521 len = strlen(name);
1522
1523 for(i = 0, count = 0; i < len; i++) {
1524 if (name[i] == '.')
1525 count++;
1526 }
1527
1528 /* don't count initial wildcard */
1529 if (name[0] == '*')
1530 if (count)
1531 count--;
1532
1533 /* don't count the null label for root. */
1534 /* if terminating '.' not found, must adjust */
1535 /* count to include last label */
1536 if (len > 0 && name[len-1] != '.')
1537 count++;
1538 return (count);
1539}
1540
1541
1542/*
1543 * Make dates expressed in seconds-since-Jan-1-1970 easy to read.
1544 * SIG records are required to be printed like this, by the Secure DNS RFC.
1545 */
1546char *
1547__p_secstodate (secs)
1548 unsigned long secs;
1549{
1550 static char output[15]; /* YYYYMMDDHHMMSS and null */
1551 time_t clock = secs;
1552 struct tm *time;
1553
1554 time = gmtime(&clock);
1555 time->tm_year += 1900;
1556 time->tm_mon += 1;
1557 snprintf(output, sizeof output, "%04d%02d%02d%02d%02d%02d",
1558 time->tm_year, time->tm_mon, time->tm_mday,
1559 time->tm_hour, time->tm_min, time->tm_sec);
1560 return (output);
749} 1561}
diff --git a/src/lib/libc/net/res_init.c b/src/lib/libc/net/res_init.c
index 33cc8d39f1..9c73958883 100644
--- a/src/lib/libc/net/res_init.c
+++ b/src/lib/libc/net/res_init.c
@@ -1,9 +1,11 @@
1/* $NetBSD: res_init.c,v 1.8 1995/06/03 22:33:36 mycroft Exp $ */ 1/* $OpenBSD: res_init.c,v 1.29 2003/06/02 20:18:36 millert Exp $ */
2 2
3/*- 3/*
4 * ++Copyright++ 1985, 1989, 1993
5 * -
4 * Copyright (c) 1985, 1989, 1993 6 * Copyright (c) 1985, 1989, 1993
5 * The Regents of the University of California. All rights reserved. 7 * The Regents of the University of California. All rights reserved.
6 * 8 *
7 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
9 * are met: 11 * are met:
@@ -12,14 +14,10 @@
12 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 15 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 16 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 17 * 3. Neither the name of the University nor the names of its contributors
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 18 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission. 19 * without specific prior written permission.
22 * 20 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -53,80 +51,181 @@
53 * --Copyright-- 51 * --Copyright--
54 */ 52 */
55 53
54#ifndef INET6
55#define INET6
56#endif
57
56#if defined(LIBC_SCCS) && !defined(lint) 58#if defined(LIBC_SCCS) && !defined(lint)
57#if 0 59#if 0
58static char sccsid[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93"; 60static char sccsid[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93";
59static char rcsid[] = "$Id: res_init.c,v 4.9.1.1 1993/05/02 22:43:03 vixie Rel "; 61static char rcsid[] = "$From: res_init.c,v 8.7 1996/09/28 06:51:07 vixie Exp $";
60#else 62#else
61static char rcsid[] = "$NetBSD: res_init.c,v 1.8 1995/06/03 22:33:36 mycroft Exp $"; 63static char rcsid[] = "$OpenBSD: res_init.c,v 1.29 2003/06/02 20:18:36 millert Exp $";
62#endif 64#endif
63#endif /* LIBC_SCCS and not lint */ 65#endif /* LIBC_SCCS and not lint */
64 66
67#include <sys/types.h>
65#include <sys/param.h> 68#include <sys/param.h>
66#include <sys/socket.h> 69#include <sys/socket.h>
70#include <sys/time.h>
67#include <netinet/in.h> 71#include <netinet/in.h>
68#include <arpa/inet.h> 72#include <arpa/inet.h>
69#include <arpa/nameser.h> 73#include <arpa/nameser.h>
74
75#include <stdio.h>
76#include <ctype.h>
70#include <resolv.h> 77#include <resolv.h>
71#include <unistd.h> 78#include <unistd.h>
72#include <stdio.h>
73#include <stdlib.h> 79#include <stdlib.h>
74#include <string.h> 80#include <string.h>
81#ifdef INET6
82#include <netdb.h>
83#endif /* INET6 */
84
85#include "thread_private.h"
86
87/*-------------------------------------- info about "sortlist" --------------
88 * Marc Majka 1994/04/16
89 * Allan Nathanson 1994/10/29 (BIND 4.9.3.x)
90 *
91 * NetInfo resolver configuration directory support.
92 *
93 * Allow a NetInfo directory to be created in the hierarchy which
94 * contains the same information as the resolver configuration file.
95 *
96 * - The local domain name is stored as the value of the "domain" property.
97 * - The Internet address(es) of the name server(s) are stored as values
98 * of the "nameserver" property.
99 * - The name server addresses are stored as values of the "nameserver"
100 * property.
101 * - The search list for host-name lookup is stored as values of the
102 * "search" property.
103 * - The sortlist comprised of IP address netmask pairs are stored as
104 * values of the "sortlist" property. The IP address and optional netmask
105 * should be separated by a slash (/) or ampersand (&) character.
106 * - Internal resolver variables can be set from the value of the "options"
107 * property.
108 */
109
110static void res_setoptions(char *, char *);
75 111
76static void res_setoptions __P((char *, char *)); 112#ifdef RESOLVSORT
77static u_int32_t net_mask __P((struct in_addr)); 113static const char sort_mask[] = "/&";
114#define ISSORTMASK(ch) (strchr(sort_mask, ch) != NULL)
115static u_int32_t net_mask(struct in_addr);
116#endif
78 117
79/* 118/*
80 * Resolver state default settings 119 * Resolver state default settings.
81 */ 120 */
121volatile struct _thread_private_key_struct __THREAD_KEY_NAME(_res) = {
122 PTHREAD_ONCE_INIT, 0
123};
82 124
83struct __res_state _res = { 125struct __res_state _res
84 RES_TIMEOUT, /* retransmition time interval */ 126# if defined(__BIND_RES_TEXT)
85 4, /* number of times to retransmit */ 127 = { RES_TIMEOUT, } /* Motorola, et al. */
86 RES_DEFAULT, /* options flags */ 128# endif
87 1, /* number of name servers */ 129 ;
130#ifdef INET6
131volatile struct _thread_private_key_struct __THREAD_KEY_NAME(_res_ext) = {
132 PTHREAD_ONCE_INIT, 0
88}; 133};
89 134
135struct __res_state_ext _res_ext;
136#endif /* INET6 */
137
90/* 138/*
91 * Set up default settings. If the configuration file exist, the values 139 * Set up default settings. If the configuration file exist, the values
92 * there will have precedence. Otherwise, the server address is set to 140 * there will have precedence. Otherwise, the server address is set to
93 * INADDR_ANY and the default domain name comes from the gethostname(). 141 * INADDR_ANY and the default domain name comes from the gethostname().
94 * 142 *
95 * The configuration file should only be used if you want to redefine your 143 * An interrim version of this code (BIND 4.9, pre-4.4BSD) used 127.0.0.1
96 * domain or run without a server on your machine. 144 * rather than INADDR_ANY ("0.0.0.0") as the default name server address
145 * since it was noted that INADDR_ANY actually meant ``the first interface
146 * you "ifconfig"'d at boot time'' and if this was a SLIP or PPP interface,
147 * it had to be "up" in order for you to reach your own name server. It
148 * was later decided that since the recommended practice is to always
149 * install local static routes through 127.0.0.1 for all your network
150 * interfaces, that we could solve this problem without a code change.
151 *
152 * The configuration file should always be used, since it is the only way
153 * to specify a default domain. If you are running a server on your local
154 * machine, you should say "nameserver 0.0.0.0" or "nameserver 127.0.0.1"
155 * in the configuration file.
97 * 156 *
98 * Return 0 if completes successfully, -1 on error 157 * Return 0 if completes successfully, -1 on error
99 */ 158 */
159int
100res_init() 160res_init()
101{ 161{
162 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
163#ifdef INET6
164 struct __res_state_ext *_res_extp = _THREAD_PRIVATE(_res_ext, _res_ext,
165 &_res_ext);
166#endif
102 register FILE *fp; 167 register FILE *fp;
103 register char *cp, **pp, *net; 168 register char *cp, **pp;
104 register int n; 169 register int n;
105 char buf[BUFSIZ], buf2[BUFSIZ]; 170 char buf[BUFSIZ];
106 int nserv = 0; /* number of nameserver records read from file */ 171 int nserv = 0; /* number of nameserver records read from file */
107 int haveenv = 0; 172 int haveenv = 0;
108 int havesearch = 0; 173 int havesearch = 0;
174 size_t len;
175#ifdef RESOLVSORT
109 int nsort = 0; 176 int nsort = 0;
110 u_long mask; 177 char *net;
178#endif
179#ifndef RFC1535
180 int dots;
181#endif
182
183 /*
184 * These three fields used to be statically initialized. This made
185 * it hard to use this code in a shared library. It is necessary,
186 * now that we're doing dynamic initialization here, that we preserve
187 * the old semantics: if an application modifies one of these three
188 * fields of _res before res_init() is called, res_init() will not
189 * alter them. Of course, if an application is setting them to
190 * _zero_ before calling res_init(), hoping to override what used
191 * to be the static default, we can't detect it and unexpected results
192 * will follow. Zero for any of these fields would make no sense,
193 * so one can safely assume that the applications were already getting
194 * unexpected results.
195 *
196 * _res.options is tricky since some apps were known to diddle the bits
197 * before res_init() was first called. We can't replicate that semantic
198 * with dynamic initialization (they may have turned bits off that are
199 * set in RES_DEFAULT). Our solution is to declare such applications
200 * "broken". They could fool us by setting RES_INIT but none do (yet).
201 */
202 if (!_resp->retrans)
203 _resp->retrans = RES_TIMEOUT;
204 if (!_resp->retry)
205 _resp->retry = 4;
206 if (!(_resp->options & RES_INIT))
207 _resp->options = RES_DEFAULT;
111 208
112 _res.nsaddr.sin_len = sizeof(struct sockaddr_in);
113 _res.nsaddr.sin_family = AF_INET;
114 _res.nsaddr.sin_port = htons(NAMESERVER_PORT);
115#ifdef USELOOPBACK 209#ifdef USELOOPBACK
116 _res.nsaddr.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1); 210 _resp->nsaddr.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1);
117#else 211#else
118 _res.nsaddr.sin_addr.s_addr = INADDR_ANY; 212 _resp->nsaddr.sin_addr.s_addr = INADDR_ANY;
213#endif
214 _resp->nsaddr.sin_family = AF_INET;
215 _resp->nsaddr.sin_port = htons(NAMESERVER_PORT);
216 _resp->nsaddr.sin_len = sizeof(struct sockaddr_in);
217#ifdef INET6
218 if (sizeof(_res_extp->nsaddr) >= _resp->nsaddr.sin_len)
219 memcpy(&_res_extp->nsaddr, &_resp->nsaddr, _resp->nsaddr.sin_len);
119#endif 220#endif
120 _res.nscount = 1; 221 _resp->nscount = 1;
121 _res.ndots = 1; 222 _resp->ndots = 1;
122 _res.pfcode = 0; 223 _resp->pfcode = 0;
123 strncpy(_res.lookups, "f", sizeof _res.lookups); 224 strlcpy(_resp->lookups, "f", sizeof _resp->lookups);
124 225
125 /* Allow user to override the local domain definition */ 226 /* Allow user to override the local domain definition */
126 if ((cp = getenv("LOCALDOMAIN")) != NULL) { 227 if (issetugid() == 0 && (cp = getenv("LOCALDOMAIN")) != NULL) {
127 (void)strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1); 228 strlcpy(_resp->defdname, cp, sizeof(_resp->defdname));
128 if ((cp = strpbrk(_res.defdname, " \t\n")) != NULL)
129 *cp = '\0';
130 haveenv++; 229 haveenv++;
131 230
132 /* 231 /*
@@ -136,11 +235,11 @@ res_init()
136 * one that they want to use as an individual (even more 235 * one that they want to use as an individual (even more
137 * important now that the rfc1535 stuff restricts searches) 236 * important now that the rfc1535 stuff restricts searches)
138 */ 237 */
139 cp = _res.defdname; 238 cp = _resp->defdname;
140 pp = _res.dnsrch; 239 pp = _resp->dnsrch;
141 *pp++ = cp; 240 *pp++ = cp;
142 for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) { 241 for (n = 0; *cp && pp < _resp->dnsrch + MAXDNSRCH; cp++) {
143 if (*cp == '\n') /* silly backwards compat */ 242 if (*cp == '\n') /* silly backwards compat */
144 break; 243 break;
145 else if (*cp == ' ' || *cp == '\t') { 244 else if (*cp == ' ' || *cp == '\t') {
146 *cp = 0; 245 *cp = 0;
@@ -158,16 +257,29 @@ res_init()
158 *pp++ = 0; 257 *pp++ = 0;
159 } 258 }
160 259
260#define MATCH(line, name) \
261 (!strncmp(line, name, sizeof(name) - 1) && \
262 (line[sizeof(name) - 1] == ' ' || \
263 line[sizeof(name) - 1] == '\t'))
264
161 if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) { 265 if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) {
162 strncpy(_res.lookups, "bf", sizeof _res.lookups); 266 strlcpy(_resp->lookups, "bf", sizeof _resp->lookups);
163 267
164 /* read the config file */ 268 /* read the config file */
165 while (fgets(buf, sizeof(buf), fp) != NULL) { 269 buf[0] = '\0';
270 while ((cp = fgetln(fp, &len)) != NULL) {
271 /* skip lines that are too long or zero length */
272 if (len >= sizeof(buf) || len == 0)
273 continue;
274 (void)memcpy(buf, cp, len);
275 buf[len] = '\0';
166 /* skip comments */ 276 /* skip comments */
167 if ((*buf == ';') || (*buf == '#')) 277 if ((cp = strpbrk(buf, ";#")) != NULL)
278 *cp = '\0';
279 if (buf[0] == '\0')
168 continue; 280 continue;
169 /* read default domain name */ 281 /* read default domain name */
170 if (!strncmp(buf, "domain", sizeof("domain") - 1)) { 282 if (MATCH(buf, "domain")) {
171 if (haveenv) /* skip if have from environ */ 283 if (haveenv) /* skip if have from environ */
172 continue; 284 continue;
173 cp = buf + sizeof("domain") - 1; 285 cp = buf + sizeof("domain") - 1;
@@ -175,18 +287,17 @@ res_init()
175 cp++; 287 cp++;
176 if ((*cp == '\0') || (*cp == '\n')) 288 if ((*cp == '\0') || (*cp == '\n'))
177 continue; 289 continue;
178 (void)strncpy(_res.defdname, cp, 290 strlcpy(_resp->defdname, cp, sizeof(_resp->defdname));
179 sizeof(_res.defdname) - 1); 291 if ((cp = strpbrk(_resp->defdname, " \t\n")) != NULL)
180 if ((cp = strpbrk(_res.defdname, " \t\n")) != NULL)
181 *cp = '\0'; 292 *cp = '\0';
182 havesearch = 0; 293 havesearch = 0;
183 continue; 294 continue;
184 } 295 }
185 /* lookup types */ 296 /* lookup types */
186 if (!strncmp(buf, "lookup", sizeof("lookup") -1)) { 297 if (MATCH(buf, "lookup")) {
187 char *sp = NULL; 298 char *sp = NULL;
188 299
189 bzero(_res.lookups, sizeof _res.lookups); 300 bzero(_resp->lookups, sizeof _resp->lookups);
190 cp = buf + sizeof("lookup") - 1; 301 cp = buf + sizeof("lookup") - 1;
191 for (n = 0;; cp++) { 302 for (n = 0;; cp++) {
192 if (n == MAXDNSLUS) 303 if (n == MAXDNSLUS)
@@ -194,14 +305,14 @@ res_init()
194 if ((*cp == '\0') || (*cp == '\n')) { 305 if ((*cp == '\0') || (*cp == '\n')) {
195 if (sp) { 306 if (sp) {
196 if (*sp=='y' || *sp=='b' || *sp=='f') 307 if (*sp=='y' || *sp=='b' || *sp=='f')
197 _res.lookups[n++] = *sp; 308 _resp->lookups[n++] = *sp;
198 sp = NULL; 309 sp = NULL;
199 } 310 }
200 break; 311 break;
201 } else if ((*cp == ' ') || (*cp == '\t') || (*cp == ',')) { 312 } else if ((*cp == ' ') || (*cp == '\t') || (*cp == ',')) {
202 if (sp) { 313 if (sp) {
203 if (*sp=='y' || *sp=='b' || *sp=='f') 314 if (*sp=='y' || *sp=='b' || *sp=='f')
204 _res.lookups[n++] = *sp; 315 _resp->lookups[n++] = *sp;
205 sp = NULL; 316 sp = NULL;
206 } 317 }
207 } else if (sp == NULL) 318 } else if (sp == NULL)
@@ -210,7 +321,7 @@ res_init()
210 continue; 321 continue;
211 } 322 }
212 /* set search list */ 323 /* set search list */
213 if (!strncmp(buf, "search", sizeof("search") - 1)) { 324 if (MATCH(buf, "search")) {
214 if (haveenv) /* skip if have from environ */ 325 if (haveenv) /* skip if have from environ */
215 continue; 326 continue;
216 cp = buf + sizeof("search") - 1; 327 cp = buf + sizeof("search") - 1;
@@ -218,18 +329,17 @@ res_init()
218 cp++; 329 cp++;
219 if ((*cp == '\0') || (*cp == '\n')) 330 if ((*cp == '\0') || (*cp == '\n'))
220 continue; 331 continue;
221 (void)strncpy(_res.defdname, cp, 332 strlcpy(_resp->defdname, cp, sizeof(_resp->defdname));
222 sizeof(_res.defdname) - 1); 333 if ((cp = strchr(_resp->defdname, '\n')) != NULL)
223 if ((cp = strchr(_res.defdname, '\n')) != NULL)
224 *cp = '\0'; 334 *cp = '\0';
225 /* 335 /*
226 * Set search list to be blank-separated strings 336 * Set search list to be blank-separated strings
227 * on rest of line. 337 * on rest of line.
228 */ 338 */
229 cp = _res.defdname; 339 cp = _resp->defdname;
230 pp = _res.dnsrch; 340 pp = _resp->dnsrch;
231 *pp++ = cp; 341 *pp++ = cp;
232 for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) { 342 for (n = 0; *cp && pp < _resp->dnsrch + MAXDNSRCH; cp++) {
233 if (*cp == ' ' || *cp == '\t') { 343 if (*cp == ' ' || *cp == '\t') {
234 *cp = 0; 344 *cp = 0;
235 n = 1; 345 n = 1;
@@ -247,130 +357,273 @@ res_init()
247 continue; 357 continue;
248 } 358 }
249 /* read nameservers to query */ 359 /* read nameservers to query */
250 if (!strncmp(buf, "nameserver", sizeof("nameserver") - 1) && 360 if (MATCH(buf, "nameserver") && nserv < MAXNS) {
251 nserv < MAXNS) { 361#ifdef INET6
252 struct in_addr a; 362 char *q;
363 struct addrinfo hints, *res;
364 char pbuf[NI_MAXSERV];
365#else
366 struct in_addr a;
367#endif /* INET6 */
253 368
254 cp = buf + sizeof("nameserver") - 1; 369 cp = buf + sizeof("nameserver") - 1;
255 while (*cp == ' ' || *cp == '\t') 370 while (*cp == ' ' || *cp == '\t')
256 cp++; 371 cp++;
372#ifdef INET6
373 if ((*cp == '\0') || (*cp == '\n'))
374 continue;
375 for (q = cp; *q; q++) {
376 if (isspace(*q)) {
377 *q = '\0';
378 break;
379 }
380 }
381 memset(&hints, 0, sizeof(hints));
382 hints.ai_flags = AI_NUMERICHOST;
383 hints.ai_socktype = SOCK_DGRAM;
384 snprintf(pbuf, sizeof(pbuf), "%u", NAMESERVER_PORT);
385 res = NULL;
386 if (getaddrinfo(cp, pbuf, &hints, &res) == 0 &&
387 res->ai_next == NULL) {
388 if (res->ai_addrlen <= sizeof(_res_extp->nsaddr_list[nserv])) {
389 memcpy(&_res_extp->nsaddr_list[nserv], res->ai_addr,
390 res->ai_addrlen);
391 } else {
392 memset(&_res_extp->nsaddr_list[nserv], 0,
393 sizeof(_res_extp->nsaddr_list[nserv]));
394 }
395 if (res->ai_addrlen <= sizeof(_resp->nsaddr_list[nserv])) {
396 memcpy(&_resp->nsaddr_list[nserv], res->ai_addr,
397 res->ai_addrlen);
398 } else {
399 memset(&_resp->nsaddr_list[nserv], 0,
400 sizeof(_resp->nsaddr_list[nserv]));
401 }
402 nserv++;
403 }
404 if (res)
405 freeaddrinfo(res);
406#else /* INET6 */
257 if ((*cp != '\0') && (*cp != '\n') && inet_aton(cp, &a)) { 407 if ((*cp != '\0') && (*cp != '\n') && inet_aton(cp, &a)) {
258 _res.nsaddr_list[nserv].sin_len = sizeof(struct sockaddr_in); 408 _resp->nsaddr_list[nserv].sin_addr = a;
259 _res.nsaddr_list[nserv].sin_family = AF_INET; 409 _resp->nsaddr_list[nserv].sin_family = AF_INET;
260 _res.nsaddr_list[nserv].sin_port = 410 _resp->nsaddr_list[nserv].sin_port =
261 htons(NAMESERVER_PORT); 411 htons(NAMESERVER_PORT);
262 _res.nsaddr_list[nserv].sin_addr = a; 412 _resp->nsaddr_list[nserv].sin_len =
413 sizeof(struct sockaddr_in);
263 nserv++; 414 nserv++;
264 } 415 }
416#endif /* INET6 */
265 continue; 417 continue;
266 } 418 }
267 if (!strncmp(buf, "sortlist", sizeof("sortlist") - 1)) { 419#ifdef RESOLVSORT
420 if (MATCH(buf, "sortlist")) {
268 struct in_addr a; 421 struct in_addr a;
422#ifdef INET6
423 struct in6_addr a6;
424 int m, i;
425 u_char *u;
426#endif /* INET6 */
269 427
270 cp = buf + sizeof("sortlist") - 1; 428 cp = buf + sizeof("sortlist") - 1;
271 while (*cp == ' ' || *cp == '\t') 429 while (nsort < MAXRESOLVSORT) {
272 cp++; 430 while (*cp == ' ' || *cp == '\t')
273 while (sscanf(cp,"%[0-9./]s", buf2) && nsort < MAXRESOLVSORT) { 431 cp++;
274 if (net = strchr(buf2, '/')) 432 if (*cp == '\0' || *cp == '\n' || *cp == ';')
275 *net = '\0'; 433 break;
276 if (inet_aton(buf2, &a)) { 434 net = cp;
277 _res.sort_list[nsort].addr = a; 435 while (*cp && !ISSORTMASK(*cp) && *cp != ';' &&
278 if (net && inet_aton(net+1, &a)) { 436 isascii(*cp) && !isspace(*cp))
279 _res.sort_list[nsort].mask = a.s_addr; 437 cp++;
438 n = *cp;
439 *cp = 0;
440 if (inet_aton(net, &a)) {
441 _resp->sort_list[nsort].addr = a;
442 if (ISSORTMASK(n)) {
443 *cp++ = n;
444 net = cp;
445 while (*cp && *cp != ';' &&
446 isascii(*cp) && !isspace(*cp))
447 cp++;
448 n = *cp;
449 *cp = 0;
450 if (inet_aton(net, &a)) {
451 _resp->sort_list[nsort].mask = a.s_addr;
452 } else {
453 _resp->sort_list[nsort].mask =
454 net_mask(_resp->sort_list[nsort].addr);
455 }
280 } else { 456 } else {
281 _res.sort_list[nsort].mask = 457 _resp->sort_list[nsort].mask =
282 net_mask(_res.sort_list[nsort].addr); 458 net_mask(_resp->sort_list[nsort].addr);
283 } 459 }
460#ifdef INET6
461 _res_extp->sort_list[nsort].af = AF_INET;
462 _res_extp->sort_list[nsort].addr.ina =
463 _resp->sort_list[nsort].addr;
464 _res_extp->sort_list[nsort].mask.ina.s_addr =
465 _resp->sort_list[nsort].mask;
466#endif /* INET6 */
284 nsort++; 467 nsort++;
285 } 468 }
286 if (net) 469#ifdef INET6
287 *net = '/'; 470 else if (inet_pton(AF_INET6, net, &a6) == 1) {
288 cp += strlen(buf2); 471 _res_extp->sort_list[nsort].af = AF_INET6;
289 while (*cp == ' ' || *cp == '\t') 472 _res_extp->sort_list[nsort].addr.in6a = a6;
290 cp++; 473 u = (u_char *)&_res_extp->sort_list[nsort].mask.in6a;
474 *cp++ = n;
475 net = cp;
476 while (*cp && *cp != ';' &&
477 isascii(*cp) && !isspace(*cp))
478 cp++;
479 m = n;
480 n = *cp;
481 *cp = 0;
482 switch (m) {
483 case '/':
484 m = atoi(net);
485 break;
486 case '&':
487 if (inet_pton(AF_INET6, net, u) == 1) {
488 m = -1;
489 break;
490 }
491 /*FALLTHRU*/
492 default:
493 m = sizeof(struct in6_addr) * NBBY;
494 break;
495 }
496 if (m >= 0) {
497 for (i = 0; i < sizeof(struct in6_addr); i++) {
498 if (m <= 0) {
499 *u = 0;
500 } else {
501 m -= NBBY;
502 *u = (u_char)~0;
503 if (m < 0)
504 *u <<= -m;
505 }
506 u++;
507 }
508 }
509 nsort++;
510 }
511#endif /* INET6 */
512 *cp = n;
291 } 513 }
292 continue; 514 continue;
293 } 515 }
294 if (!strncmp(buf, "options", sizeof("options") -1)) { 516#endif
517 if (MATCH(buf, "options")) {
295 res_setoptions(buf + sizeof("options") - 1, "conf"); 518 res_setoptions(buf + sizeof("options") - 1, "conf");
296 continue; 519 continue;
297 } 520 }
298 } 521 }
299 if (nserv > 1) 522 if (nserv > 1)
300 _res.nscount = nserv; 523 _resp->nscount = nserv;
301 _res.nsort = nsort; 524#ifdef RESOLVSORT
525 _resp->nsort = nsort;
526#endif
302 (void) fclose(fp); 527 (void) fclose(fp);
303 } 528 }
304 if (_res.defdname[0] == 0) { 529 if (_resp->defdname[0] == 0 &&
305 if (gethostname(buf, sizeof(_res.defdname) - 1) == 0 && 530 gethostname(buf, sizeof(_resp->defdname) - 1) == 0 &&
306 (cp = strchr(buf, '.'))) 531 (cp = strchr(buf, '.')) != NULL)
307 (void)strcpy(_res.defdname, cp + 1); 532 {
533 strlcpy(_resp->defdname, cp + 1,
534 sizeof(_resp->defdname));
308 } 535 }
309 536
310 /* find components of local domain that might be searched */ 537 /* find components of local domain that might be searched */
311 if (havesearch == 0) { 538 if (havesearch == 0) {
312 pp = _res.dnsrch; 539 pp = _resp->dnsrch;
313 *pp++ = _res.defdname; 540 *pp++ = _resp->defdname;
314#ifndef SEARCH_LOCAL_DOMAINS
315 *pp = NULL; 541 *pp = NULL;
316#else 542
317 for (cp = _res.defdname, n = 0; *cp; cp++) 543#ifndef RFC1535
318 if (*cp == '.') 544 dots = 0;
319 n++; 545 for (cp = _resp->defdname; *cp; cp++)
320 cp = _res.defdname; 546 dots += (*cp == '.');
321 for (; n >= LOCALDOMAINPARTS && pp < _res.dnsrch + MAXDFLSRCH; 547
322 n--) { 548 cp = _resp->defdname;
323 cp = strchr(cp, '.'); 549 while (pp < _resp->dnsrch + MAXDFLSRCH) {
324 *pp++ = ++cp; 550 if (dots < LOCALDOMAINPARTS)
551 break;
552 cp = strchr(cp, '.') + 1; /* we know there is one */
553 *pp++ = cp;
554 dots--;
325 } 555 }
326 *pp++ = 0; 556 *pp = NULL;
327#endif 557#ifdef DEBUG
558 if (_resp->options & RES_DEBUG) {
559 printf(";; res_init()... default dnsrch list:\n");
560 for (pp = _resp->dnsrch; *pp; pp++)
561 printf(";;\t%s\n", *pp);
562 printf(";;\t..END..\n");
563 }
564#endif /* DEBUG */
565#endif /* !RFC1535 */
328 } 566 }
329 567
330 if ((cp = getenv("RES_OPTIONS")) != NULL) 568 if (issetugid())
569 _resp->options |= RES_NOALIASES;
570 else if ((cp = getenv("RES_OPTIONS")) != NULL)
331 res_setoptions(cp, "env"); 571 res_setoptions(cp, "env");
332 _res.options |= RES_INIT; 572 _resp->options |= RES_INIT;
333 return (0); 573 return (0);
334} 574}
335 575
576/* ARGSUSED */
336static void 577static void
337res_setoptions(options, source) 578res_setoptions(options, source)
338 char *options, *source; 579 char *options, *source;
339{ 580{
581 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
340 char *cp = options; 582 char *cp = options;
341 int i; 583 char *endp;
584 long l;
342 585
343#ifdef DEBUG 586#ifdef DEBUG
344 if (_res.options & RES_DEBUG) { 587 if (_resp->options & RES_DEBUG)
345 printf(";; res_setoptions(\"%s\", \"%s\")...\n", 588 printf(";; res_setoptions(\"%s\", \"%s\")...\n",
346 options, source); 589 options, source);
347 }
348#endif 590#endif
349 while (*cp) { 591 while (*cp) {
350 /* skip leading and inner runs of spaces */ 592 /* skip leading and inner runs of spaces */
351 while (*cp == ' ' || *cp == '\t') 593 while (*cp == ' ' || *cp == '\t')
352 cp++; 594 cp++;
353 /* search for and process individual options */ 595 /* search for and process individual options */
354 if (!strncmp(cp, "ndots:", sizeof("ndots:")-1)) { 596 if (!strncmp(cp, "ndots:", sizeof("ndots:") - 1)) {
355 i = atoi(cp + sizeof("ndots:") - 1); 597 char *p = cp + sizeof("ndots:") - 1;
356 if (i <= RES_MAXNDOTS) 598 l = strtol(p, &endp, 10);
357 _res.ndots = i; 599 if (l >= 0 && endp != p &&
358 else 600 (*endp = '\0' || isspace(*endp))) {
359 _res.ndots = RES_MAXNDOTS; 601 if (l <= RES_MAXNDOTS)
602 _resp->ndots = l;
603 else
604 _resp->ndots = RES_MAXNDOTS;
360#ifdef DEBUG 605#ifdef DEBUG
361 if (_res.options & RES_DEBUG) { 606 if (_resp->options & RES_DEBUG)
362 printf(";;\tndots=%d\n", _res.ndots); 607 printf(";;\tndots=%u\n", _resp->ndots);
363 }
364#endif 608#endif
365 } else if (!strncmp(cp, "debug", sizeof("debug")-1)) { 609 }
610 } else if (!strncmp(cp, "debug", sizeof("debug") - 1)) {
366#ifdef DEBUG 611#ifdef DEBUG
367 if (!(_res.options & RES_DEBUG)) { 612 if (!(_resp->options & RES_DEBUG)) {
368 printf(";; res_setoptions(\"%s\", \"%s\")..\n", 613 printf(";; res_setoptions(\"%s\", \"%s\")..\n",
369 options, source); 614 options, source);
370 _res.options |= RES_DEBUG; 615 _resp->options |= RES_DEBUG;
371 } 616 }
372 printf(";;\tdebug\n"); 617 printf(";;\tdebug\n");
373#endif 618#endif
619 } else if (!strncmp(cp, "inet6", sizeof("inet6") - 1)) {
620 _resp->options |= RES_USE_INET6;
621 } else if (!strncmp(cp, "insecure1", sizeof("insecure1") - 1)) {
622 _resp->options |= RES_INSECURE1;
623 } else if (!strncmp(cp, "insecure2", sizeof("insecure2") - 1)) {
624 _resp->options |= RES_INSECURE2;
625 } else if (!strncmp(cp, "edns0", sizeof("edns0") - 1)) {
626 _resp->options |= RES_USE_EDNS0;
374 } else { 627 } else {
375 /* XXX - print a warning here? */ 628 /* XXX - print a warning here? */
376 } 629 }
@@ -380,6 +633,8 @@ res_setoptions(options, source)
380 } 633 }
381} 634}
382 635
636#ifdef RESOLVSORT
637/* XXX - should really support CIDR which means explicit masks always. */
383static u_int32_t 638static u_int32_t
384net_mask(in) /* XXX - should really use system's version of this */ 639net_mask(in) /* XXX - should really use system's version of this */
385 struct in_addr in; 640 struct in_addr in;
@@ -388,7 +643,8 @@ net_mask(in) /* XXX - should really use system's version of this */
388 643
389 if (IN_CLASSA(i)) 644 if (IN_CLASSA(i))
390 return (htonl(IN_CLASSA_NET)); 645 return (htonl(IN_CLASSA_NET));
391 if (IN_CLASSB(i)) 646 else if (IN_CLASSB(i))
392 return (htonl(IN_CLASSB_NET)); 647 return (htonl(IN_CLASSB_NET));
393 return (htonl(IN_CLASSC_NET)); 648 return (htonl(IN_CLASSC_NET));
394} 649}
650#endif
diff --git a/src/lib/libc/net/res_mkquery.c b/src/lib/libc/net/res_mkquery.c
index 25f025e147..82aa2796c2 100644
--- a/src/lib/libc/net/res_mkquery.c
+++ b/src/lib/libc/net/res_mkquery.c
@@ -1,9 +1,11 @@
1/* $NetBSD: res_mkquery.c,v 1.5 1995/02/25 06:20:58 cgd Exp $ */ 1/* $OpenBSD: res_mkquery.c,v 1.14 2003/06/02 20:18:36 millert Exp $ */
2 2
3/*- 3/*
4 * ++Copyright++ 1985, 1993
5 * -
4 * Copyright (c) 1985, 1993 6 * Copyright (c) 1985, 1993
5 * The Regents of the University of California. All rights reserved. 7 * The Regents of the University of California. All rights reserved.
6 * 8 *
7 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
9 * are met: 11 * are met:
@@ -12,14 +14,10 @@
12 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 15 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 16 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 17 * 3. Neither the name of the University nor the names of its contributors
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 18 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission. 19 * without specific prior written permission.
22 * 20 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -56,98 +54,115 @@
56#if defined(LIBC_SCCS) && !defined(lint) 54#if defined(LIBC_SCCS) && !defined(lint)
57#if 0 55#if 0
58static char sccsid[] = "@(#)res_mkquery.c 8.1 (Berkeley) 6/4/93"; 56static char sccsid[] = "@(#)res_mkquery.c 8.1 (Berkeley) 6/4/93";
59static char rcsid[] = "$Id: res_mkquery.c,v 4.9.1.2 1993/05/17 10:00:01 vixie Exp "; 57static char rcsid[] = "$From: res_mkquery.c,v 8.5 1996/08/27 08:33:28 vixie Exp $";
60#else 58#else
61static char rcsid[] = "$NetBSD: res_mkquery.c,v 1.5 1995/02/25 06:20:58 cgd Exp $"; 59static char rcsid[] = "$OpenBSD: res_mkquery.c,v 1.14 2003/06/02 20:18:36 millert Exp $";
62#endif 60#endif
63#endif /* LIBC_SCCS and not lint */ 61#endif /* LIBC_SCCS and not lint */
64 62
63#include <sys/types.h>
65#include <sys/param.h> 64#include <sys/param.h>
66#include <netinet/in.h> 65#include <netinet/in.h>
67#include <arpa/nameser.h> 66#include <arpa/nameser.h>
68#include <resolv.h> 67
69#include <stdio.h> 68#include <stdio.h>
69#include <netdb.h>
70#include <resolv.h>
70#include <string.h> 71#include <string.h>
71 72
73#include "thread_private.h"
74
72/* 75/*
73 * Form all types of queries. 76 * Form all types of queries.
74 * Returns the size of the result or -1. 77 * Returns the size of the result or -1.
75 */ 78 */
79/* ARGSUSED */
80int
76res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen) 81res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
77 int op; /* opcode of query */ 82 int op; /* opcode of query */
78 const char *dname; /* domain name */ 83 const char *dname; /* domain name */
79 int class, type; /* class and type of query */ 84 int class, type; /* class and type of query */
80 const char *data; /* resource record data */ 85 const u_char *data; /* resource record data */
81 int datalen; /* length of data */ 86 int datalen; /* length of data */
82 const char *newrr_in; /* new rr for modify or append */ 87 const u_char *newrr_in; /* new rr for modify or append */
83 char *buf; /* buffer to put query */ 88 u_char *buf; /* buffer to put query */
84 int buflen; /* size of buffer */ 89 int buflen; /* size of buffer */
85{ 90{
91 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
86 register HEADER *hp; 92 register HEADER *hp;
87 register char *cp; 93 register u_char *cp, *ep;
88 register int n; 94 register int n;
89 struct rrec *newrr = (struct rrec *) newrr_in; 95 u_char *dnptrs[20], **dpp, **lastdnptr;
90 char *dnptrs[10], **dpp, **lastdnptr;
91 96
97 if ((_resp->options & RES_INIT) == 0 && res_init() == -1) {
98 h_errno = NETDB_INTERNAL;
99 return (-1);
100 }
92#ifdef DEBUG 101#ifdef DEBUG
93 if (_res.options & RES_DEBUG) 102 if (_resp->options & RES_DEBUG)
94 printf(";; res_mkquery(%d, %s, %d, %d)\n", 103 printf(";; res_mkquery(%d, %s, %d, %d)\n",
95 op, dname, class, type); 104 op, dname, class, type);
96#endif 105#endif
97 /* 106 /*
98 * Initialize header fields. 107 * Initialize header fields.
108 *
109 * A special random number generator is used to create non predictable
110 * and non repeating ids over a long period. It also avoids reuse
111 * by switching between two distinct number cycles.
99 */ 112 */
100 if ((buf == NULL) || (buflen < sizeof(HEADER))) 113
101 return(-1); 114 if ((buf == NULL) || (buflen < HFIXEDSZ))
102 bzero(buf, sizeof(HEADER)); 115 return (-1);
116 bzero(buf, HFIXEDSZ);
103 hp = (HEADER *) buf; 117 hp = (HEADER *) buf;
104 hp->id = htons(++_res.id); 118 _resp->id = res_randomid();
119 hp->id = htons(_resp->id);
105 hp->opcode = op; 120 hp->opcode = op;
106 hp->pr = (_res.options & RES_PRIMARY) != 0; 121 hp->rd = (_resp->options & RES_RECURSE) != 0;
107 hp->rd = (_res.options & RES_RECURSE) != 0;
108 hp->rcode = NOERROR; 122 hp->rcode = NOERROR;
109 cp = buf + sizeof(HEADER); 123 cp = buf + HFIXEDSZ;
110 buflen -= sizeof(HEADER); 124 ep = buf + buflen;
111 dpp = dnptrs; 125 dpp = dnptrs;
112 *dpp++ = buf; 126 *dpp++ = buf;
113 *dpp++ = NULL; 127 *dpp++ = NULL;
114 lastdnptr = dnptrs + sizeof(dnptrs)/sizeof(dnptrs[0]); 128 lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0];
115 /* 129 /*
116 * perform opcode specific processing 130 * perform opcode specific processing
117 */ 131 */
118 switch (op) { 132 switch (op) {
119 case QUERY: 133 case QUERY: /*FALLTHROUGH*/
120 if ((buflen -= QFIXEDSZ) < 0) 134 case NS_NOTIFY_OP:
121 return(-1); 135 if (ep - cp < QFIXEDSZ)
122 if ((n = dn_comp((u_char *)dname, (u_char *)cp, buflen, 136 return (-1);
123 (u_char **)dnptrs, (u_char **)lastdnptr)) < 0) 137 if ((n = dn_comp(dname, cp, ep - cp - QFIXEDSZ, dnptrs,
138 lastdnptr)) < 0)
124 return (-1); 139 return (-1);
125 cp += n; 140 cp += n;
126 buflen -= n; 141 __putshort(type, cp);
127 __putshort(type, (u_char *)cp); 142 cp += INT16SZ;
128 cp += sizeof(u_int16_t); 143 __putshort(class, cp);
129 __putshort(class, (u_char *)cp); 144 cp += INT16SZ;
130 cp += sizeof(u_int16_t);
131 hp->qdcount = htons(1); 145 hp->qdcount = htons(1);
132 if (op == QUERY || data == NULL) 146 if (op == QUERY || data == NULL)
133 break; 147 break;
134 /* 148 /*
135 * Make an additional record for completion domain. 149 * Make an additional record for completion domain.
136 */ 150 */
137 buflen -= RRFIXEDSZ; 151 if (ep - cp < RRFIXEDSZ)
138 if ((n = dn_comp((u_char *)data, (u_char *)cp, buflen, 152 return (-1);
139 (u_char **)dnptrs, (u_char **)lastdnptr)) < 0) 153 n = dn_comp((char *)data, cp, ep - cp - RRFIXEDSZ, dnptrs,
154 lastdnptr);
155 if (n < 0)
140 return (-1); 156 return (-1);
141 cp += n; 157 cp += n;
142 buflen -= n; 158 __putshort(T_NULL, cp);
143 __putshort(T_NULL, (u_char *)cp); 159 cp += INT16SZ;
144 cp += sizeof(u_int16_t); 160 __putshort(class, cp);
145 __putshort(class, (u_char *)cp); 161 cp += INT16SZ;
146 cp += sizeof(u_int16_t); 162 __putlong(0, cp);
147 __putlong(0, (u_char *)cp); 163 cp += INT32SZ;
148 cp += sizeof(u_int32_t); 164 __putshort(0, cp);
149 __putshort(0, (u_char *)cp); 165 cp += INT16SZ;
150 cp += sizeof(u_int16_t);
151 hp->arcount = htons(1); 166 hp->arcount = htons(1);
152 break; 167 break;
153 168
@@ -155,82 +170,73 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
155 /* 170 /*
156 * Initialize answer section 171 * Initialize answer section
157 */ 172 */
158 if (buflen < 1 + RRFIXEDSZ + datalen) 173 if (ep - cp < 1 + RRFIXEDSZ + datalen)
159 return (-1); 174 return (-1);
160 *cp++ = '\0'; /* no domain name */ 175 *cp++ = '\0'; /* no domain name */
161 __putshort(type, (u_char *)cp);
162 cp += sizeof(u_int16_t);
163 __putshort(class, (u_char *)cp);
164 cp += sizeof(u_int16_t);
165 __putlong(0, (u_char *)cp);
166 cp += sizeof(u_int32_t);
167 __putshort(datalen, (u_char *)cp);
168 cp += sizeof(u_int16_t);
169 if (datalen) {
170 bcopy(data, cp, datalen);
171 cp += datalen;
172 }
173 hp->ancount = htons(1);
174 break;
175
176#ifdef ALLOW_UPDATES
177 /*
178 * For UPDATEM/UPDATEMA, do UPDATED/UPDATEDA followed by UPDATEA
179 * (Record to be modified is followed by its replacement in msg.)
180 */
181 case UPDATEM:
182 case UPDATEMA:
183
184 case UPDATED:
185 /*
186 * The res code for UPDATED and UPDATEDA is the same; user
187 * calls them differently: specifies data for UPDATED; server
188 * ignores data if specified for UPDATEDA.
189 */
190 case UPDATEDA:
191 buflen -= RRFIXEDSZ + datalen;
192 if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
193 return (-1);
194 cp += n;
195 __putshort(type, cp); 176 __putshort(type, cp);
196 cp += sizeof(u_int16_t); 177 cp += INT16SZ;
197 __putshort(class, cp); 178 __putshort(class, cp);
198 cp += sizeof(u_int16_t); 179 cp += INT16SZ;
199 __putlong(0, cp); 180 __putlong(0, cp);
200 cp += sizeof(u_int32_t); 181 cp += INT32SZ;
201 __putshort(datalen, cp); 182 __putshort(datalen, cp);
202 cp += sizeof(u_int16_t); 183 cp += INT16SZ;
203 if (datalen) { 184 if (datalen) {
204 bcopy(data, cp, datalen); 185 bcopy(data, cp, datalen);
205 cp += datalen; 186 cp += datalen;
206 } 187 }
207 if ( (op == UPDATED) || (op == UPDATEDA) ) { 188 hp->ancount = htons(1);
208 hp->ancount = htons(0);
209 break;
210 }
211 /* Else UPDATEM/UPDATEMA, so drop into code for UPDATEA */
212
213 case UPDATEA: /* Add new resource record */
214 buflen -= RRFIXEDSZ + datalen;
215 if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
216 return (-1);
217 cp += n;
218 __putshort(newrr->r_type, cp);
219 cp += sizeof(u_int16_t);
220 __putshort(newrr->r_class, cp);
221 cp += sizeof(u_int16_t);
222 __putlong(0, cp);
223 cp += sizeof(u_int32_t);
224 __putshort(newrr->r_size, cp);
225 cp += sizeof(u_int16_t);
226 if (newrr->r_size) {
227 bcopy(newrr->r_data, cp, newrr->r_size);
228 cp += newrr->r_size;
229 }
230 hp->ancount = htons(0);
231 break; 189 break;
232 190
233#endif /* ALLOW_UPDATES */ 191 default:
192 return (-1);
234 } 193 }
235 return (cp - buf); 194 return (cp - buf);
236} 195}
196
197/* attach OPT pseudo-RR, as documented in RFC2671 (EDNS0). */
198int
199res_opt(n0, buf, buflen, anslen)
200 int n0;
201 u_char *buf; /* buffer to put query */
202 int buflen; /* size of buffer */
203 int anslen; /* answer buffer length */
204{
205 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
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 (_resp->options & RES_USE_DNSSEC) {
227#ifdef DEBUG
228 if (_resp->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
index 7649462e56..3cdb7a7477 100644
--- a/src/lib/libc/net/res_query.c
+++ b/src/lib/libc/net/res_query.c
@@ -1,9 +1,11 @@
1/* $NetBSD: res_query.c,v 1.9 1995/02/25 06:58:58 cgd Exp $ */ 1/* $OpenBSD: res_query.c,v 1.21 2003/06/02 20:18:36 millert Exp $ */
2 2
3/*- 3/*
4 * ++Copyright++ 1988, 1993
5 * -
4 * Copyright (c) 1988, 1993 6 * Copyright (c) 1988, 1993
5 * The Regents of the University of California. All rights reserved. 7 * The Regents of the University of California. All rights reserved.
6 * 8 *
7 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
9 * are met: 11 * are met:
@@ -12,14 +14,10 @@
12 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 15 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 16 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 17 * 3. Neither the name of the University nor the names of its contributors
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 18 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission. 19 * without specific prior written permission.
22 * 20 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -56,23 +54,28 @@
56#if defined(LIBC_SCCS) && !defined(lint) 54#if defined(LIBC_SCCS) && !defined(lint)
57#if 0 55#if 0
58static char sccsid[] = "@(#)res_query.c 8.1 (Berkeley) 6/4/93"; 56static char sccsid[] = "@(#)res_query.c 8.1 (Berkeley) 6/4/93";
59static char rcsid[] = "$Id: res_query.c,v 1.1 1993/06/01 09:42:14 vixie Exp vixie "; 57static char rcsid[] = "$From: res_query.c,v 8.9 1996/09/22 00:13:28 vixie Exp $";
60#else 58#else
61static char rcsid[] = "$NetBSD: res_query.c,v 1.9 1995/02/25 06:58:58 cgd Exp $"; 59static char rcsid[] = "$OpenBSD: res_query.c,v 1.21 2003/06/02 20:18:36 millert Exp $";
62#endif 60#endif
63#endif /* LIBC_SCCS and not lint */ 61#endif /* LIBC_SCCS and not lint */
64 62
63#include <sys/types.h>
65#include <sys/param.h> 64#include <sys/param.h>
66#include <netinet/in.h> 65#include <netinet/in.h>
67#include <arpa/inet.h> 66#include <arpa/inet.h>
68#include <arpa/nameser.h> 67#include <arpa/nameser.h>
68
69#include <stdio.h>
69#include <netdb.h> 70#include <netdb.h>
70#include <resolv.h> 71#include <resolv.h>
71#include <stdio.h>
72#include <ctype.h> 72#include <ctype.h>
73#include <errno.h> 73#include <errno.h>
74#include <stdlib.h> 74#include <stdlib.h>
75#include <string.h> 75#include <string.h>
76#include <unistd.h>
77
78#include "thread_private.h"
76 79
77#if PACKETSZ > 1024 80#if PACKETSZ > 1024
78#define MAXPACKET PACKETSZ 81#define MAXPACKET PACKETSZ
@@ -80,8 +83,9 @@ static char rcsid[] = "$NetBSD: res_query.c,v 1.9 1995/02/25 06:58:58 cgd Exp $"
80#define MAXPACKET 1024 83#define MAXPACKET 1024
81#endif 84#endif
82 85
83char *__hostalias __P((const char *)); 86const char *hostalias(const char *);
84int h_errno; 87int h_errno;
88extern int res_opt(int, u_char *, int, int);
85 89
86/* 90/*
87 * Formulate a normal query, send, and await answer. 91 * Formulate a normal query, send, and await answer.
@@ -90,68 +94,79 @@ int h_errno;
90 * if no error is indicated and the answer count is nonzero. 94 * if no error is indicated and the answer count is nonzero.
91 * Return the size of the response on success, -1 on error. 95 * Return the size of the response on success, -1 on error.
92 * Error number is left in h_errno. 96 * Error number is left in h_errno.
97 *
93 * Caller must parse answer and determine whether it answers the question. 98 * Caller must parse answer and determine whether it answers the question.
94 */ 99 */
100int
95res_query(name, class, type, answer, anslen) 101res_query(name, class, type, answer, anslen)
96 char *name; /* domain name */ 102 const char *name; /* domain name */
97 int class, type; /* class and type of query */ 103 int class, type; /* class and type of query */
98 u_char *answer; /* buffer to put answer */ 104 u_char *answer; /* buffer to put answer */
99 int anslen; /* size of answer buffer */ 105 int anslen; /* size of answer buffer */
100{ 106{
101 char buf[MAXPACKET]; 107 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
102 HEADER *hp; 108 u_char buf[MAXPACKET];
109 register HEADER *hp = (HEADER *) answer;
103 int n; 110 int n;
104 111
105 if ((_res.options & RES_INIT) == 0 && res_init() == -1) 112 hp->rcode = NOERROR; /* default */
113
114 if ((_resp->options & RES_INIT) == 0 && res_init() == -1) {
115 h_errno = NETDB_INTERNAL;
106 return (-1); 116 return (-1);
117 }
107#ifdef DEBUG 118#ifdef DEBUG
108 if (_res.options & RES_DEBUG) 119 if (_resp->options & RES_DEBUG)
109 printf(";; res_query(%s, %d, %d)\n", name, class, type); 120 printf(";; res_query(%s, %d, %d)\n", name, class, type);
110#endif 121#endif
111 n = res_mkquery(QUERY, name, class, type, (char *)NULL, 0, NULL, 122
112 buf, sizeof(buf)); 123 n = res_mkquery(QUERY, name, class, type, NULL, 0, NULL,
124 buf, sizeof(buf));
125 if (n > 0 && ((_resp->options & RES_USE_EDNS0) ||
126 (_resp->options & RES_USE_DNSSEC))) {
127 n = res_opt(n, buf, sizeof(buf), anslen);
128 }
113 129
114 if (n <= 0) { 130 if (n <= 0) {
115#ifdef DEBUG 131#ifdef DEBUG
116 if (_res.options & RES_DEBUG) 132 if (_resp->options & RES_DEBUG)
117 printf(";; res_query: mkquery failed\n"); 133 printf(";; res_query: mkquery failed\n");
118#endif 134#endif
119 h_errno = NO_RECOVERY; 135 h_errno = NO_RECOVERY;
120 return (n); 136 return (n);
121 } 137 }
122 n = res_send(buf, n, (char *)answer, anslen); 138 n = res_send(buf, n, answer, anslen);
123 if (n < 0) { 139 if (n < 0) {
124#ifdef DEBUG 140#ifdef DEBUG
125 if (_res.options & RES_DEBUG) 141 if (_resp->options & RES_DEBUG)
126 printf(";; res_query: send error\n"); 142 printf(";; res_query: send error\n");
127#endif 143#endif
128 h_errno = TRY_AGAIN; 144 h_errno = TRY_AGAIN;
129 return (n); 145 return (n);
130 } 146 }
131 147
132 hp = (HEADER *) answer;
133 if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) { 148 if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) {
134#ifdef DEBUG 149#ifdef DEBUG
135 if (_res.options & RES_DEBUG) 150 if (_resp->options & RES_DEBUG)
136 printf(";; rcode = %d, ancount=%d\n", hp->rcode, 151 printf(";; rcode = %u, ancount=%u\n", hp->rcode,
137 ntohs(hp->ancount)); 152 ntohs(hp->ancount));
138#endif 153#endif
139 switch (hp->rcode) { 154 switch (hp->rcode) {
140 case NXDOMAIN: 155 case NXDOMAIN:
141 h_errno = HOST_NOT_FOUND; 156 h_errno = HOST_NOT_FOUND;
142 break; 157 break;
143 case SERVFAIL: 158 case SERVFAIL:
144 h_errno = TRY_AGAIN; 159 h_errno = TRY_AGAIN;
145 break; 160 break;
146 case NOERROR: 161 case NOERROR:
147 h_errno = NO_DATA; 162 h_errno = NO_DATA;
148 break; 163 break;
149 case FORMERR: 164 case FORMERR:
150 case NOTIMP: 165 case NOTIMP:
151 case REFUSED: 166 case REFUSED:
152 default: 167 default:
153 h_errno = NO_RECOVERY; 168 h_errno = NO_RECOVERY;
154 break; 169 break;
155 } 170 }
156 return (-1); 171 return (-1);
157 } 172 }
@@ -162,9 +177,7 @@ res_query(name, class, type, answer, anslen)
162 * Formulate a normal query, send, and retrieve answer in supplied buffer. 177 * Formulate a normal query, send, and retrieve answer in supplied buffer.
163 * Return the size of the response on success, -1 on error. 178 * Return the size of the response on success, -1 on error.
164 * If enabled, implement search rules until answer or unrecoverable failure 179 * If enabled, implement search rules until answer or unrecoverable failure
165 * is detected. Error number is left in h_errno. 180 * is detected. Error code, if any, is left in h_errno.
166 * Only useful for queries in the same name hierarchy as the local host
167 * (not, for example, for host address-to-name lookups in domain in-addr.arpa).
168 */ 181 */
169int 182int
170res_search(name, class, type, answer, anslen) 183res_search(name, class, type, answer, anslen)
@@ -173,28 +186,30 @@ res_search(name, class, type, answer, anslen)
173 u_char *answer; /* buffer to put answer */ 186 u_char *answer; /* buffer to put answer */
174 int anslen; /* size of answer */ 187 int anslen; /* size of answer */
175{ 188{
176 register char *cp, **domain; 189 register const char *cp, * const *domain;
177 int dots, trailing_dot, ret, got_nodata, saved_herrno, tried_as_is; 190 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
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;
178 195
179 if ((_res.options & RES_INIT) == 0 && res_init() == -1) 196 if ((_resp->options & RES_INIT) == 0 && res_init() == -1) {
197 h_errno = NETDB_INTERNAL;
180 return (-1); 198 return (-1);
181 199 }
182 got_nodata = 0;
183 errno = 0; 200 errno = 0;
184 h_errno = HOST_NOT_FOUND; /* default, if we never query */ 201 h_errno = HOST_NOT_FOUND; /* default, if we never query */
185 dots = 0; 202 dots = 0;
186 for (cp = (char *)name; *cp; cp++) { 203 for (cp = name; *cp; cp++)
187 if (*cp == '.') 204 dots += (*cp == '.');
188 dots++;
189 }
190 trailing_dot = 0; 205 trailing_dot = 0;
191 if ((cp > name) && (*--cp == '.')) 206 if (cp > name && *--cp == '.')
192 trailing_dot++; 207 trailing_dot++;
193 208
194 /* 209 /*
195 * if there aren't any dots, it could be a user-level alias 210 * if there aren't any dots, it could be a user-level alias
196 */ 211 */
197 if (!dots && (cp = __hostalias(name))) 212 if (!dots && (cp = __hostalias(name)) != NULL)
198 return (res_query(cp, class, type, answer, anslen)); 213 return (res_query(cp, class, type, answer, anslen));
199 214
200 /* 215 /*
@@ -202,8 +217,7 @@ res_search(name, class, type, answer, anslen)
202 * 'as is'. The threshold can be set with the "ndots" option. 217 * 'as is'. The threshold can be set with the "ndots" option.
203 */ 218 */
204 saved_herrno = -1; 219 saved_herrno = -1;
205 tried_as_is = 0; 220 if (dots >= _resp->ndots) {
206 if (dots >= _res.ndots) {
207 ret = res_querydomain(name, NULL, class, type, answer, anslen); 221 ret = res_querydomain(name, NULL, class, type, answer, anslen);
208 if (ret > 0) 222 if (ret > 0)
209 return (ret); 223 return (ret);
@@ -217,15 +231,19 @@ res_search(name, class, type, answer, anslen)
217 * - there is at least one dot, there is no trailing dot, 231 * - there is at least one dot, there is no trailing dot,
218 * and RES_DNSRCH is set. 232 * and RES_DNSRCH is set.
219 */ 233 */
220 if ((!dots && (_res.options & RES_DEFNAMES)) || 234 if ((!dots && (_resp->options & RES_DEFNAMES)) ||
221 (dots && !trailing_dot && (_res.options & RES_DNSRCH))) { 235 (dots && !trailing_dot && (_resp->options & RES_DNSRCH))) {
222 for (domain = _res.dnsrch; *domain; domain++) { 236 int done = 0;
223 int done = 0; 237
238 for (domain = (const char * const *)_resp->dnsrch;
239 *domain && !done;
240 domain++) {
224 241
225 ret = res_querydomain(name, *domain, class, type, 242 ret = res_querydomain(name, *domain, class, type,
226 answer, anslen); 243 answer, anslen);
227 if (ret > 0) 244 if (ret > 0)
228 return (ret); 245 return (ret);
246
229 /* 247 /*
230 * If no server present, give up. 248 * If no server present, give up.
231 * If name isn't found in this domain, 249 * If name isn't found in this domain,
@@ -251,24 +269,27 @@ res_search(name, class, type, answer, anslen)
251 case HOST_NOT_FOUND: 269 case HOST_NOT_FOUND:
252 /* keep trying */ 270 /* keep trying */
253 break; 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 */
254 default: 279 default:
255 /* anything else implies that we're done */ 280 /* anything else implies that we're done */
256 done++; 281 done++;
257 } 282 }
258 /* 283
259 * if we got here for some reason other than DNSRCH, 284 /* if we got here for some reason other than DNSRCH,
260 * we only wanted one iteration of the loop, so stop. 285 * we only wanted one iteration of the loop, so stop.
261 */ 286 */
262 if (!(_res.options & RES_DNSRCH)) 287 if (!(_resp->options & RES_DNSRCH))
263 done++; 288 done++;
264
265 if (done)
266 break;
267 } 289 }
268 } 290 }
269 291
270 /* 292 /* if we have not already tried the name "as is", do that now.
271 * if we have not already tried the name "as is", do that now.
272 * note that we do this regardless of how many dots were in the 293 * note that we do this regardless of how many dots were in the
273 * name or whether it ends with a dot. 294 * name or whether it ends with a dot.
274 */ 295 */
@@ -276,11 +297,9 @@ res_search(name, class, type, answer, anslen)
276 ret = res_querydomain(name, NULL, class, type, answer, anslen); 297 ret = res_querydomain(name, NULL, class, type, answer, anslen);
277 if (ret > 0) 298 if (ret > 0)
278 return (ret); 299 return (ret);
279 saved_herrno = h_errno;
280 } 300 }
281 301
282 /* 302 /* if we got here, we didn't satisfy the search.
283 * if we got here, we didn't satisfy the search.
284 * if we did an initial full query, return that query's h_errno 303 * if we did an initial full query, return that query's h_errno
285 * (note that we wouldn't be here if that query had succeeded). 304 * (note that we wouldn't be here if that query had succeeded).
286 * else if we ever got a nodata, send that back as the reason. 305 * else if we ever got a nodata, send that back as the reason.
@@ -291,6 +310,8 @@ res_search(name, class, type, answer, anslen)
291 h_errno = saved_herrno; 310 h_errno = saved_herrno;
292 else if (got_nodata) 311 else if (got_nodata)
293 h_errno = NO_DATA; 312 h_errno = NO_DATA;
313 else if (got_servfail)
314 h_errno = TRY_AGAIN;
294 return (-1); 315 return (-1);
295} 316}
296 317
@@ -298,20 +319,26 @@ res_search(name, class, type, answer, anslen)
298 * Perform a call on res_query on the concatenation of name and domain, 319 * Perform a call on res_query on the concatenation of name and domain,
299 * removing a trailing dot from name if domain is NULL. 320 * removing a trailing dot from name if domain is NULL.
300 */ 321 */
322int
301res_querydomain(name, domain, class, type, answer, anslen) 323res_querydomain(name, domain, class, type, answer, anslen)
302 char *name, *domain; 324 const char *name, *domain;
303 int class, type; /* class and type of query */ 325 int class, type; /* class and type of query */
304 u_char *answer; /* buffer to put answer */ 326 u_char *answer; /* buffer to put answer */
305 int anslen; /* size of answer */ 327 int anslen; /* size of answer */
306{ 328{
307 char nbuf[2*MAXDNAME+2]; 329 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
308 char *longname = nbuf; 330 char nbuf[MAXDNAME*2+1+1];
331 const char *longname = nbuf;
309 int n; 332 int n;
310 333
334 if ((_resp->options & RES_INIT) == 0 && res_init() == -1) {
335 h_errno = NETDB_INTERNAL;
336 return (-1);
337 }
311#ifdef DEBUG 338#ifdef DEBUG
312 if (_res.options & RES_DEBUG) 339 if (_resp->options & RES_DEBUG)
313 printf(";; res_querydomain(%s, %s, %d, %d)\n", 340 printf(";; res_querydomain(%s, %s, %d, %d)\n",
314 name, domain, class, type); 341 name, domain?domain:"<Nil>", class, type);
315#endif 342#endif
316 if (domain == NULL) { 343 if (domain == NULL) {
317 /* 344 /*
@@ -325,38 +352,52 @@ res_querydomain(name, domain, class, type, answer, anslen)
325 } else 352 } else
326 longname = name; 353 longname = name;
327 } else 354 } else
328 (void)sprintf(nbuf, "%.*s.%.*s", 355 snprintf(nbuf, sizeof nbuf, "%.*s.%.*s",
329 MAXDNAME, name, MAXDNAME, domain); 356 MAXDNAME, name, MAXDNAME, domain);
330 357
331 return (res_query(longname, class, type, answer, anslen)); 358 return (res_query(longname, class, type, answer, anslen));
332} 359}
333 360
334char * 361const char *
335__hostalias(name) 362hostalias(name)
336 register const char *name; 363 register const char *name;
337{ 364{
365 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
338 register char *cp1, *cp2; 366 register char *cp1, *cp2;
339 FILE *fp; 367 FILE *fp;
340 char *file, *getenv(), *strcpy(), *strncpy(); 368 char *file;
341 char buf[BUFSIZ]; 369 char buf[BUFSIZ];
342 static char abuf[MAXDNAME]; 370 static char abuf[MAXDNAME];
371 size_t len;
343 372
373 if (_resp->options & RES_NOALIASES)
374 return (NULL);
344 file = getenv("HOSTALIASES"); 375 file = getenv("HOSTALIASES");
345 if (file == NULL || (fp = fopen(file, "r")) == NULL) 376 if (issetugid() != 0 || file == NULL || (fp = fopen(file, "r")) == NULL)
346 return (NULL); 377 return (NULL);
347 buf[sizeof(buf) - 1] = '\0'; 378 setbuf(fp, NULL);
348 while (fgets(buf, sizeof(buf), fp)) { 379 while ((cp1 = fgetln(fp, &len)) != NULL) {
349 for (cp1 = buf; *cp1 && !isspace(*cp1); ++cp1); 380 if (cp1[len-1] == '\n')
381 len--;
382 if (len >= sizeof(buf) || len == 0)
383 continue;
384 (void)memcpy(buf, cp1, len);
385 buf[len] = '\0';
386
387 for (cp1 = buf; *cp1 && !isspace(*cp1); ++cp1)
388 ;
350 if (!*cp1) 389 if (!*cp1)
351 break; 390 break;
352 *cp1 = '\0'; 391 *cp1 = '\0';
353 if (!strcasecmp(buf, name)) { 392 if (!strcasecmp(buf, name)) {
354 while (isspace(*++cp1)); 393 while (isspace(*++cp1))
394 ;
355 if (!*cp1) 395 if (!*cp1)
356 break; 396 break;
357 for (cp2 = cp1 + 1; *cp2 && !isspace(*cp2); ++cp2); 397 for (cp2 = cp1 + 1; *cp2 && !isspace(*cp2); ++cp2)
358 abuf[sizeof(abuf) - 1] = *cp2 = '\0'; 398 ;
359 (void)strncpy(abuf, cp1, sizeof(abuf) - 1); 399 *cp2 = '\0';
400 strlcpy(abuf, cp1, sizeof(abuf));
360 fclose(fp); 401 fclose(fp);
361 return (abuf); 402 return (abuf);
362 } 403 }
diff --git a/src/lib/libc/net/res_random.c b/src/lib/libc/net/res_random.c
new file mode 100644
index 0000000000..b52330b3ee
--- /dev/null
+++ b/src/lib/libc/net/res_random.c
@@ -0,0 +1,228 @@
1/* $OpenBSD: res_random.c,v 1.15 2003/12/12 06:57:12 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 *
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/*
34 * seed = random 15bit
35 * n = prime, g0 = generator to n,
36 * j = random so that gcd(j,n-1) == 1
37 * g = g0^j mod n will be a generator again.
38 *
39 * X[0] = random seed.
40 * X[n] = a*X[n-1]+b mod m is a Linear Congruential Generator
41 * with a = 7^(even random) mod m,
42 * b = random with gcd(b,m) == 1
43 * m = 31104 and a maximal period of m-1.
44 *
45 * The transaction id is determined by:
46 * id[n] = seed xor (g^X[n] mod n)
47 *
48 * Effectivly the id is restricted to the lower 15 bits, thus
49 * yielding two different cycles by toggling the msb on and off.
50 * This avoids reuse issues caused by reseeding.
51 *
52 * The 16 bit space is very small and brute force attempts are
53 * entirly feasible, we skip a random number of transaction ids
54 * so that an attacker will not get sequential ids.
55 */
56
57#include <sys/types.h>
58#include <netinet/in.h>
59#include <sys/time.h>
60#include <resolv.h>
61
62#include <unistd.h>
63#include <stdlib.h>
64#include <string.h>
65
66#define RU_OUT 180 /* Time after wich will be reseeded */
67#define RU_MAX 30000 /* Uniq cycle, avoid blackjack prediction */
68#define RU_GEN 2 /* Starting generator */
69#define RU_N 32749 /* RU_N-1 = 2*2*3*2729 */
70#define RU_AGEN 7 /* determine ru_a as RU_AGEN^(2*rand) */
71#define RU_M 31104 /* RU_M = 2^7*3^5 - don't change */
72
73#define PFAC_N 3
74const static u_int16_t pfacts[PFAC_N] = {
75 2,
76 3,
77 2729
78};
79
80static u_int16_t ru_x;
81static u_int16_t ru_seed, ru_seed2;
82static u_int16_t ru_a, ru_b;
83static u_int16_t ru_g;
84static u_int16_t ru_counter = 0;
85static u_int16_t ru_msb = 0;
86static long ru_reseed;
87static u_int32_t tmp; /* Storage for unused random */
88static struct timeval tv;
89
90static u_int16_t pmod(u_int16_t, u_int16_t, u_int16_t);
91static void res_initid(void);
92
93/*
94 * Do a fast modular exponation, returned value will be in the range
95 * of 0 - (mod-1)
96 */
97
98static u_int16_t
99pmod(u_int16_t gen, u_int16_t exp, u_int16_t mod)
100{
101 u_int16_t s, t, u;
102
103 s = 1;
104 t = gen;
105 u = exp;
106
107 while (u) {
108 if (u & 1)
109 s = (s * t) % mod;
110 u >>= 1;
111 t = (t * t) % mod;
112 }
113 return (s);
114}
115
116/*
117 * Initializes the seed and chooses a suitable generator. Also toggles
118 * the msb flag. The msb flag is used to generate two distinct
119 * cycles of random numbers and thus avoiding reuse of ids.
120 *
121 * This function is called from res_randomid() when needed, an
122 * application does not have to worry about it.
123 */
124static void
125res_initid()
126{
127 u_int16_t j, i;
128 int noprime = 1;
129
130 tmp = arc4random();
131 ru_x = (tmp & 0xFFFF) % RU_M;
132
133 /* 15 bits of random seed */
134 ru_seed = (tmp >> 16) & 0x7FFF;
135 tmp = arc4random();
136 ru_seed2 = tmp & 0x7FFF;
137
138 tmp = arc4random();
139
140 /* Determine the LCG we use */
141 ru_b = (tmp & 0xfffe) | 1;
142 ru_a = pmod(RU_AGEN, (tmp >> 16) & 0xfffe, RU_M);
143 while (ru_b % 3 == 0)
144 ru_b += 2;
145
146 tmp = arc4random();
147 j = tmp % RU_N;
148 tmp = tmp >> 16;
149
150 /*
151 * Do a fast gcd(j,RU_N-1), so we can find a j with
152 * gcd(j, RU_N-1) == 1, giving a new generator for
153 * RU_GEN^j mod RU_N
154 */
155
156 while (noprime) {
157 for (i = 0; i < PFAC_N; i++)
158 if (j % pfacts[i] == 0)
159 break;
160
161 if (i >= PFAC_N)
162 noprime = 0;
163 else
164 j = (j + 1) % RU_N;
165 }
166
167 ru_g = pmod(RU_GEN, j, RU_N);
168 ru_counter = 0;
169
170 gettimeofday(&tv, NULL);
171 ru_reseed = tv.tv_sec + RU_OUT;
172 ru_msb = ru_msb == 0x8000 ? 0 : 0x8000;
173}
174
175u_int
176res_randomid()
177{
178 int i, n;
179
180 gettimeofday(&tv, NULL);
181 if (ru_counter >= RU_MAX || tv.tv_sec > ru_reseed)
182 res_initid();
183
184#if 0
185 if (!tmp)
186 tmp = arc4random();
187
188 /* Skip a random number of ids */
189 n = tmp & 0x7; tmp = tmp >> 3;
190 if (ru_counter + n >= RU_MAX)
191 res_initid();
192#else
193 n = 0;
194#endif
195
196 for (i = 0; i <= n; i++)
197 /* Linear Congruential Generator */
198 ru_x = (ru_a * ru_x + ru_b) % RU_M;
199
200 ru_counter += i;
201
202 return (ru_seed ^ pmod(ru_g, ru_seed2 + ru_x, RU_N)) | ru_msb;
203}
204
205#if 0
206void
207main(int argc, char **argv)
208{
209 int i, n;
210 u_int16_t wert;
211
212 res_initid();
213
214 printf("Generator: %u\n", ru_g);
215 printf("Seed: %u\n", ru_seed);
216 printf("Reseed at %ld\n", ru_reseed);
217 printf("Ru_X: %u\n", ru_x);
218 printf("Ru_A: %u\n", ru_a);
219 printf("Ru_B: %u\n", ru_b);
220
221 n = atoi(argv[1]);
222 for (i=0;i<n;i++) {
223 wert = res_randomid();
224 printf("%06d\n", wert);
225 }
226}
227#endif
228
diff --git a/src/lib/libc/net/res_send.c b/src/lib/libc/net/res_send.c
index e608358180..c456a92d32 100644
--- a/src/lib/libc/net/res_send.c
+++ b/src/lib/libc/net/res_send.c
@@ -1,9 +1,11 @@
1/* $NetBSD: res_send.c,v 1.4 1995/02/25 06:21:01 cgd Exp $ */ 1/* $OpenBSD: res_send.c,v 1.15 2003/06/02 20:18:36 millert Exp $ */
2 2
3/*- 3/*
4 * ++Copyright++ 1985, 1989, 1993
5 * -
4 * Copyright (c) 1985, 1989, 1993 6 * Copyright (c) 1985, 1989, 1993
5 * The Regents of the University of California. All rights reserved. 7 * The Regents of the University of California. All rights reserved.
6 * 8 *
7 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
9 * are met: 11 * are met:
@@ -12,14 +14,10 @@
12 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 15 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 16 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 17 * 3. Neither the name of the University nor the names of its contributors
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 18 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission. 19 * without specific prior written permission.
22 * 20 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -53,19 +51,31 @@
53 * --Copyright-- 51 * --Copyright--
54 */ 52 */
55 53
54#ifndef INET6
55#define INET6
56#endif
57
56#if defined(LIBC_SCCS) && !defined(lint) 58#if defined(LIBC_SCCS) && !defined(lint)
57#if 0 59#if 0
58static char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93"; 60static char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93";
59static char rcsid[] = "$Id: res_send.c,v 4.9.1.1 1993/05/02 22:43:03 vixie Rel "; 61static char rcsid[] = "$From: res_send.c,v 8.12 1996/10/08 04:51:06 vixie Exp $";
60#else 62#else
61static char rcsid[] = "$NetBSD: res_send.c,v 1.4 1995/02/25 06:21:01 cgd Exp $"; 63static char rcsid[] = "$OpenBSD: res_send.c,v 1.15 2003/06/02 20:18:36 millert Exp $";
62#endif 64#endif
63#endif /* LIBC_SCCS and not lint */ 65#endif /* LIBC_SCCS and not lint */
64 66
67 /* change this to "0"
68 * if you talk to a lot
69 * of multi-homed SunOS
70 * ("broken") name servers.
71 */
72#define CHECK_SRVR_ADDR 1 /* XXX - should be in options.h */
73
65/* 74/*
66 * Send query to name server and wait for reply. 75 * Send query to name server and wait for reply.
67 */ 76 */
68 77
78#include <sys/types.h>
69#include <sys/param.h> 79#include <sys/param.h>
70#include <sys/time.h> 80#include <sys/time.h>
71#include <sys/socket.h> 81#include <sys/socket.h>
@@ -73,16 +83,24 @@ static char rcsid[] = "$NetBSD: res_send.c,v 1.4 1995/02/25 06:21:01 cgd Exp $";
73#include <netinet/in.h> 83#include <netinet/in.h>
74#include <arpa/nameser.h> 84#include <arpa/nameser.h>
75#include <arpa/inet.h> 85#include <arpa/inet.h>
86
76#include <stdio.h> 87#include <stdio.h>
88#include <netdb.h>
77#include <errno.h> 89#include <errno.h>
78#include <resolv.h> 90#include <resolv.h>
79#include <unistd.h> 91#include <stdlib.h>
80#include <string.h> 92#include <string.h>
93#include <unistd.h>
94
95#include "thread_private.h"
81 96
82static int s = -1; /* socket used for communications */ 97static int s = -1; /* socket used for communications */
83static struct sockaddr no_addr; 98static int connected = 0; /* is the socket connected */
99static int vc = 0; /* is the socket a virtual ciruit? */
100static int af = 0; /* address family of socket */
84 101
85#ifndef FD_SET 102#ifndef FD_SET
103/* XXX - should be in portability.h */
86#define NFDBITS 32 104#define NFDBITS 32
87#define FD_SETSIZE 32 105#define FD_SETSIZE 32
88#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS))) 106#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
@@ -91,121 +109,403 @@ static struct sockaddr no_addr;
91#define FD_ZERO(p) bzero((char *)(p), sizeof(*(p))) 109#define FD_ZERO(p) bzero((char *)(p), sizeof(*(p)))
92#endif 110#endif
93 111
94res_send(buf, buflen, answer, anslen) 112#define CAN_RECONNECT 1
95 const char *buf; 113
96 int buflen; 114#ifndef DEBUG
97 char *answer; 115# define Dprint(cond, args) /*empty*/
98 int anslen; 116# define DprintQ(cond, args, query, size) /*empty*/
117# define Aerror(file, string, error, address) /*empty*/
118# define Perror(file, string, error) /*empty*/
119#else
120# define Dprint(cond, args) if (cond) {fprintf args;} else {}
121# define DprintQ(cond, args, query, size) if (cond) {\
122 fprintf args;\
123 __fp_nquery(query, size, stdout);\
124 } else {}
125static char abuf[NI_MAXHOST];
126static char pbuf[NI_MAXSERV];
127static void Aerror(FILE *, char *, int, struct sockaddr *);
128static void Perror(FILE *, char *, int);
129
130 static void
131 Aerror(file, string, error, address)
132 FILE *file;
133 char *string;
134 int error;
135 struct sockaddr *address;
136 {
137 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
138 int save = errno;
139
140 if (_resp->options & RES_DEBUG) {
141 if (getnameinfo(address, address->sa_len, abuf, sizeof(abuf),
142 pbuf, sizeof(pbuf),
143 NI_NUMERICHOST|NI_NUMERICSERV|NI_WITHSCOPEID) != 0) {
144 strlcpy(abuf, "?", sizeof(abuf));
145 strlcpy(pbuf, "?", sizeof(pbuf));
146 }
147 fprintf(file, "res_send: %s ([%s].%s): %s\n",
148 string, abuf, pbuf, strerror(error));
149 }
150 errno = save;
151 }
152 static void
153 Perror(file, string, error)
154 FILE *file;
155 char *string;
156 int error;
157 {
158 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
159 int save = errno;
160
161 if (_resp->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;
99{ 175{
100 register int n; 176
101 int try, v_circuit, resplen, ns; 177 Qhook = hook;
102 int gotsomewhere = 0, connected = 0; 178}
103 int connreset = 0; 179
104 u_short id, len; 180void
105 char *cp; 181res_send_setrhook(hook)
106 fd_set dsmask; 182 res_send_rhook hook;
107 struct timeval timeout; 183{
108 HEADER *hp = (HEADER *) buf; 184
109 HEADER *anhp = (HEADER *) answer; 185 Rhook = hook;
110 u_int badns; /* XXX NSMAX can't exceed #/bits per this */ 186}
111 struct iovec iov[2]; 187
112 int terrno = ETIMEDOUT; 188#ifdef INET6
113 char junk[512]; 189static struct sockaddr * get_nsaddr(size_t);
114 190
115#ifdef DEBUG 191/*
116 if ((_res.options & RES_DEBUG) || (_res.pfcode & RES_PRF_QUERY)) { 192 * pick appropriate nsaddr_list for use. see res_init() for initialization.
117 printf(";; res_send()\n"); 193 */
118 __p_query(buf); 194static struct sockaddr *
195get_nsaddr(n)
196 size_t n;
197{
198 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
199 struct __res_state_ext *_res_extp = _THREAD_PRIVATE(_res_ext, _res_ext,
200 &_res_ext);
201
202 if (!_resp->nsaddr_list[n].sin_family) {
203 /*
204 * - _res_extp->nsaddr_list[n] holds an address that is larger
205 * than struct sockaddr, and
206 * - user code did not update _resp->nsaddr_list[n].
207 */
208 return (struct sockaddr *)&_res_extp->nsaddr_list[n];
209 } else {
210 /*
211 * - user code updated _res.nsaddr_list[n], or
212 * - _resp->nsaddr_list[n] has the same content as
213 * _res_extp->nsaddr_list[n].
214 */
215 return (struct sockaddr *)&_resp->nsaddr_list[n];
119 } 216 }
217}
218#else
219#define get_nsaddr(n) ((struct sockaddr *)&_resp->nsaddr_list[(n)])
120#endif 220#endif
121 if (!(_res.options & RES_INIT)) 221
122 if (res_init() == -1) { 222/* int
123 return(-1); 223 * res_isourserver(ina)
224 * looks up "ina" in _resp->ns_addr_list[]
225 * returns:
226 * 0 : not found
227 * >0 : found
228 * author:
229 * paul vixie, 29may94
230 */
231int
232res_isourserver(inp)
233 const struct sockaddr_in *inp;
234{
235 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
236#ifdef INET6
237 const struct sockaddr_in6 *in6p = (const struct sockaddr_in6 *)inp;
238 const struct sockaddr_in6 *srv6;
239#endif
240 const struct sockaddr_in *srv;
241 int ns, ret;
242
243 ret = 0;
244 switch (inp->sin_family) {
245#ifdef INET6
246 case AF_INET6:
247 for (ns = 0; ns < _resp->nscount; ns++) {
248 srv6 = (struct sockaddr_in6 *)get_nsaddr(ns);
249 if (srv6->sin6_family == in6p->sin6_family &&
250 srv6->sin6_port == in6p->sin6_port &&
251 srv6->sin6_scope_id == in6p->sin6_scope_id &&
252 (IN6_IS_ADDR_UNSPECIFIED(&srv6->sin6_addr) ||
253 IN6_ARE_ADDR_EQUAL(&srv6->sin6_addr,
254 &in6p->sin6_addr))) {
255 ret++;
256 break;
257 }
124 } 258 }
125 v_circuit = (_res.options & RES_USEVC) || buflen > PACKETSZ; 259 break;
126 id = hp->id; 260#endif
261 case AF_INET:
262 for (ns = 0; ns < _resp->nscount; ns++) {
263 srv = (struct sockaddr_in *)get_nsaddr(ns);
264 if (srv->sin_family == inp->sin_family &&
265 srv->sin_port == inp->sin_port &&
266 (srv->sin_addr.s_addr == INADDR_ANY ||
267 srv->sin_addr.s_addr == inp->sin_addr.s_addr)) {
268 ret++;
269 break;
270 }
271 }
272 break;
273 }
274 return (ret);
275}
276
277/* int
278 * res_nameinquery(name, type, class, buf, eom)
279 * look for (name,type,class) in the query section of packet (buf,eom)
280 * returns:
281 * -1 : format error
282 * 0 : not found
283 * >0 : found
284 * author:
285 * paul vixie, 29may94
286 */
287int
288res_nameinquery(name, type, class, buf, eom)
289 const char *name;
290 register int type, class;
291 const u_char *buf, *eom;
292{
293 register const u_char *cp = buf + HFIXEDSZ;
294 int qdcount = ntohs(((HEADER*)buf)->qdcount);
295
296 while (qdcount-- > 0) {
297 char tname[MAXDNAME+1];
298 register int n, ttype, tclass;
299
300 n = dn_expand(buf, eom, cp, tname, sizeof tname);
301 if (n < 0)
302 return (-1);
303 cp += n;
304 ttype = _getshort(cp); cp += INT16SZ;
305 tclass = _getshort(cp); cp += INT16SZ;
306 if (ttype == type &&
307 tclass == class &&
308 strcasecmp(tname, name) == 0)
309 return (1);
310 }
311 return (0);
312}
313
314/* int
315 * res_queriesmatch(buf1, eom1, buf2, eom2)
316 * is there a 1:1 mapping of (name,type,class)
317 * in (buf1,eom1) and (buf2,eom2)?
318 * returns:
319 * -1 : format error
320 * 0 : not a 1:1 mapping
321 * >0 : is a 1:1 mapping
322 * author:
323 * paul vixie, 29may94
324 */
325int
326res_queriesmatch(buf1, eom1, buf2, eom2)
327 const u_char *buf1, *eom1;
328 const u_char *buf2, *eom2;
329{
330 register const u_char *cp = buf1 + HFIXEDSZ;
331 int qdcount = ntohs(((HEADER*)buf1)->qdcount);
332
333 if (qdcount != ntohs(((HEADER*)buf2)->qdcount))
334 return (0);
335 while (qdcount-- > 0) {
336 char tname[MAXDNAME+1];
337 register int n, ttype, tclass;
338
339 n = dn_expand(buf1, eom1, cp, tname, sizeof tname);
340 if (n < 0)
341 return (-1);
342 cp += n;
343 ttype = _getshort(cp); cp += INT16SZ;
344 tclass = _getshort(cp); cp += INT16SZ;
345 if (!res_nameinquery(tname, ttype, tclass, buf2, eom2))
346 return (0);
347 }
348 return (1);
349}
350
351int
352res_send(buf, buflen, ans, anssiz)
353 const u_char *buf;
354 int buflen;
355 u_char *ans;
356 int anssiz;
357{
358 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
359 HEADER *hp = (HEADER *) buf;
360 HEADER *anhp = (HEADER *) ans;
361 int gotsomewhere, connreset, terrno, try, v_circuit, resplen, ns;
362 register int n;
363 u_int badns; /* XXX NSMAX can't exceed #/bits in this var */
364
365 if ((_resp->options & RES_INIT) == 0 && res_init() == -1) {
366 /* errno should have been set by res_init() in this case. */
367 return (-1);
368 }
369 DprintQ((_resp->options & RES_DEBUG) || (_resp->pfcode & RES_PRF_QUERY),
370 (stdout, ";; res_send()\n"), buf, buflen);
371 v_circuit = (_resp->options & RES_USEVC) || buflen > PACKETSZ;
372 gotsomewhere = 0;
373 connreset = 0;
374 terrno = ETIMEDOUT;
127 badns = 0; 375 badns = 0;
376
128 /* 377 /*
129 * Send request, RETRY times, or until successful 378 * Send request, RETRY times, or until successful
130 */ 379 */
131 for (try = 0; try < _res.retry; try++) { 380 for (try = 0; try < _resp->retry; try++) {
132 for (ns = 0; ns < _res.nscount; ns++) { 381 for (ns = 0; ns < _resp->nscount; ns++) {
133 if (badns & (1<<ns)) 382 struct sockaddr *nsap = get_nsaddr(ns);
134 continue; 383 socklen_t salen;
135#ifdef DEBUG 384
136 if (_res.options & RES_DEBUG) 385 if (nsap->sa_len)
137 printf(";; Querying server (# %d) address = %s\n", 386 salen = nsap->sa_len;
138 ns+1, 387#ifdef INET6
139 inet_ntoa(_res.nsaddr_list[ns].sin_addr)); 388 else if (nsap->sa_family == AF_INET6)
389 salen = sizeof(struct sockaddr_in6);
140#endif 390#endif
141 usevc: 391 else if (nsap->sa_family == AF_INET)
392 salen = sizeof(struct sockaddr_in);
393 else
394 salen = 0; /*unknown, die on connect*/
395
396 same_ns:
397 if (badns & (1 << ns)) {
398 res_close();
399 goto next_ns;
400 }
401
402 if (Qhook) {
403 int done = 0, loops = 0;
404
405 do {
406 res_sendhookact act;
407
408 act = (*Qhook)((struct sockaddr_in **)&nsap,
409 &buf, &buflen,
410 ans, anssiz, &resplen);
411 switch (act) {
412 case res_goahead:
413 done = 1;
414 break;
415 case res_nextns:
416 res_close();
417 goto next_ns;
418 case res_done:
419 return (resplen);
420 case res_modified:
421 /* give the hook another try */
422 if (++loops < 42) /*doug adams*/
423 break;
424 /*FALLTHROUGH*/
425 case res_error:
426 /*FALLTHROUGH*/
427 default:
428 return (-1);
429 }
430 } while (!done);
431 }
432
433 Dprint((_resp->options & RES_DEBUG) &&
434 getnameinfo(nsap, salen, abuf, sizeof(abuf),
435 NULL, 0, NI_NUMERICHOST | NI_WITHSCOPEID) == 0,
436 (stdout, ";; Querying server (# %d) address = %s\n",
437 ns + 1, abuf));
438
142 if (v_circuit) { 439 if (v_circuit) {
143 int truncated = 0; 440 int truncated;
441 struct iovec iov[2];
442 u_short len;
443 u_char *cp;
144 444
145 /* 445 /*
146 * Use virtual circuit; 446 * Use virtual circuit;
147 * at most one attempt per server. 447 * at most one attempt per server.
148 */ 448 */
149 try = _res.retry; 449 try = _resp->retry;
150 if (s < 0) { 450 truncated = 0;
151 s = socket(AF_INET, SOCK_STREAM, 0); 451 if ((s < 0) || (!vc) || (af != nsap->sa_family)) {
452 if (s >= 0)
453 res_close();
454
455 af = nsap->sa_family;
456 s = socket(af, SOCK_STREAM, 0);
152 if (s < 0) { 457 if (s < 0) {
153 terrno = errno; 458 terrno = errno;
154#ifdef DEBUG 459 Perror(stderr, "socket(vc)", errno);
155 if (_res.options & RES_DEBUG) 460#if 0
156 perror("socket (vc) failed"); 461 return (-1);
462#else
463 badns |= (1 << ns);
464 res_close();
465 goto next_ns;
157#endif 466#endif
158 continue;
159 } 467 }
160 if (connect(s, 468 errno = 0;
161 (struct sockaddr *)&(_res.nsaddr_list[ns]), 469 if (connect(s, nsap, salen) < 0) {
162 sizeof(struct sockaddr)) < 0) {
163 terrno = errno; 470 terrno = errno;
164#ifdef DEBUG 471 Aerror(stderr, "connect/vc",
165 if (_res.options & RES_DEBUG) 472 errno, nsap);
166 perror("connect failed"); 473 badns |= (1 << ns);
167#endif 474 res_close();
168 (void) close(s); 475 goto next_ns;
169 s = -1;
170 continue;
171 } 476 }
477 vc = 1;
172 } 478 }
173 /* 479 /*
174 * Send length & message 480 * Send length & message
175 */ 481 */
176 len = htons((u_short)buflen); 482 putshort((u_short)buflen, (u_char*)&len);
177 iov[0].iov_base = (caddr_t)&len; 483 iov[0].iov_base = (caddr_t)&len;
178 iov[0].iov_len = sizeof(len); 484 iov[0].iov_len = INT16SZ;
179 iov[1].iov_base = (char *)buf; 485 iov[1].iov_base = (caddr_t)buf;
180 iov[1].iov_len = buflen; 486 iov[1].iov_len = buflen;
181 if (writev(s, iov, 2) != sizeof(len) + buflen) { 487 if (writev(s, iov, 2) != (INT16SZ + buflen)) {
182 terrno = errno; 488 terrno = errno;
183#ifdef DEBUG 489 Perror(stderr, "write failed", errno);
184 if (_res.options & RES_DEBUG) 490 badns |= (1 << ns);
185 perror("write failed"); 491 res_close();
186#endif 492 goto next_ns;
187 (void) close(s);
188 s = -1;
189 continue;
190 } 493 }
191 /* 494 /*
192 * Receive length & response 495 * Receive length & response
193 */ 496 */
194 cp = answer; 497read_len:
195 len = sizeof(short); 498 cp = ans;
196 while (len != 0 && 499 len = INT16SZ;
197 (n = read(s, (char *)cp, (int)len)) > 0) { 500 while ((n = read(s, (char *)cp, (int)len)) > 0) {
198 cp += n; 501 cp += n;
199 len -= n; 502 if ((len -= n) <= 0)
503 break;
200 } 504 }
201 if (n <= 0) { 505 if (n <= 0) {
202 terrno = errno; 506 terrno = errno;
203#ifdef DEBUG 507 Perror(stderr, "read failed", errno);
204 if (_res.options & RES_DEBUG) 508 res_close();
205 perror("read failed");
206#endif
207 (void) close(s);
208 s = -1;
209 /* 509 /*
210 * A long running process might get its TCP 510 * A long running process might get its TCP
211 * connection reset if the remote server was 511 * connection reset if the remote server was
@@ -217,35 +517,32 @@ res_send(buf, buflen, answer, anslen)
217 */ 517 */
218 if (terrno == ECONNRESET && !connreset) { 518 if (terrno == ECONNRESET && !connreset) {
219 connreset = 1; 519 connreset = 1;
220 ns--; 520 res_close();
521 goto same_ns;
221 } 522 }
222 continue; 523 res_close();
524 goto next_ns;
223 } 525 }
224 cp = answer; 526 resplen = _getshort(ans);
225 if ((resplen = ntohs(*(u_short *)cp)) > anslen) { 527 if (resplen > anssiz) {
226#ifdef DEBUG 528 Dprint(_resp->options & RES_DEBUG,
227 if (_res.options & RES_DEBUG) 529 (stdout, ";; response truncated\n")
228 fprintf(stderr, 530 );
229 ";; response truncated\n");
230#endif
231 len = anslen;
232 truncated = 1; 531 truncated = 1;
532 len = anssiz;
233 } else 533 } else
234 len = resplen; 534 len = resplen;
535 cp = ans;
235 while (len != 0 && 536 while (len != 0 &&
236 (n = read(s, (char *)cp, (int)len)) > 0) { 537 (n = read(s, (char *)cp, (int)len)) > 0) {
237 cp += n; 538 cp += n;
238 len -= n; 539 len -= n;
239 } 540 }
240 if (n <= 0) { 541 if (n <= 0) {
241 terrno = errno; 542 terrno = errno;
242#ifdef DEBUG 543 Perror(stderr, "read(vc)", errno);
243 if (_res.options & RES_DEBUG) 544 res_close();
244 perror("read failed"); 545 goto next_ns;
245#endif
246 (void) close(s);
247 s = -1;
248 continue;
249 } 546 }
250 if (truncated) { 547 if (truncated) {
251 /* 548 /*
@@ -253,33 +550,72 @@ res_send(buf, buflen, answer, anslen)
253 * so connection stays in synch. 550 * so connection stays in synch.
254 */ 551 */
255 anhp->tc = 1; 552 anhp->tc = 1;
256 len = resplen - anslen; 553 len = resplen - anssiz;
257 while (len != 0) { 554 while (len != 0) {
258 n = (len > sizeof(junk) ? 555 char junk[PACKETSZ];
259 sizeof(junk) : len); 556
557 n = (len > sizeof(junk)
558 ? sizeof(junk)
559 : len);
260 if ((n = read(s, junk, n)) > 0) 560 if ((n = read(s, junk, n)) > 0)
261 len -= n; 561 len -= n;
262 else 562 else
263 break; 563 break;
264 } 564 }
265 } 565 }
566 /*
567 * The calling applicating has bailed out of
568 * a previous call and failed to arrange to have
569 * the circuit closed or the server has got
570 * itself confused. Anyway drop the packet and
571 * wait for the correct one.
572 */
573 if (hp->id != anhp->id) {
574 DprintQ((_resp->options & RES_DEBUG) ||
575 (_resp->pfcode & RES_PRF_REPLY),
576 (stdout, ";; old answer (unexpected):\n"),
577 ans, (resplen>anssiz)?anssiz:resplen);
578 goto read_len;
579 }
266 } else { 580 } else {
267 /* 581 /*
268 * Use datagrams. 582 * Use datagrams.
269 */ 583 */
270 if (s < 0) { 584 struct timeval timeout;
271 s = socket(AF_INET, SOCK_DGRAM, 0); 585 fd_set *dsmaskp;
586 struct sockaddr_storage from;
587 socklen_t fromlen;
588
589 if ((s < 0) || vc || (af != nsap->sa_family)) {
590 if (vc)
591 res_close();
592 af = nsap->sa_family;
593 s = socket(af, SOCK_DGRAM, 0);
272 if (s < 0) { 594 if (s < 0) {
595#if !CAN_RECONNECT
596 bad_dg_sock:
597#endif
273 terrno = errno; 598 terrno = errno;
274#ifdef DEBUG 599 Perror(stderr, "socket(dg)", errno);
275 if (_res.options & RES_DEBUG) 600#if 0
276 perror("socket (dg) failed"); 601 return (-1);
602#else
603 badns |= (1 << ns);
604 res_close();
605 goto next_ns;
277#endif 606#endif
278 continue;
279 } 607 }
608#ifdef IPV6_MINMTU
609 if (af == AF_INET6) {
610 const int yes = 1;
611 (void)setsockopt(s, IPPROTO_IPV6,
612 IPV6_USE_MIN_MTU, &yes,
613 sizeof(yes));
614 }
615#endif
616 connected = 0;
280 } 617 }
281 /* 618 /*
282 * I'm tired of answering this question, so:
283 * On a 4.3BSD+ machine (client and server, 619 * On a 4.3BSD+ machine (client and server,
284 * actually), sending to a nameserver datagram 620 * actually), sending to a nameserver datagram
285 * port with no nameserver will cause an 621 * port with no nameserver will cause an
@@ -294,31 +630,28 @@ res_send(buf, buflen, answer, anslen)
294 * as we wish to receive answers from the first 630 * as we wish to receive answers from the first
295 * server to respond. 631 * server to respond.
296 */ 632 */
297 if (_res.nscount == 1 || (try == 0 && ns == 0)) { 633 if (!(_resp->options & RES_INSECURE1) &&
634 (_resp->nscount == 1 || (try == 0 && ns == 0))) {
298 /* 635 /*
299 * Don't use connect if we might 636 * Connect only if we are sure we won't
300 * still receive a response 637 * receive a response from another server.
301 * from another server.
302 */ 638 */
303 if (connected == 0) { 639 if (!connected) {
304 if (connect(s, 640 if (connect(s, nsap, salen) < 0) {
305 (struct sockaddr *) 641 Aerror(stderr,
306 &_res.nsaddr_list[ns], 642 "connect(dg)",
307 sizeof(struct sockaddr)) < 0) { 643 errno, nsap);
308#ifdef DEBUG 644 badns |= (1 << ns);
309 if (_res.options & RES_DEBUG) 645 res_close();
310 perror("connect"); 646 goto next_ns;
311#endif
312 continue;
313 } 647 }
314 connected = 1; 648 connected = 1;
315 } 649 }
316 if (send(s, buf, buflen, 0) != buflen) { 650 if (send(s, (char*)buf, buflen, 0) != buflen) {
317#ifdef DEBUG 651 Perror(stderr, "send", errno);
318 if (_res.options & RES_DEBUG) 652 badns |= (1 << ns);
319 perror("send"); 653 res_close();
320#endif 654 goto next_ns;
321 continue;
322 } 655 }
323 } else { 656 } else {
324 /* 657 /*
@@ -326,134 +659,221 @@ res_send(buf, buflen, answer, anslen)
326 * for responses from more than one server. 659 * for responses from more than one server.
327 */ 660 */
328 if (connected) { 661 if (connected) {
329 (void) connect(s, &no_addr, 662#if CAN_RECONNECT
330 sizeof(no_addr)); 663#ifdef INET6
664 /* XXX: any errornous address */
665#endif /* INET6 */
666 struct sockaddr_in no_addr;
667
668 no_addr.sin_family = AF_INET;
669 no_addr.sin_addr.s_addr = INADDR_ANY;
670 no_addr.sin_port = 0;
671 (void) connect(s,
672 (struct sockaddr *)
673 &no_addr,
674 sizeof(no_addr));
675#else
676 int s1 = socket(af, SOCK_DGRAM,0);
677 if (s1 < 0)
678 goto bad_dg_sock;
679 (void) dup2(s1, s);
680 (void) close(s1);
681 Dprint(_resp->options & RES_DEBUG,
682 (stdout, ";; new DG socket\n"))
683#endif
684#ifdef IPV6_MINMTU
685 if (af == AF_INET6) {
686 const int yes = 1;
687 (void)setsockopt(s, IPPROTO_IPV6,
688 IPV6_USE_MIN_MTU, &yes,
689 sizeof(yes));
690 }
691#endif
331 connected = 0; 692 connected = 0;
693 errno = 0;
332 } 694 }
333 if (sendto(s, buf, buflen, 0, 695 if (sendto(s, (char*)buf, buflen, 0,
334 (struct sockaddr *)&_res.nsaddr_list[ns], 696 nsap, salen) != buflen) {
335 sizeof(struct sockaddr)) != buflen) { 697 Aerror(stderr, "sendto", errno, nsap);
336#ifdef DEBUG 698 badns |= (1 << ns);
337 if (_res.options & RES_DEBUG) 699 res_close();
338 perror("sendto"); 700 goto next_ns;
339#endif
340 continue;
341 } 701 }
342 } 702 }
343 703
344 /* 704 /*
345 * Wait for reply 705 * Wait for reply
346 */ 706 */
347 timeout.tv_sec = (_res.retrans << try); 707 timeout.tv_sec = (_resp->retrans << try);
348 if (try > 0) 708 if (try > 0)
349 timeout.tv_sec /= _res.nscount; 709 timeout.tv_sec /= _resp->nscount;
350 if ((long) timeout.tv_sec <= 0) 710 if ((long) timeout.tv_sec <= 0)
351 timeout.tv_sec = 1; 711 timeout.tv_sec = 1;
352 timeout.tv_usec = 0; 712 timeout.tv_usec = 0;
353wait: 713 wait:
354 FD_ZERO(&dsmask); 714 dsmaskp = (fd_set *)calloc(howmany(s+1, NFDBITS),
355 FD_SET(s, &dsmask); 715 sizeof(fd_mask));
356 n = select(s+1, &dsmask, (fd_set *)NULL, 716 if (dsmaskp == NULL) {
357 (fd_set *)NULL, &timeout); 717 res_close();
718 goto next_ns;
719 }
720 FD_SET(s, dsmaskp);
721 n = select(s+1, dsmaskp, (fd_set *)NULL,
722 (fd_set *)NULL, &timeout);
723 free(dsmaskp);
358 if (n < 0) { 724 if (n < 0) {
359#ifdef DEBUG 725 if (errno == EINTR)
360 if (_res.options & RES_DEBUG) 726 goto wait;
361 perror("select"); 727 Perror(stderr, "select", errno);
362#endif 728 res_close();
363 continue; 729 goto next_ns;
364 } 730 }
365 if (n == 0) { 731 if (n == 0) {
366 /* 732 /*
367 * timeout 733 * timeout
368 */ 734 */
369#ifdef DEBUG 735 Dprint(_resp->options & RES_DEBUG,
370 if (_res.options & RES_DEBUG) 736 (stdout, ";; timeout\n"));
371 printf(";; timeout\n");
372#endif
373 gotsomewhere = 1; 737 gotsomewhere = 1;
374 continue; 738 res_close();
739 goto next_ns;
375 } 740 }
376 if ((resplen = recv(s, answer, anslen, 0)) <= 0) { 741 errno = 0;
377#ifdef DEBUG 742 fromlen = sizeof(from);
378 if (_res.options & RES_DEBUG) 743 resplen = recvfrom(s, (char*)ans, anssiz, 0,
379 perror("recvfrom"); 744 (struct sockaddr *)&from, &fromlen);
380#endif 745 if (resplen <= 0) {
381 continue; 746 Perror(stderr, "recvfrom", errno);
747 res_close();
748 goto next_ns;
382 } 749 }
383 gotsomewhere = 1; 750 gotsomewhere = 1;
384 if (id != anhp->id) { 751 if (hp->id != anhp->id) {
385 /* 752 /*
386 * response from old query, ignore it 753 * response from old query, ignore it.
754 * XXX - potential security hazard could
755 * be detected here.
387 */ 756 */
388#ifdef DEBUG 757 DprintQ((_resp->options & RES_DEBUG) ||
389 if ((_res.options & RES_DEBUG) || 758 (_resp->pfcode & RES_PRF_REPLY),
390 (_res.pfcode & RES_PRF_REPLY)) { 759 (stdout, ";; old answer:\n"),
391 printf(";; old answer:\n"); 760 ans, (resplen>anssiz)?anssiz:resplen);
392 __p_query(answer); 761 goto wait;
393 } 762 }
763#if CHECK_SRVR_ADDR
764 if (!(_resp->options & RES_INSECURE1) &&
765 !res_isourserver((struct sockaddr_in *)&from)) {
766 /*
767 * response from wrong server? ignore it.
768 * XXX - potential security hazard could
769 * be detected here.
770 */
771 DprintQ((_resp->options & RES_DEBUG) ||
772 (_resp->pfcode & RES_PRF_REPLY),
773 (stdout, ";; not our server:\n"),
774 ans, (resplen>anssiz)?anssiz:resplen);
775 goto wait;
776 }
394#endif 777#endif
778 if (!(_resp->options & RES_INSECURE2) &&
779 !res_queriesmatch(buf, buf + buflen,
780 ans, ans + anssiz)) {
781 /*
782 * response contains wrong query? ignore it.
783 * XXX - potential security hazard could
784 * be detected here.
785 */
786 DprintQ((_resp->options & RES_DEBUG) ||
787 (_resp->pfcode & RES_PRF_REPLY),
788 (stdout, ";; wrong query name:\n"),
789 ans, (resplen>anssiz)?anssiz:resplen);
395 goto wait; 790 goto wait;
396 } 791 }
397 if (anhp->rcode == SERVFAIL || anhp->rcode == NOTIMP || 792 if (anhp->rcode == SERVFAIL ||
793 anhp->rcode == NOTIMP ||
398 anhp->rcode == REFUSED) { 794 anhp->rcode == REFUSED) {
399#ifdef DEBUG 795 DprintQ(_resp->options & RES_DEBUG,
400 if (_res.options & RES_DEBUG) { 796 (stdout, "server rejected query:\n"),
401 printf("server rejected query:\n"); 797 ans, (resplen>anssiz)?anssiz:resplen);
402 __p_query(answer); 798 badns |= (1 << ns);
403 } 799 res_close();
404#endif 800 /* don't retry if called from dig */
405 badns |= (1<<ns); 801 if (!_resp->pfcode)
406 continue; 802 goto next_ns;
407 } 803 }
408 if (!(_res.options & RES_IGNTC) && anhp->tc) { 804 if (!(_resp->options & RES_IGNTC) && anhp->tc) {
409 /* 805 /*
410 * get rest of answer; 806 * get rest of answer;
411 * use TCP with same server. 807 * use TCP with same server.
412 */ 808 */
413#ifdef DEBUG 809 Dprint(_resp->options & RES_DEBUG,
414 if (_res.options & RES_DEBUG) 810 (stdout, ";; truncated answer\n"));
415 printf(";; truncated answer\n");
416#endif
417 (void) close(s);
418 s = -1;
419 v_circuit = 1; 811 v_circuit = 1;
420 goto usevc; 812 res_close();
813 goto same_ns;
421 } 814 }
422 } 815 } /*if vc/dg*/
423#ifdef DEBUG 816 Dprint((_resp->options & RES_DEBUG) ||
424 if (_res.options & RES_DEBUG) 817 ((_resp->pfcode & RES_PRF_REPLY) &&
425 printf(";; got answer:\n"); 818 (_resp->pfcode & RES_PRF_HEAD1)),
426 if ((_res.options & RES_DEBUG) || 819 (stdout, ";; got answer:\n"));
427 (_res.pfcode & RES_PRF_REPLY)) 820 DprintQ((_resp->options & RES_DEBUG) ||
428 __p_query(answer); 821 (_resp->pfcode & RES_PRF_REPLY),
429#endif 822 (stdout, "%s", ""),
823 ans, (resplen>anssiz)?anssiz:resplen);
430 /* 824 /*
431 * If using virtual circuits, we assume that the first server 825 * If using virtual circuits, we assume that the first server
432 * is preferred * over the rest (i.e. it is on the local 826 * is preferred over the rest (i.e. it is on the local
433 * machine) and only keep that one open. 827 * machine) and only keep that one open.
434 * If we have temporarily opened a virtual circuit, 828 * If we have temporarily opened a virtual circuit,
435 * or if we haven't been asked to keep a socket open, 829 * or if we haven't been asked to keep a socket open,
436 * close the socket. 830 * close the socket.
437 */ 831 */
438 if ((v_circuit && 832 if ((v_circuit && (!(_resp->options & RES_USEVC) || ns != 0)) ||
439 ((_res.options & RES_USEVC) == 0 || ns != 0)) || 833 !(_resp->options & RES_STAYOPEN)) {
440 (_res.options & RES_STAYOPEN) == 0) { 834 res_close();
441 (void) close(s); 835 }
442 s = -1; 836 if (Rhook) {
837 int done = 0, loops = 0;
838
839 do {
840 res_sendhookact act;
841
842 act = (*Rhook)((struct sockaddr_in *)nsap,
843 buf, buflen,
844 ans, anssiz, &resplen);
845 switch (act) {
846 case res_goahead:
847 case res_done:
848 done = 1;
849 break;
850 case res_nextns:
851 res_close();
852 goto next_ns;
853 case res_modified:
854 /* give the hook another try */
855 if (++loops < 42) /*doug adams*/
856 break;
857 /*FALLTHROUGH*/
858 case res_error:
859 /*FALLTHROUGH*/
860 default:
861 return (-1);
862 }
863 } while (!done);
864
443 } 865 }
444 return (resplen); 866 return (resplen);
445 } 867 next_ns: ;
446 } 868 } /*foreach ns*/
447 if (s >= 0) { 869 } /*foreach retry*/
448 (void) close(s); 870 res_close();
449 s = -1; 871 if (!v_circuit) {
450 } 872 if (!gotsomewhere)
451 if (v_circuit == 0)
452 if (gotsomewhere == 0)
453 errno = ECONNREFUSED; /* no nameservers found */ 873 errno = ECONNREFUSED; /* no nameservers found */
454 else 874 else
455 errno = ETIMEDOUT; /* no answer obtained */ 875 errno = ETIMEDOUT; /* no answer obtained */
456 else 876 } else
457 errno = terrno; 877 errno = terrno;
458 return (-1); 878 return (-1);
459} 879}
@@ -465,10 +885,14 @@ wait:
465 * 885 *
466 * This routine is not expected to be user visible. 886 * This routine is not expected to be user visible.
467 */ 887 */
468_res_close() 888void
889res_close()
469{ 890{
470 if (s != -1) { 891 if (s >= 0) {
471 (void) close(s); 892 (void) close(s);
472 s = -1; 893 s = -1;
894 connected = 0;
895 vc = 0;
896 af = 0;
473 } 897 }
474} 898}
diff --git a/src/lib/libc/net/resolver.3 b/src/lib/libc/net/resolver.3
index 99abe17f03..577420e9f1 100644
--- a/src/lib/libc/net/resolver.3
+++ b/src/lib/libc/net/resolver.3
@@ -1,4 +1,4 @@
1.\" $NetBSD: resolver.3,v 1.5 1995/02/25 06:21:02 cgd Exp $ 1.\" $OpenBSD: resolver.3,v 1.17 2003/08/08 09:26:02 jmc Exp $
2.\" 2.\"
3.\" Copyright (c) 1985, 1991, 1993 3.\" Copyright (c) 1985, 1991, 1993
4.\" The Regents of the University of California. All rights reserved. 4.\" The Regents of the University of California. All rights reserved.
@@ -11,11 +11,7 @@
11.\" 2. Redistributions in binary form must reproduce the above copyright 11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the 12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution. 13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software 14.\" 3. Neither the name of the University nor the names of its contributors
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 15.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission. 16.\" without specific prior written permission.
21.\" 17.\"
@@ -31,11 +27,9 @@
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE. 28.\" SUCH DAMAGE.
33.\" 29.\"
34.\" @(#)resolver.3 8.1 (Berkeley) 6/4/93
35.\"
36.Dd June 4, 1993 30.Dd June 4, 1993
37.Dt RESOLVER 3 31.Dt RESOLVER 3
38.Os BSD 4.3 32.Os
39.Sh NAME 33.Sh NAME
40.Nm res_query , 34.Nm res_query ,
41.Nm res_search , 35.Nm res_search ,
@@ -50,6 +44,7 @@
50.Fd #include <netinet/in.h> 44.Fd #include <netinet/in.h>
51.Fd #include <arpa/nameser.h> 45.Fd #include <arpa/nameser.h>
52.Fd #include <resolv.h> 46.Fd #include <resolv.h>
47.Ft int
53.Fo res_query 48.Fo res_query
54.Fa "char *dname" 49.Fa "char *dname"
55.Fa "int class" 50.Fa "int class"
@@ -57,6 +52,7 @@
57.Fa "u_char *answer" 52.Fa "u_char *answer"
58.Fa "int anslen" 53.Fa "int anslen"
59.Fc 54.Fc
55.Ft int
60.Fo res_search 56.Fo res_search
61.Fa "char *dname" 57.Fa "char *dname"
62.Fa "int class" 58.Fa "int class"
@@ -64,6 +60,7 @@
64.Fa "u_char *answer" 60.Fa "u_char *answer"
65.Fa "int anslen" 61.Fa "int anslen"
66.Fc 62.Fc
63.Ft int
67.Fo res_mkquery 64.Fo res_mkquery
68.Fa "int op" 65.Fa "int op"
69.Fa "char *dname" 66.Fa "char *dname"
@@ -75,13 +72,16 @@
75.Fa "char *buf" 72.Fa "char *buf"
76.Fa "int buflen" 73.Fa "int buflen"
77.Fc 74.Fc
75.Ft int
78.Fo res_send 76.Fo res_send
79.Fa "char *msg" 77.Fa "char *msg"
80.Fa "int msglen" 78.Fa "int msglen"
81.Fa "char *answer" 79.Fa "char *answer"
82.Fa "int anslen" 80.Fa "int anslen"
83.Fc 81.Fc
84.Fn res_init 82.Ft int
83.Fn res_init "void"
84.Ft int
85.Fo dn_comp 85.Fo dn_comp
86.Fa "char *exp_dn" 86.Fa "char *exp_dn"
87.Fa "char *comp_dn" 87.Fa "char *comp_dn"
@@ -89,6 +89,7 @@
89.Fa "char **dnptrs" 89.Fa "char **dnptrs"
90.Fa "char **lastdnptr" 90.Fa "char **lastdnptr"
91.Fc 91.Fc
92.Ft int
92.Fo dn_expand 93.Fo dn_expand
93.Fa "u_char *msg" 94.Fa "u_char *msg"
94.Fa "u_char *eomorig" 95.Fa "u_char *eomorig"
@@ -97,22 +98,22 @@
97.Fa "int length" 98.Fa "int length"
98.Fc 99.Fc
99.Sh DESCRIPTION 100.Sh DESCRIPTION
100These routines are used for making, sending and interpreting 101These routines are used for making, sending, and interpreting
101query and reply messages with Internet domain name servers. 102query and reply messages with Internet domain name servers.
102.Pp 103.Pp
103Global configuration and state information that is used by the 104Global configuration and state information that is used by the
104resolver routines is kept in the structure 105resolver routines is kept in the structure
105.Em _res . 106.Li _res .
106Most of the values have reasonable defaults and can be ignored. 107Most of the values have reasonable defaults and can be ignored.
107Options 108Options stored in
108stored in 109.Li _res.options
109.Em _res.options
110are defined in 110are defined in
111.Pa resolv.h 111.Aq Pa resolv.h
112and are as follows. 112and are as follows.
113Options are stored as a simple bit mask containing the bitwise ``or'' 113Options are stored as a simple bit mask containing the bitwise
114.Tn OR
114of the options enabled. 115of the options enabled.
115.Bl -tag -width RES_DEFNAMES 116.Bl -tag -width RES_USE_INET6
116.It Dv RES_INIT 117.It Dv RES_INIT
117True if the initial name server address and default domain name are 118True if the initial name server address and default domain name are
118initialized (i.e., 119initialized (i.e.,
@@ -137,8 +138,7 @@ Used with
137.Dv RES_USEVC 138.Dv RES_USEVC
138to keep the 139to keep the
139.Tn TCP 140.Tn TCP
140connection open between 141connection open between queries.
141queries.
142This is useful only in programs that regularly do many queries. 142This is useful only in programs that regularly do many queries.
143.Tn UDP 143.Tn UDP
144should be the normal mode used. 144should be the normal mode used.
@@ -165,16 +165,20 @@ will search for host names in the current domain and in parent domains; see
165This is used by the standard host lookup routine 165This is used by the standard host lookup routine
166.Xr gethostbyname 3 . 166.Xr gethostbyname 3 .
167This option is enabled by default. 167This option is enabled by default.
168.It Dv RES_USE_INET6
169Enables support for IPv6-only applications.
170This causes IPv4 addresses to be returned as an IPv4 mapped address.
171For example, 10.1.1.1 will be returned as ::ffff:10.1.1.1.
172The option is not meaningful on
173.Ox .
168.El 174.El
169.Pp 175.Pp
170The 176The
171.Fn res_init 177.Fn res_init
172routine 178routine reads the configuration file (if any; see
173reads the configuration file (if any; see
174.Xr resolv.conf 5 ) 179.Xr resolv.conf 5 )
175to get the default domain name, 180to get the default domain name, search list, and the Internet address
176search list and 181of the local name server(s).
177the Internet address of the local name server(s).
178If no server is configured, the host running 182If no server is configured, the host running
179the resolver is tried. 183the resolver is tried.
180The current domain name is defined by the hostname 184The current domain name is defined by the hostname
@@ -212,7 +216,7 @@ The query requests information of the specified
212.Fa type 216.Fa type
213and 217and
214.Fa class 218.Fa class
215for the specified fully-qualified domain name 219for the specified fully qualified domain name
216.Fa dname . 220.Fa dname .
217The reply message is left in the 221The reply message is left in the
218.Fa answer 222.Fa answer
@@ -224,8 +228,7 @@ The
224.Fn res_search 228.Fn res_search
225routine makes a query and awaits a response like 229routine makes a query and awaits a response like
226.Fn res_query , 230.Fn res_query ,
227but in addition, it implements the default and search rules 231but in addition, it implements the default and search rules controlled by the
228controlled by the
229.Dv RES_DEFNAMES 232.Dv RES_DEFNAMES
230and 233and
231.Dv RES_DNSRCH 234.Dv RES_DNSRCH
@@ -236,11 +239,9 @@ The remaining routines are lower-level routines used by
236.Fn res_query . 239.Fn res_query .
237The 240The
238.Fn res_mkquery 241.Fn res_mkquery
239function 242function constructs a standard query message and places it in
240constructs a standard query message and places it in
241.Fa buf . 243.Fa buf .
242It returns the size of the query, or \-1 if the query is 244It returns the size of the query, or \-1 if the query is larger than
243larger than
244.Fa buflen . 245.Fa buflen .
245The query type 246The query type
246.Fa op 247.Fa op
@@ -250,26 +251,23 @@ but can be any of the query types defined in
250.Aq Pa arpa/nameser.h . 251.Aq Pa arpa/nameser.h .
251The domain name for the query is given by 252The domain name for the query is given by
252.Fa dname . 253.Fa dname .
253.Fa Newrr 254.Fa newrr
254is currently unused but is intended for making update messages. 255is currently unused but is intended for making update messages.
255.Pp 256.Pp
256The 257The
257.Fn res_send 258.Fn res_send
258routine 259routine sends a pre-formatted query and returns an answer.
259sends a pre-formatted query and returns an answer.
260It will call 260It will call
261.Fn res_init 261.Fn res_init
262if 262if
263.Dv RES_INIT 263.Dv RES_INIT
264is not set, send the query to the local name server, and 264is not set, send the query to the local name server, and
265handle timeouts and retries. 265handle timeouts and retries.
266The length of the reply message is returned, or 266The length of the reply message is returned, or \-1 if there were errors.
267\-1 if there were errors.
268.Pp 267.Pp
269The 268The
270.Fn dn_comp 269.Fn dn_comp
271function 270function compresses the domain name
272compresses the domain name
273.Fa exp_dn 271.Fa exp_dn
274and stores it in 272and stores it in
275.Fa comp_dn . 273.Fa comp_dn .
@@ -278,24 +276,23 @@ The size of the array pointed to by
278.Fa comp_dn 276.Fa comp_dn
279is given by 277is given by
280.Fa length . 278.Fa length .
281The compression uses 279The compression uses an array of pointers
282an array of pointers
283.Fa dnptrs 280.Fa dnptrs
284to previously-compressed names in the current message. 281to previously compressed names in the current message.
285The first pointer points to 282The first pointer points
286to the beginning of the message and the list ends with 283to the beginning of the message and the list ends with
287.Dv NULL . 284.Dv NULL .
288The limit to the array is specified by 285The limit to the array is specified by
289.Fa lastdnptr . 286.Fa lastdnptr .
290A side effect of 287A side effect of
291.Fn dn_comp 288.Fn dn_comp
292is to update the list of pointers for 289is to update the list of pointers for labels inserted into the message
293labels inserted into the message
294as the name is compressed. 290as the name is compressed.
295If 291If
296.Em dnptr 292.Em dnptr
297is 293is
298.Dv NULL, names are not compressed. 294.Dv NULL ,
295names are not compressed.
299If 296If
300.Fa lastdnptr 297.Fa lastdnptr
301is 298is
@@ -304,8 +301,7 @@ the list of labels is not updated.
304.Pp 301.Pp
305The 302The
306.Fn dn_expand 303.Fn dn_expand
307entry 304entry expands the compressed domain name
308expands the compressed domain name
309.Fa comp_dn 305.Fa comp_dn
310to a full domain name 306to a full domain name
311The compressed name is contained in a query or reply message; 307The compressed name is contained in a query or reply message;
@@ -319,26 +315,27 @@ The size of compressed name is returned or \-1 if there was an error.
319.Sh FILES 315.Sh FILES
320.Bl -tag -width Pa 316.Bl -tag -width Pa
321/etc/resolv.conf 317/etc/resolv.conf
322The configuration file 318configuration file
323see 319see
324.Xr resolv.conf 5 . 320.Xr resolv.conf 5 .
325.El 321.El
326.Sh SEE ALSO 322.Sh SEE ALSO
327.Xr gethostbyname 3 , 323.Xr gethostbyname 3 ,
328.Xr named 8 ,
329.Xr resolv.conf 5 , 324.Xr resolv.conf 5 ,
330.Xr hostname 7 , 325.Xr hostname 7 ,
326.Xr named 8
331.Pp 327.Pp
332.%T RFC1032 , 328.%T RFC 1032 ,
333.%T RFC1033 , 329.%T RFC 1033 ,
334.%T RFC1034 , 330.%T RFC 1034 ,
335.%T RFC1035 , 331.%T RFC 1035 ,
336.%T RFC974 332.%T RFC 1535 ,
333.%T RFC 974
337.Rs 334.Rs
338.%T "Name Server Operations Guide for BIND" 335.%T "Name Server Operations Guide for BIND"
339.Re 336.Re
340.Sh HISTORY 337.Sh HISTORY
341The 338The
342.Nm 339.Nm
343function appeared in 340function appeared in
344.Bx 4.3 . 341.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..6e4698e3be
--- /dev/null
+++ b/src/lib/libc/net/rresvport.c
@@ -0,0 +1,113 @@
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. Neither the name of the University nor the names of its contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31#if defined(LIBC_SCCS) && !defined(lint)
32static char *rcsid = "$OpenBSD: rresvport.c,v 1.6 2003/06/03 02:11:35 deraadt Exp $";
33#endif /* LIBC_SCCS and not lint */
34
35#include <sys/param.h>
36#include <sys/socket.h>
37#include <sys/stat.h>
38
39#include <netinet/in.h>
40#include <arpa/inet.h>
41
42#include <signal.h>
43#include <fcntl.h>
44#include <netdb.h>
45#include <unistd.h>
46#include <pwd.h>
47#include <errno.h>
48#include <stdio.h>
49#include <ctype.h>
50#include <string.h>
51#include <syslog.h>
52#include <stdlib.h>
53#include <netgroup.h>
54
55int
56rresvport(alport)
57 int *alport;
58{
59 return rresvport_af(alport, AF_INET);
60}
61
62
63int
64rresvport_af(alport, af)
65 int *alport;
66 int af;
67{
68 struct sockaddr_storage ss;
69 struct sockaddr *sa;
70 u_int16_t *portp;
71 int s;
72
73 bzero(&ss, sizeof ss);
74 sa = (struct sockaddr *)&ss;
75
76 switch (af) {
77 case AF_INET:
78 sa->sa_len = sizeof(struct sockaddr_in);
79 portp = &((struct sockaddr_in *)sa)->sin_port;
80 break;
81 case AF_INET6:
82 sa->sa_len = sizeof(struct sockaddr_in6);
83 portp = &((struct sockaddr_in6 *)sa)->sin6_port;
84 break;
85 default:
86 errno = EPFNOSUPPORT;
87 return (-1);
88 }
89 sa->sa_family = af;
90
91 s = socket(af, SOCK_STREAM, 0);
92 if (s < 0)
93 return (-1);
94
95 *portp = htons(*alport);
96 if (*alport < IPPORT_RESERVED - 1) {
97 if (bind(s, sa, sa->sa_len) >= 0)
98 return (s);
99 if (errno != EADDRINUSE) {
100 (void)close(s);
101 return (-1);
102 }
103 }
104
105 *portp = 0;
106 sa->sa_family = af;
107 if (bindresvport_sa(s, sa) == -1) {
108 (void)close(s);
109 return (-1);
110 }
111 *alport = ntohs(*portp);
112 return (s);
113}
diff --git a/src/lib/libc/net/rthdr.c b/src/lib/libc/net/rthdr.c
new file mode 100644
index 0000000000..366ca9e6ba
--- /dev/null
+++ b/src/lib/libc/net/rthdr.c
@@ -0,0 +1,228 @@
1/* $OpenBSD: rthdr.c,v 1.6 2003/06/11 02:54: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 +
51 sizeof(struct ip6_rthdr0)));
52 default:
53 return (0);
54 }
55}
56
57struct cmsghdr *
58inet6_rthdr_init(bp, type)
59 void *bp;
60 int type;
61{
62 struct cmsghdr *ch = (struct cmsghdr *)bp;
63 struct ip6_rthdr *rthdr;
64
65 rthdr = (struct ip6_rthdr *)CMSG_DATA(ch);
66
67 ch->cmsg_level = IPPROTO_IPV6;
68 ch->cmsg_type = IPV6_RTHDR;
69
70 switch (type) {
71 case IPV6_RTHDR_TYPE_0:
72 ch->cmsg_len = CMSG_LEN(sizeof(struct ip6_rthdr0));
73 bzero(rthdr, sizeof(struct ip6_rthdr0));
74 rthdr->ip6r_type = IPV6_RTHDR_TYPE_0;
75 return (ch);
76 default:
77 return (NULL);
78 }
79}
80
81int
82inet6_rthdr_add(cmsg, addr, flags)
83 struct cmsghdr *cmsg;
84 const struct in6_addr *addr;
85 u_int flags;
86{
87 struct ip6_rthdr *rthdr;
88
89 rthdr = (struct ip6_rthdr *)CMSG_DATA(cmsg);
90
91 switch (rthdr->ip6r_type) {
92 case IPV6_RTHDR_TYPE_0:
93 {
94 struct ip6_rthdr0 *rt0 = (struct ip6_rthdr0 *)rthdr;
95 if (flags != IPV6_RTHDR_LOOSE)
96 return (-1);
97 if (rt0->ip6r0_segleft == 23)
98 return (-1);
99 rt0->ip6r0_segleft++;
100 bcopy(addr, (caddr_t)rt0 + ((rt0->ip6r0_len + 1) << 3),
101 sizeof(struct in6_addr));
102 rt0->ip6r0_len += sizeof(struct in6_addr) >> 3;
103 cmsg->cmsg_len = CMSG_LEN((rt0->ip6r0_len + 1) << 3);
104 break;
105 }
106 default:
107 return (-1);
108 }
109
110 return (0);
111}
112
113int
114inet6_rthdr_lasthop(cmsg, flags)
115 struct cmsghdr *cmsg;
116 unsigned int flags;
117{
118 struct ip6_rthdr *rthdr;
119
120 rthdr = (struct ip6_rthdr *)CMSG_DATA(cmsg);
121
122 switch (rthdr->ip6r_type) {
123 case IPV6_RTHDR_TYPE_0:
124 {
125 struct ip6_rthdr0 *rt0 = (struct ip6_rthdr0 *)rthdr;
126 if (flags != IPV6_RTHDR_LOOSE)
127 return (-1);
128 if (rt0->ip6r0_segleft > 23)
129 return (-1);
130 break;
131 }
132 default:
133 return (-1);
134 }
135
136 return (0);
137}
138
139#if 0
140int
141inet6_rthdr_reverse(in, out)
142 const struct cmsghdr *in;
143 struct cmsghdr *out;
144{
145
146 return (-1);
147}
148#endif
149
150int
151inet6_rthdr_segments(cmsg)
152 const struct cmsghdr *cmsg;
153{
154 struct ip6_rthdr *rthdr;
155
156 rthdr = (struct ip6_rthdr *)CMSG_DATA(cmsg);
157
158 switch (rthdr->ip6r_type) {
159 case IPV6_RTHDR_TYPE_0:
160 {
161 struct ip6_rthdr0 *rt0 = (struct ip6_rthdr0 *)rthdr;
162
163 if (rt0->ip6r0_len % 2 || 46 < rt0->ip6r0_len)
164 return (-1);
165
166 return (rt0->ip6r0_len * 8) / sizeof(struct in6_addr);
167 }
168
169 default:
170 return (-1);
171 }
172}
173
174struct in6_addr *
175inet6_rthdr_getaddr(cmsg, index)
176 struct cmsghdr *cmsg;
177 int index;
178{
179 struct ip6_rthdr *rthdr;
180
181 rthdr = (struct ip6_rthdr *)CMSG_DATA(cmsg);
182
183 switch (rthdr->ip6r_type) {
184 case IPV6_RTHDR_TYPE_0:
185 {
186 struct ip6_rthdr0 *rt0 = (struct ip6_rthdr0 *)rthdr;
187 int naddr;
188
189 if (rt0->ip6r0_len % 2 || 46 < rt0->ip6r0_len)
190 return NULL;
191 naddr = (rt0->ip6r0_len * 8) / sizeof(struct in6_addr);
192 if (index <= 0 || naddr < index)
193 return NULL;
194 return ((struct in6_addr *)(rt0 + 1)) + index;
195 }
196
197 default:
198 return NULL;
199 }
200}
201
202int
203inet6_rthdr_getflags(cmsg, index)
204 const struct cmsghdr *cmsg;
205 int index;
206{
207 struct ip6_rthdr *rthdr;
208
209 rthdr = (struct ip6_rthdr *)CMSG_DATA(cmsg);
210
211 switch (rthdr->ip6r_type) {
212 case IPV6_RTHDR_TYPE_0:
213 {
214 struct ip6_rthdr0 *rt0 = (struct ip6_rthdr0 *)rthdr;
215 int naddr;
216
217 if (rt0->ip6r0_len % 2 || 46 < rt0->ip6r0_len)
218 return (-1);
219 naddr = (rt0->ip6r0_len * 8) / sizeof(struct in6_addr);
220 if (index < 0 || naddr < index)
221 return (-1);
222 return IPV6_RTHDR_LOOSE;
223 }
224
225 default:
226 return (-1);
227 }
228}
diff --git a/src/lib/libc/net/send.c b/src/lib/libc/net/send.c
index 88f3550ec6..8a7cc74e2d 100644
--- a/src/lib/libc/net/send.c
+++ b/src/lib/libc/net/send.c
@@ -1,5 +1,3 @@
1/* $NetBSD: send.c,v 1.6 1995/02/25 06:21:02 cgd Exp $ */
2
3/* 1/*
4 * Copyright (c) 1988, 1993 2 * Copyright (c) 1988, 1993
5 * The Regents of the University of California. All rights reserved. 3 * The Regents of the University of California. All rights reserved.
@@ -12,11 +10,7 @@
12 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission. 15 * without specific prior written permission.
22 * 16 *
@@ -34,11 +28,7 @@
34 */ 28 */
35 29
36#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
37#if 0 31static char rcsid[] = "$OpenBSD: send.c,v 1.3 2003/06/02 20:18:36 millert Exp $";
38static char sccsid[] = "@(#)send.c 8.2 (Berkeley) 2/21/94";
39#else
40static char rcsid[] = "$NetBSD: send.c,v 1.6 1995/02/25 06:21:02 cgd Exp $";
41#endif
42#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
43 33
44#include <sys/types.h> 34#include <sys/types.h>
diff --git a/src/lib/libc/net/sethostent.c b/src/lib/libc/net/sethostent.c
index 00f6499695..2a8df101d4 100644
--- a/src/lib/libc/net/sethostent.c
+++ b/src/lib/libc/net/sethostent.c
@@ -1,5 +1,3 @@
1/* $NetBSD: sethostent.c,v 1.4 1995/02/25 06:21:03 cgd Exp $ */
2
3/* 1/*
4 * Copyright (c) 1985, 1993 2 * Copyright (c) 1985, 1993
5 * The Regents of the University of California. All rights reserved. 3 * The Regents of the University of California. All rights reserved.
@@ -12,11 +10,7 @@
12 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission. 15 * without specific prior written permission.
22 * 16 *
@@ -34,11 +28,7 @@
34 */ 28 */
35 29
36#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
37#if 0 31static char rcsid[] = "$OpenBSD: sethostent.c,v 1.6 2003/06/02 20:18:36 millert Exp $";
38static char sccsid[] = "@(#)sethostent.c 8.1 (Berkeley) 6/4/93";
39#else
40static char rcsid[] = "$NetBSD: sethostent.c,v 1.4 1995/02/25 06:21:03 cgd Exp $";
41#endif
42#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
43 33
44#include <sys/param.h> 34#include <sys/param.h>
@@ -47,16 +37,25 @@ static char rcsid[] = "$NetBSD: sethostent.c,v 1.4 1995/02/25 06:21:03 cgd Exp $
47#include <netdb.h> 37#include <netdb.h>
48#include <resolv.h> 38#include <resolv.h>
49 39
40#include "thread_private.h"
41
50void 42void
51sethostent(stayopen) 43sethostent(stayopen)
44 int stayopen;
52{ 45{
46 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
47
48 if ((_resp->options & RES_INIT) == 0 && res_init() == -1)
49 return;
53 if (stayopen) 50 if (stayopen)
54 _res.options |= RES_STAYOPEN | RES_USEVC; 51 _resp->options |= RES_STAYOPEN | RES_USEVC;
55} 52}
56 53
57void 54void
58endhostent() 55endhostent()
59{ 56{
60 _res.options &= ~(RES_STAYOPEN | RES_USEVC); 57 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
61 _res_close(); 58
59 _resp->options &= ~(RES_STAYOPEN | RES_USEVC);
60 res_close();
62} 61}
diff --git a/src/lib/libc/net/vars6.c b/src/lib/libc/net/vars6.c
new file mode 100644
index 0000000000..a22d49d047
--- /dev/null
+++ b/src/lib/libc/net/vars6.c
@@ -0,0 +1,42 @@
1/* $OpenBSD: vars6.c,v 1.2 2003/05/10 10:56:47 jmc 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 constant 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
index 782a4ab022..74f8ff5e7a 100644
--- a/src/lib/libc/stdlib/Makefile.inc
+++ b/src/lib/libc/stdlib/Makefile.inc
@@ -1,24 +1,28 @@
1# from: @(#)Makefile.inc 5.6 (Berkeley) 6/4/91 1# $OpenBDS: Makefile.inc,v 1.6 1996/08/21 03:47:21 tholo Exp $
2# $Id: Makefile.inc,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $
3 2
4# stdlib sources 3# stdlib sources
5.PATH: ${.CURDIR}/arch/${MACHINE_ARCH}/stdlib ${.CURDIR}/stdlib 4.PATH: ${LIBCSRCDIR}/arch/${MACHINE_ARCH}/stdlib ${LIBCSRCDIR}/stdlib
6 5
7SRCS+= a64l.c abort.c atexit.c atoi.c atof.c atol.c bsearch.c calloc.c \ 6SRCS+= a64l.c abort.c atexit.c atoi.c atof.c atol.c atoll.c bsearch.c \
8 exit.c getenv.c getopt.c heapsort.c l64a.c malloc.c merge.c \ 7 calloc.c cfree.c exit.c ecvt.c gcvt.c getenv.c getopt_long.c \
8 getsubopt.c heapsort.c l64a.c llabs.c lsearch.c malloc.c merge.c \
9 multibyte.c putenv.c qsort.c radixsort.c rand.c random.c realpath.c \ 9 multibyte.c putenv.c qsort.c radixsort.c rand.c random.c realpath.c \
10 setenv.c strtod.c strtol.c strtoq.c strtoul.c strtouq.c system.c \ 10 setenv.c strtod.c strtol.c strtoll.c strtoul.c strtoull.c system.c \
11 _rand48.c drand48.c erand48.c jrand48.c lcong48.c lrand48.c \ 11 tfind.c tsearch.c _rand48.c drand48.c erand48.c jrand48.c lcong48.c \
12 mrand48.c nrand48.c seed48.c srand48.c qabs.c qdiv.c 12 lrand48.c mrand48.c nrand48.c seed48.c srand48.c qabs.c qdiv.c
13 13
14.if (${MACHINE_ARCH} == "m68k") 14.if (${MACHINE_ARCH} == "m68k")
15SRCS+= abs.S div.c labs.c ldiv.c 15SRCS+= abs.S div.c labs.c ldiv.c
16LSRCS+= abs.c
16.elif (${MACHINE_ARCH} == "i386") 17.elif (${MACHINE_ARCH} == "i386")
17SRCS+= abs.S div.S labs.S ldiv.S 18SRCS+= abs.S div.S labs.S ldiv.S
19LSRCS+= abs.c div.c labs.c ldiv.c
18.elif (${MACHINE_ARCH} == "ns32k") 20.elif (${MACHINE_ARCH} == "ns32k")
19SRCS+= abs.S div.c labs.c ldiv.c 21SRCS+= abs.S div.c labs.c ldiv.c
22LSRCS+= abs.c
20.elif (${MACHINE_ARCH} == "tahoe") 23.elif (${MACHINE_ARCH} == "tahoe")
21SRCS+= abs.S div.c labs.c ldiv.c 24SRCS+= abs.S div.c labs.c ldiv.c
25LSRCS+= abs.c
22.elif (${MACHINE_ARCH} == "vax") 26.elif (${MACHINE_ARCH} == "vax")
23SRCS+= abs.c div.c labs.c ldiv.c 27SRCS+= abs.c div.c labs.c ldiv.c
24.elif (${MACHINE_ARCH} == "alpha") 28.elif (${MACHINE_ARCH} == "alpha")
@@ -28,18 +32,37 @@ SRCS+= abs.c div.c labs.c ldiv.c
28SRCS+= abs.c div.c labs.c ldiv.c 32SRCS+= abs.c div.c labs.c ldiv.c
29.endif 33.endif
30 34
31MAN+= abort.3 abs.3 alloca.3 atexit.3 atof.3 atoi.3 atol.3 bsearch.3 \ 35.if (${MACHINE_ARCH} == "vax") || (${MACHINE_ARCH} == "m68k")
32 calloc.3 div.3 exit.3 free.3 getenv.3 getopt.3 labs.3 ldiv.3 \ 36SRCS+= insque.S remque.S
33 malloc.3 memory.3 qabs.3 qdiv.3 qsort.3 radixsort.3 rand48.3 \ 37.else
34 rand.3 random.3 realloc.3 realpath.3 strtod.3 strtol.3 strtoul.3 \ 38SRCS+= insque.c remque.c
35 system.3 39.endif
40
41MAN+= a64l.3 abort.3 abs.3 alloca.3 atexit.3 atof.3 atoi.3 atol.3 atoll.3 \
42 bsearch.3 div.3 ecvt.3 exit.3 getenv.3 getopt.3 getopt_long.3 \
43 getsubopt.3 insque.3 labs.3 ldiv.3 lsearch.3 malloc.3 qabs.3 \
44 qdiv.3 qsort.3 radixsort.3 rand48.3 rand.3 random.3 realpath.3 \
45 strtod.3 strtol.3 strtoul.3 system.3 tsearch.3
36 46
47MLINKS+=ecvt.3 fcvt.3 ecvt.3 gcvt.3
37MLINKS+=getenv.3 setenv.3 getenv.3 unsetenv.3 getenv.3 putenv.3 48MLINKS+=getenv.3 setenv.3 getenv.3 unsetenv.3 getenv.3 putenv.3
49MLINKS+=getopt_long.3 getopt_long_only.3
50MLINKS+=insque.3 remque.3
51MLINKS+=labs.3 llabs.3
52MLINKS+=lsearch.3 lfind.3
53MLINKS+=malloc.3 free.3 malloc.3 realloc.3 malloc.3 calloc.3
54MLINKS+=malloc.3 cfree.3 malloc.3 malloc.conf.5
38MLINKS+=qsort.3 heapsort.3 qsort.3 mergesort.3 55MLINKS+=qsort.3 heapsort.3 qsort.3 mergesort.3
39MLINKS+=rand.3 srand.3 56MLINKS+=radixsort.3 sradixsort.3
40MLINKS+=strtol.3 strtoq.3 57MLINKS+=rand.3 srand.3 rand.3 rand_r.3
41MLINKS+=strtoul.3 strtouq.3 58MLINKS+=random.3 initstate.3 random.3 setstate.3
42MLINKS+=random.3 initstate.3 random.3 setstate.3 random.3 srandom.3 59MLINKS+=random.3 srandom.3 random.3 srandomdev.3
43MLINKS+=rand48.3 drand48.3 rand48.3 erand48.3 rand48.3 lrand48.3 60MLINKS+=rand48.3 drand48.3 rand48.3 erand48.3 rand48.3 lrand48.3
44MLINKS+=rand48.3 mrand48.3 rand48.3 nrand48.3 rand48.3 jrand48.3 61MLINKS+=rand48.3 mrand48.3 rand48.3 nrand48.3 rand48.3 jrand48.3
45MLINKS+=rand48.3 srand48.3 rand48.3 seed48.3 rand48.3 lcong48.3 62MLINKS+=rand48.3 srand48.3 rand48.3 seed48.3 rand48.3 lcong48.3
63MLINKS+=strtol.3 strtoll.3 strtol.3 strtoq.3
64MLINKS+=strtoul.3 strtoull.3 strtoul.3 strtouq.3
65MLINKS+=tsearch.3 tfind.3
66MLINKS+=tsearch.3 tdelete.3
67MLINKS+=tsearch.3 twalk.3
68MLINKS+=a64l.3 l64a.3
diff --git a/src/lib/libc/stdlib/_rand48.c b/src/lib/libc/stdlib/_rand48.c
index 83ade4645a..fed7372f68 100644
--- a/src/lib/libc/stdlib/_rand48.c
+++ b/src/lib/libc/stdlib/_rand48.c
@@ -11,6 +11,10 @@
11 * to anyone/anything when using this software. 11 * to anyone/anything when using this software.
12 */ 12 */
13 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
14#include "rand48.h" 18#include "rand48.h"
15 19
16unsigned short __rand48_seed[3] = { 20unsigned short __rand48_seed[3] = {
diff --git a/src/lib/libc/stdlib/a64l.3 b/src/lib/libc/stdlib/a64l.3
new file mode 100644
index 0000000000..de70d0af71
--- /dev/null
+++ b/src/lib/libc/stdlib/a64l.3
@@ -0,0 +1,133 @@
1.\" $OpenBSD: a64l.3,v 1.8 2003/06/17 21:56:24 millert Exp $
2.\"
3.\" Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
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 THE AUTHOR DISCLAIMS ALL WARRANTIES
10.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16.\"
17.Dd August 17, 1997
18.Dt A64L 3
19.Os
20.Sh NAME
21.Nm a64l ,
22.Nm l64a
23.Nd convert between 32-bit integer and radix-64 ASCII string
24.Sh SYNOPSIS
25.Fd #include <stdlib.h>
26.Ft long
27.Fn a64l "const char *s"
28.Ft char *
29.Fn l64a "long l"
30.Sh DESCRIPTION
31The
32.Fn a64l
33and
34.Fn l64a
35functions are used to maintain numbers stored in radix-64
36.Tn ASCII
37characters.
38This is a notation by which 32-bit integers
39can be represented by up to six characters; each character represents a
40.Dq digit
41in a radix-64 notation.
42.Pp
43The characters used to represent digits are
44.Ql \&.
45for 0,
46.Ql /
47for 1,
48.Ql 0
49through
50.Ql 9
51for 2-11,
52.Ql A
53through
54.Ql Z
55for 12-37, and
56.Ql a
57through
58.Ql z
59for 38-63.
60.Pp
61The
62.Fn a64l
63function takes a pointer to a null-terminated radix-64 representation
64and returns a corresponding 32-bit value.
65If the string pointed to by
66.Fa s
67contains more than six characters,
68.Fn a64l
69will use the first six.
70.Fn a64l
71scans the character string from left to right, decoding
72each character as a 6-bit radix-64 number.
73If a long integer is
74larger than 32 bits, the return value will be sign-extended.
75.Pp
76.Fn l64a
77takes a long integer argument
78.Fa l
79and returns a pointer to the corresponding radix-64 representation.
80.Sh RETURN VALUES
81On success,
82.Fn a64l
83returns a 32-bit representation of
84.Fa s .
85If
86.Fa s
87is a null pointer or if it contains digits other than those described above,
88.Fn a64l
89returns \-1 and sets the global variable
90.Va errno
91to
92.Er EINVAL .
93.Pp
94On success,
95.Fn l64a
96returns a pointer to a string containing the radix-64 representation of
97.Fa l .
98If
99.Fa l
100is 0,
101.Fn l64a
102returns a pointer to the empty string.
103If
104.Fa l
105is negative,
106.Fn l64a
107returns a null pointer and sets the global variable
108.Va errno
109to
110.Er EINVAL .
111.Sh WARNINGS
112The value returned by
113.Fn l64a
114is a pointer into a static buffer, the contents of which
115will be overwritten by subsequent calls.
116.Pp
117The value returned by
118.Fn a64l
119may be incorrect if the value is too large; for that reason, only strings
120that resulted from a call to
121.Fn l64a
122should be used to call
123.Fn a64l .
124.Pp
125If a long integer is larger than 32 bits, only the low-order
12632 bits are used.
127.Sh STANDARDS
128The
129.Fn a64l
130and
131.Fn l64a
132functions conform to
133.St -xpg4.2 .
diff --git a/src/lib/libc/stdlib/a64l.c b/src/lib/libc/stdlib/a64l.c
index 03fc77e034..a68f0a6dcd 100644
--- a/src/lib/libc/stdlib/a64l.c
+++ b/src/lib/libc/stdlib/a64l.c
@@ -4,8 +4,11 @@
4 */ 4 */
5 5
6#if defined(LIBC_SCCS) && !defined(lint) 6#if defined(LIBC_SCCS) && !defined(lint)
7static char *rcsid = "$NetBSD: a64l.c,v 1.3 1995/05/11 23:04:47 jtc Exp $"; 7static char *rcsid = "$OpenBSD: a64l.c,v 1.3 1997/08/17 22:58:34 millert Exp $";
8#endif 8#endif /* LIBC_SCCS and not lint */
9
10#include <errno.h>
11#include <stdlib.h>
9 12
10long 13long
11a64l(s) 14a64l(s)
@@ -14,21 +17,30 @@ a64l(s)
14 long value, digit, shift; 17 long value, digit, shift;
15 int i; 18 int i;
16 19
20 if (s == NULL) {
21 errno = EINVAL;
22 return(-1L);
23 }
24
17 value = 0; 25 value = 0;
18 shift = 0; 26 shift = 0;
19 for (i = 0; *s && i < 6; i++, s++) { 27 for (i = 0; *s && i < 6; i++, s++) {
20 if (*s <= '/') 28 if (*s >= '.' && *s <= '/')
21 digit = *s - '.'; 29 digit = *s - '.';
22 else if (*s <= '9') 30 else if (*s >= '0' && *s <= '9')
23 digit = *s - '0' + 2; 31 digit = *s - '0' + 2;
24 else if (*s <= 'Z') 32 else if (*s >= 'A' && *s <= 'Z')
25 digit = *s - 'A' + 12; 33 digit = *s - 'A' + 12;
26 else 34 else if (*s >= 'a' && *s <= 'z')
27 digit = *s - 'a' + 38; 35 digit = *s - 'a' + 38;
36 else {
37 errno = EINVAL;
38 return(-1L);
39 }
28 40
29 value |= digit << shift; 41 value |= digit << shift;
30 shift += 6; 42 shift += 6;
31 } 43 }
32 44
33 return (long) value; 45 return(value);
34} 46}
diff --git a/src/lib/libc/stdlib/abort.3 b/src/lib/libc/stdlib/abort.3
index ab57327585..d411b859eb 100644
--- a/src/lib/libc/stdlib/abort.3
+++ b/src/lib/libc/stdlib/abort.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,8 +29,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)abort.3 6.7 (Berkeley) 6/29/91 32.\" $OpenBSD: abort.3,v 1.7 2003/06/02 20:18:37 millert Exp $
37.\" $Id: abort.3,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd June 29, 1991
40.Dt ABORT 3 35.Dt ABORT 3
@@ -49,23 +44,20 @@
49.Sh DESCRIPTION 44.Sh DESCRIPTION
50The 45The
51.Fn abort 46.Fn abort
52function causes abnormal program termination to occur, unless the 47function causes abnormal program termination to occur, unless the signal
53signal
54.Dv SIGABRT 48.Dv SIGABRT
55is being caught and the signal handler does not return. 49is being caught and the signal handler does not return.
56.Pp 50.Pp
57No open streams are closed or flushed. 51Any open streams are flushed and closed.
58.Sh RETURN VALUES 52.Sh RETURN VALUES
59The 53The
60.Nm abort 54.Fn abort
61function 55function never returns.
62never returns.
63.Sh SEE ALSO 56.Sh SEE ALSO
64.Xr sigaction 2 , 57.Xr sigaction 2 ,
65.Xr exit 2 58.Xr exit 3
66.Sh STANDARDS 59.Sh STANDARDS
67The 60The
68.Fn abort 61.Fn abort
69function 62function conforms to
70conforms to 63.St -p1003.1-90 .
71.St -ansiC .
diff --git a/src/lib/libc/stdlib/abort.c b/src/lib/libc/stdlib/abort.c
index c298e016b4..2430c124f9 100644
--- a/src/lib/libc/stdlib/abort.c
+++ b/src/lib/libc/stdlib/abort.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,26 +28,43 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)abort.c 5.11 (Berkeley) 2/23/91";*/ 31static char *rcsid = "$OpenBSD: abort.c,v 1.13 2004/01/20 19:35:17 millert Exp $";
36static char *rcsid = "$Id: abort.c,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
39#include <signal.h> 34#include <signal.h>
40#include <stdlib.h> 35#include <stdlib.h>
41#include <unistd.h> 36#include <unistd.h>
37#include "thread_private.h"
38#include "atexit.h"
42 39
43void 40void
44abort() 41abort(void)
45{ 42{
43 struct atexit *p = __atexit;
44 static int cleanup_called = 0;
46 sigset_t mask; 45 sigset_t mask;
47 46
47
48 sigfillset(&mask); 48 sigfillset(&mask);
49 /* 49 /*
50 * don't block SIGABRT to give any handler a chance; we ignore 50 * don't block SIGABRT to give any handler a chance; we ignore
51 * any errors -- X311J doesn't allow abort to return anyway. 51 * any errors -- X311J doesn't allow abort to return anyway.
52 */ 52 */
53 sigdelset(&mask, SIGABRT); 53 sigdelset(&mask, SIGABRT);
54 (void)sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL); 54 (void)_thread_sys_sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL);
55
56 /*
57 * POSIX requires we flush stdio buffers on abort
58 */
59 if (cleanup_called == 0) {
60 while (p != NULL && p->next != NULL)
61 p = p->next;
62 if (p != NULL && p->fns[0] != NULL) {
63 cleanup_called = 1;
64 (*p->fns[0])();
65 }
66 }
67
55 (void)kill(getpid(), SIGABRT); 68 (void)kill(getpid(), SIGABRT);
56 69
57 /* 70 /*
@@ -59,7 +72,7 @@ abort()
59 * it again, only harder. 72 * it again, only harder.
60 */ 73 */
61 (void)signal(SIGABRT, SIG_DFL); 74 (void)signal(SIGABRT, SIG_DFL);
62 (void)sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL); 75 (void)_thread_sys_sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL);
63 (void)kill(getpid(), SIGABRT); 76 (void)kill(getpid(), SIGABRT);
64 exit(1); 77 _exit(1);
65} 78}
diff --git a/src/lib/libc/stdlib/abs.3 b/src/lib/libc/stdlib/abs.3
index 4748d89e77..f0a6b8a23a 100644
--- a/src/lib/libc/stdlib/abs.3
+++ b/src/lib/libc/stdlib/abs.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,8 +29,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)abs.3 6.4 (Berkeley) 6/29/91 32.\" $OpenBSD: abs.3,v 1.6 2003/06/02 20:18:37 millert Exp $
37.\" $Id: abs.3,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd June 29, 1991
40.Dt ABS 3 35.Dt ABS 3
@@ -49,21 +44,17 @@
49.Sh DESCRIPTION 44.Sh DESCRIPTION
50The 45The
51.Fn abs 46.Fn abs
52function 47function computes the absolute value of the integer
53computes 48.Fa j .
54the absolute value of the integer
55.Ar j .
56.Sh RETURN VALUES 49.Sh RETURN VALUES
57The 50The
58.Fn abs 51.Fn abs
59function 52function returns the absolute value.
60returns
61the absolute value.
62.Sh SEE ALSO 53.Sh SEE ALSO
63.Xr floor 3 ,
64.Xr labs 3 ,
65.Xr cabs 3 , 54.Xr cabs 3 ,
55.Xr floor 3 ,
66.Xr hypot 3 , 56.Xr hypot 3 ,
57.Xr labs 3 ,
67.Xr math 3 58.Xr math 3
68.Sh STANDARDS 59.Sh STANDARDS
69The 60The
diff --git a/src/lib/libc/stdlib/abs.c b/src/lib/libc/stdlib/abs.c
index 64468e0224..c67ad9494f 100644
--- a/src/lib/libc/stdlib/abs.c
+++ b/src/lib/libc/stdlib/abs.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,8 +28,7 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)abs.c 5.2 (Berkeley) 5/17/90";*/ 31static char *rcsid = "$OpenBSD: abs.c,v 1.3 2003/06/02 20:18:37 millert Exp $";
36static char *rcsid = "$Id: abs.c,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
39#include <stdlib.h> 34#include <stdlib.h>
diff --git a/src/lib/libc/stdlib/alloca.3 b/src/lib/libc/stdlib/alloca.3
index dcb97ab11c..4136dc405c 100644
--- a/src/lib/libc/stdlib/alloca.3
+++ b/src/lib/libc/stdlib/alloca.3
@@ -9,11 +9,7 @@
9.\" 2. Redistributions in binary form must reproduce the above copyright 9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\" notice, this list of conditions and the following disclaimer in the 10.\" notice, this list of conditions and the following disclaimer in the
11.\" documentation and/or other materials provided with the distribution. 11.\" documentation and/or other materials provided with the distribution.
12.\" 3. All advertising materials mentioning features or use of this software 12.\" 3. Neither the name of the University nor the names of its contributors
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 13.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission. 14.\" without specific prior written permission.
19.\" 15.\"
@@ -29,12 +25,11 @@
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE. 26.\" SUCH DAMAGE.
31.\" 27.\"
32.\" from: @(#)alloca.3 5.1 (Berkeley) 5/2/91 28.\" $OpenBSD: alloca.3,v 1.10 2003/06/02 20:18:37 millert Exp $
33.\" $Id: alloca.3,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $
34.\" 29.\"
35.Dd May 2, 1991 30.Dd May 2, 1991
36.Dt ALLOCA 3 31.Dt ALLOCA 3
37.Os BSD 4 32.Os
38.Sh NAME 33.Sh NAME
39.Nm alloca 34.Nm alloca
40.Nd memory allocator 35.Nd memory allocator
@@ -45,35 +40,41 @@
45.Sh DESCRIPTION 40.Sh DESCRIPTION
46The 41The
47.Fn alloca 42.Fn alloca
48function 43function allocates
49allocates
50.Fa size 44.Fa size
51bytes of space in the stack frame of the caller. 45bytes of space in the stack frame of the caller.
52This temporary space is automatically freed on 46This temporary space is automatically freed on return.
53return.
54.Sh RETURN VALUES 47.Sh RETURN VALUES
55The 48The
56.Fn alloca 49.Fn alloca
57function returns a pointer to the beginning of the allocated space. 50function returns a pointer to the beginning of the allocated space.
58If the allocation failed, a
59.Dv NULL
60pointer is returned.
61.Sh SEE ALSO 51.Sh SEE ALSO
52.Xr pagesize 1 ,
62.Xr brk 2 , 53.Xr brk 2 ,
63.Xr pagesize 2
64.Xr calloc 3 , 54.Xr calloc 3 ,
65.Xr malloc 3 , 55.Xr malloc 3 ,
66.Xr realloc 3 , 56.Xr realloc 3
67.Sh BUGS 57.Sh BUGS
68The 58The
69.Fn alloca 59.Fn alloca
70function 60function is machine dependent; its use is discouraged.
71is machine dependent; its use is discouraged.
72.\" .Sh HISTORY 61.\" .Sh HISTORY
73.\" The 62.\" The
74.\" .Fn alloca 63.\" .Fn alloca
75.\" function appeared in 64.\" function appeared in
76.\" .Bx ?? . 65.\" .Bx ?? .
77.\" The function appeared in 32v, pwb and pwb.2 and in 3bsd 4bsd 66.\" The function appeared in 32v, pwb and pwb.2 and in 3bsd 4bsd
78.\" The first man page (or link to a man page that I can find at the 67.\" The first man page (or link to a man page that I can find at the
79.\" moment is 4.3... 68.\" moment is 4.3...
69.Pp
70The
71.Fn alloca
72function is slightly unsafe because it cannot ensure that the pointer
73returned points to a valid and usable block of memory.
74The allocation made may exceed the bounds of the stack, or even go
75further into other objects in memory, and
76.Fn alloca
77cannot determine such an error.
78Avoid
79.Fn alloca
80with large unbounded allocations.
diff --git a/src/lib/libc/stdlib/atexit.3 b/src/lib/libc/stdlib/atexit.3
index 07de054d3c..c8d4ce63d5 100644
--- a/src/lib/libc/stdlib/atexit.3
+++ b/src/lib/libc/stdlib/atexit.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,8 +29,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)atexit.3 5.3 (Berkeley) 6/29/91 32.\" $OpenBSD: atexit.3,v 1.5 2003/06/02 20:18:37 millert Exp $
37.\" $Id: atexit.3,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd June 29, 1991
40.Dt ATEXIT 3 35.Dt ATEXIT 3
@@ -49,13 +44,12 @@
49.Sh DESCRIPTION 44.Sh DESCRIPTION
50The 45The
51.Fn atexit 46.Fn atexit
52function 47function registers the given
53registers the given 48.Fa function
54.Ar function
55to be called at program exit, whether via 49to be called at program exit, whether via
56.Xr exit 3 50.Xr exit 3
57or via return from the program's 51or via return from the program's
58.Em main . 52.Fn main .
59Functions so registered are called in reverse order; 53Functions so registered are called in reverse order;
60no arguments are passed. 54no arguments are passed.
61At least 32 functions can always be registered, 55At least 32 functions can always be registered,
@@ -73,6 +67,5 @@ The existing list of functions is unmodified.
73.Sh STANDARDS 67.Sh STANDARDS
74The 68The
75.Fn atexit 69.Fn atexit
76function 70function conforms to
77conforms to
78.St -ansiC . 71.St -ansiC .
diff --git a/src/lib/libc/stdlib/atexit.c b/src/lib/libc/stdlib/atexit.c
index 4da1eb0d9c..98564d0dd3 100644
--- a/src/lib/libc/stdlib/atexit.c
+++ b/src/lib/libc/stdlib/atexit.c
@@ -1,68 +1,135 @@
1/*- 1/*
2 * Copyright (c) 1990 The Regents of the University of California. 2 * Copyright (c) 2002 Daniel Hartmeier
3 * All rights reserved. 3 * All rights reserved.
4 * 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 5 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
10 * are met: 7 * 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 * 8 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 9 * - Redistributions of source code must retain the above copyright
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 10 * notice, this list of conditions and the following disclaimer.
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 11 * - Redistributions in binary form must reproduce the above
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 12 * copyright notice, this list of conditions and the following
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 13 * disclaimer in the documentation and/or other materials provided
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 14 * with the distribution.
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 15 *
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
34 * SUCH DAMAGE. 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 *
35 */ 29 */
36 30
37#if defined(LIBC_SCCS) && !defined(lint) 31#if defined(LIBC_SCCS) && !defined(lint)
38/*static char *sccsid = "from: @(#)atexit.c 5.2 (Berkeley) 11/14/90";*/ 32static char *rcsid = "$OpenBSD: atexit.c,v 1.7 2002/09/14 22:03:14 dhartmei Exp $";
39static char *rcsid = "$Id: atexit.c,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */ 33#endif /* LIBC_SCCS and not lint */
41 34
35#include <sys/types.h>
36#include <sys/mman.h>
42#include <stdlib.h> 37#include <stdlib.h>
38#include <unistd.h>
43#include "atexit.h" 39#include "atexit.h"
44 40
41int __atexit_invalid = 1;
45struct atexit *__atexit; 42struct atexit *__atexit;
46 43
47/* 44/*
45 * Function pointers are stored in a linked list of pages. The list
46 * is initially empty, and pages are allocated on demand. The first
47 * function pointer in the first allocated page (the last one in
48 * the linked list) is reserved for the cleanup function.
49 *
50 * Outside the following two functions, all pages are mprotect()'ed
51 * to prevent unintentional/malicious corruption.
52 *
53 * The free(malloc(1)) is a workaround causing malloc_init() to
54 * ensure that malloc.c gets the first mmap() call for its sbrk()
55 * games.
56 */
57
58/*
48 * Register a function to be performed at exit. 59 * Register a function to be performed at exit.
49 */ 60 */
50int 61int
51atexit(fn) 62atexit(fn)
52 void (*fn)(); 63 void (*fn)();
53{ 64{
54 static struct atexit __atexit0; /* one guaranteed table */ 65 register struct atexit *p = __atexit;
55 register struct atexit *p; 66 register int pgsize = getpagesize();
56 67
57 if ((p = __atexit) == NULL) 68 if (pgsize < sizeof(*p))
58 __atexit = p = &__atexit0; 69 return (-1);
59 else if (p->ind >= ATEXIT_SIZE) { 70 if (p != NULL) {
60 if ((p = malloc(sizeof(*p))) == NULL) 71 if (p->ind + 1 >= p->max)
72 p = NULL;
73 else if (mprotect(p, pgsize, PROT_READ | PROT_WRITE))
74 return (-1);
75 }
76 if (p == NULL) {
77 if (__atexit_invalid) {
78 free(malloc(1));
79 __atexit_invalid = 0;
80 }
81 p = mmap(NULL, pgsize, PROT_READ | PROT_WRITE,
82 MAP_ANON | MAP_PRIVATE, -1, 0);
83 if (p == MAP_FAILED)
61 return (-1); 84 return (-1);
62 p->ind = 0; 85 if (__atexit == NULL) {
86 p->fns[0] = NULL;
87 p->ind = 1;
88 } else
89 p->ind = 0;
90 p->max = (pgsize - ((char *)&p->fns[0] - (char *)p)) /
91 sizeof(p->fns[0]);
63 p->next = __atexit; 92 p->next = __atexit;
64 __atexit = p; 93 __atexit = p;
65 } 94 }
66 p->fns[p->ind++] = fn; 95 p->fns[p->ind++] = fn;
96 if (mprotect(p, pgsize, PROT_READ))
97 return (-1);
67 return (0); 98 return (0);
68} 99}
100
101/*
102 * Register the cleanup function
103 */
104void
105__atexit_register_cleanup(fn)
106 void (*fn)();
107{
108 register struct atexit *p = __atexit;
109 register int pgsize = getpagesize();
110
111 if (pgsize < sizeof(*p))
112 return;
113 while (p != NULL && p->next != NULL)
114 p = p->next;
115 if (p == NULL) {
116 if (__atexit_invalid) {
117 free(malloc(1));
118 __atexit_invalid = 0;
119 }
120 p = mmap(NULL, pgsize, PROT_READ | PROT_WRITE,
121 MAP_ANON | MAP_PRIVATE, -1, 0);
122 if (p == MAP_FAILED)
123 return;
124 p->ind = 1;
125 p->max = (pgsize - ((char *)&p->fns[0] - (char *)p)) /
126 sizeof(p->fns[0]);
127 p->next = NULL;
128 __atexit = p;
129 } else {
130 if (mprotect(p, pgsize, PROT_READ | PROT_WRITE))
131 return;
132 }
133 p->fns[0] = fn;
134 mprotect(p, pgsize, PROT_READ);
135}
diff --git a/src/lib/libc/stdlib/atexit.h b/src/lib/libc/stdlib/atexit.h
index 8b756e8fe2..21b0c2e532 100644
--- a/src/lib/libc/stdlib/atexit.h
+++ b/src/lib/libc/stdlib/atexit.h
@@ -1,46 +1,41 @@
1/*- 1/* $OpenBSD: atexit.h,v 1.6 2003/07/31 07:08:42 deraadt Exp $ */
2 * Copyright (c) 1990 The Regents of the University of California. 2
3/*
4 * Copyright (c) 2002 Daniel Hartmeier
3 * All rights reserved. 5 * All rights reserved.
4 * 6 *
5 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
7 * are met: 9 * 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 * 10 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 11 * - Redistributions of source code must retain the above copyright
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 12 * notice, this list of conditions and the following disclaimer.
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 13 * - Redistributions in binary form must reproduce the above
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 14 * copyright notice, this list of conditions and the following
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 15 * disclaimer in the documentation and/or other materials provided
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 16 * with the distribution.
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 17 *
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31 * SUCH DAMAGE. 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.
32 * 30 *
33 * from: @(#)atexit.h 5.1 (Berkeley) 5/15/90
34 * $Id: atexit.h,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $
35 */ 31 */
36 32
37/* must be at least 32 to guarantee ANSI conformance */
38#define ATEXIT_SIZE 32
39
40struct atexit { 33struct atexit {
41 struct atexit *next; /* next in list */ 34 struct atexit *next; /* next in list */
42 int ind; /* next index in this table */ 35 int ind; /* next index in this table */
43 void (*fns[ATEXIT_SIZE])(); /* the table itself */ 36 int max; /* max entries >= ATEXIT_SIZE */
37 void (*fns[1])(void); /* the table itself */
44}; 38};
45 39
40extern int __atexit_invalid;
46extern struct atexit *__atexit; /* points to head of LIFO stack */ 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
index 53e04f71c5..c60b9e9fd7 100644
--- a/src/lib/libc/stdlib/atof.3
+++ b/src/lib/libc/stdlib/atof.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,8 +29,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)atof.3 6.4 (Berkeley) 6/29/91 32.\" $OpenBSD: atof.3,v 1.4 2003/06/02 20:18:37 millert Exp $
37.\" $Id: atof.3,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd June 29, 1991
40.Dt ATOF 3 35.Dt ATOF 3
@@ -52,9 +47,9 @@ string to double
52The 47The
53.Fn atof 48.Fn atof
54function converts the initial portion of the string pointed to by 49function converts the initial portion of the string pointed to by
55.Ar nptr 50.Fa nptr
56to 51to
57.Ar double 52.Li double
58representation. 53representation.
59.Pp 54.Pp
60It is equivalent to: 55It is equivalent to:
diff --git a/src/lib/libc/stdlib/atof.c b/src/lib/libc/stdlib/atof.c
index 9202de50bb..dad2b77bfd 100644
--- a/src/lib/libc/stdlib/atof.c
+++ b/src/lib/libc/stdlib/atof.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,8 +28,7 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)atof.c 5.3 (Berkeley) 1/8/93";*/ 31static char *rcsid = "$OpenBSD: atof.c,v 1.3 2003/06/02 20:18:37 millert Exp $";
36static char *rcsid = "$Id: atof.c,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
39#include <stdlib.h> 34#include <stdlib.h>
diff --git a/src/lib/libc/stdlib/atoi.3 b/src/lib/libc/stdlib/atoi.3
index 219ba73c00..070344a810 100644
--- a/src/lib/libc/stdlib/atoi.3
+++ b/src/lib/libc/stdlib/atoi.3
@@ -1,5 +1,5 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California. 1.\" Copyright (c) 1990, 1991, 1993
2.\" All rights reserved. 2.\" The Regents of the University of California. All rights reserved.
3.\" 3.\"
4.\" This code is derived from software contributed to Berkeley by 4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information 5.\" the American National Standards Committee X3, on Information
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,10 +29,9 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)atoi.3 5.3 (Berkeley) 6/29/91 32.\" $OpenBSD: atoi.3,v 1.7 2003/06/02 20:18:37 millert Exp $
37.\" $Id: atoi.3,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd June 4, 1993
40.Dt ATOI 3 35.Dt ATOI 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
@@ -52,13 +47,12 @@ string to integer
52The 47The
53.Fn atoi 48.Fn atoi
54function converts the initial portion of the string pointed to by 49function converts the initial portion of the string pointed to by
55.Em nptr 50.Fa nptr
56to 51to
57.Em integer 52.Li integer
58representation. 53representation.
59.Pp 54.Pp
60It is equivalent to: 55It is equivalent to:
61.Pp
62.Bd -literal -offset indent 56.Bd -literal -offset indent
63(int)strtol(nptr, (char **)NULL, 10); 57(int)strtol(nptr, (char **)NULL, 10);
64.Ed 58.Ed
@@ -73,3 +67,15 @@ The
73.Fn atoi 67.Fn atoi
74function conforms to 68function conforms to
75.St -ansiC . 69.St -ansiC .
70.Sh CAVEATS
71.Nm
72does no overflow checking, handles unsigned numbers poorly,
73and handles strings containing trailing extra characters
74(like
75.Dq "123abc" )
76poorly.
77Careful use of
78.Xr strtol 3
79and
80.Xr strtoul 3
81can alleviate these problems.
diff --git a/src/lib/libc/stdlib/atoi.c b/src/lib/libc/stdlib/atoi.c
index df7845f90c..b1fe789fd5 100644
--- a/src/lib/libc/stdlib/atoi.c
+++ b/src/lib/libc/stdlib/atoi.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,8 +28,7 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)atoi.c 5.7 (Berkeley) 2/23/91";*/ 31static char *rcsid = "$OpenBSD: atoi.c,v 1.3 2003/06/02 20:18:37 millert Exp $";
36static char *rcsid = "$Id: atoi.c,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
39#include <stdlib.h> 34#include <stdlib.h>
diff --git a/src/lib/libc/stdlib/atol.3 b/src/lib/libc/stdlib/atol.3
index 86e3d324a3..80e54c892d 100644
--- a/src/lib/libc/stdlib/atol.3
+++ b/src/lib/libc/stdlib/atol.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,8 +29,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)atol.3 5.3 (Berkeley) 6/29/91 32.\" $OpenBSD: atol.3,v 1.6 2003/06/02 20:18:37 millert Exp $
37.\" $Id: atol.3,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd June 29, 1991
40.Dt ATOL 3 35.Dt ATOL 3
@@ -52,9 +47,9 @@ string to long integer
52The 47The
53.Fn atol 48.Fn atol
54function converts the initial portion of the string pointed to by 49function converts the initial portion of the string pointed to by
55.Ar nptr 50.Fa nptr
56to 51to
57.Em long integer 52.Li long integer
58representation. 53representation.
59.Pp 54.Pp
60It is equivalent to: 55It is equivalent to:
@@ -64,12 +59,12 @@ strtol(nptr, (char **)NULL, 10);
64.Sh SEE ALSO 59.Sh SEE ALSO
65.Xr atof 3 , 60.Xr atof 3 ,
66.Xr atoi 3 , 61.Xr atoi 3 ,
62.Xr atoll 3 ,
67.Xr strtod 3 , 63.Xr strtod 3 ,
68.Xr strtol 3 , 64.Xr strtol 3 ,
69.Xr strtoul 3 65.Xr strtoul 3
70.Sh STANDARDS 66.Sh STANDARDS
71The 67The
72.Fn atol 68.Fn atol
73function 69function conforms to
74conforms to 70.St -ansiC-99 .
75.St -ansiC .
diff --git a/src/lib/libc/stdlib/atol.c b/src/lib/libc/stdlib/atol.c
index 31ed06298b..83adad3eae 100644
--- a/src/lib/libc/stdlib/atol.c
+++ b/src/lib/libc/stdlib/atol.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,8 +28,7 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)atol.c 5.7 (Berkeley) 2/23/91";*/ 31static char *rcsid = "$OpenBSD: atol.c,v 1.3 2003/06/02 20:18:37 millert Exp $";
36static char *rcsid = "$Id: atol.c,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
39#include <stdlib.h> 34#include <stdlib.h>
diff --git a/src/lib/libc/stdlib/calloc.3 b/src/lib/libc/stdlib/atoll.3
index d0754b46a0..40584e9d47 100644
--- a/src/lib/libc/stdlib/calloc.3
+++ b/src/lib/libc/stdlib/atoll.3
@@ -1,4 +1,4 @@
1.\" Copyright (c) 1991 The Regents of the University of California. 1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved. 2.\" All rights reserved.
3.\" 3.\"
4.\" This code is derived from software contributed to Berkeley by 4.\" This code is derived from software contributed to Berkeley by
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,39 +29,42 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)calloc.3 5.2 (Berkeley) 6/29/91 32.\" $OpenBSD: atoll.3,v 1.3 2003/06/02 20:18:37 millert Exp $
37.\" $Id: calloc.3,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd June 29, 1991
40.Dt CALLOC 3 35.Dt ATOLL 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
43.Nm calloc 38.Nm atoll
44.Nd allocate clean memory (zero initialized space) 39.Nd convert
40.Tn ASCII
41string to long long integer
45.Sh SYNOPSIS 42.Sh SYNOPSIS
46.Fd #include <stdlib.h> 43.Fd #include <stdlib.h>
47.Ft void * 44.Ft long long
48.Fn calloc "size_t nmemb" "size_t size" 45.Fn atoll "const char *nptr"
49.Sh DESCRIPTION 46.Sh DESCRIPTION
50The 47The
51.Fn calloc 48.Fn atoll
52function allocates space for an array of 49function converts the initial portion of the string pointed to by
53.Fa nmemb 50.Fa nptr
54objects, each of whose size is 51to
55.Fa size . 52.Li long integer
56The space is initialized to all bits zero. 53representation.
57.Sh RETURN VALUES 54.Pp
58The 55It is equivalent to:
59.Fn calloc 56.Bd -literal -offset indent
60function returns 57strtoll(nptr, (char **)NULL, 10);
61a pointer to the 58.Ed
62the allocated space if successful; otherwise a null pointer is returned.
63.Sh SEE ALSO 59.Sh SEE ALSO
64.Xr malloc 3 , 60.Xr atof 3 ,
65.Xr realloc 3 , 61.Xr atoi 3 ,
66.Xr free 3 62.Xr atol 3 ,
63.Xr strtod 3 ,
64.Xr strtol 3 ,
65.Xr strtoul 3
67.Sh STANDARDS 66.Sh STANDARDS
68The 67The
69.Fn calloc 68.Fn atoll
70function conforms to 69function conforms to
71.St -ansiC . 70.St -ansiC-99 .
diff --git a/src/lib/libc/stdlib/atoll.c b/src/lib/libc/stdlib/atoll.c
new file mode 100644
index 0000000000..6786b62e1a
--- /dev/null
+++ b/src/lib/libc/stdlib/atoll.c
@@ -0,0 +1,41 @@
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. Neither the name of the University nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#if defined(LIBC_SCCS) && !defined(lint)
31static char *rcsid = "$OpenBSD: atoll.c,v 1.2 2003/06/02 20:18:37 millert Exp $";
32#endif /* LIBC_SCCS and not lint */
33
34#include <stdlib.h>
35
36long long
37atoll(str)
38 const char *str;
39{
40 return(strtoll(str, (char **)NULL, 10));
41}
diff --git a/src/lib/libc/stdlib/bsearch.3 b/src/lib/libc/stdlib/bsearch.3
index 1622c96c6b..d1dd9173db 100644
--- a/src/lib/libc/stdlib/bsearch.3
+++ b/src/lib/libc/stdlib/bsearch.3
@@ -1,5 +1,5 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California. 1.\" Copyright (c) 1990, 1991, 1993, 1994
2.\" All rights reserved. 2.\" The Regents of the University of California. All rights reserved.
3.\" 3.\"
4.\" This code is derived from software contributed to Berkeley by 4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information 5.\" the American National Standards Committee X3, on Information
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,10 +29,9 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)bsearch.3 5.6 (Berkeley) 6/29/91 32.\" $OpenBSD: bsearch.3,v 1.6 2003/06/02 20:18:37 millert Exp $
37.\" $Id: bsearch.3,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd April 19, 1994
40.Dt BSEARCH 3 35.Dt BSEARCH 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
@@ -51,12 +46,12 @@ The
51.Fn bsearch 46.Fn bsearch
52function searches an array of 47function searches an array of
53.Fa nmemb 48.Fa nmemb
54objects, the initial member of which is 49objects, the initial member of which is
55pointed to by 50pointed to by
56.Fa base , 51.Fa base ,
57for a member that matches the object pointed to by 52for a member that matches the object pointed to by
58.Fa key . 53.Fa key .
59The size of each member of the array is specified by 54The size of each member of the array is specified by
60.Fa size . 55.Fa size .
61.Pp 56.Pp
62The contents of the array should be in ascending sorted order according 57The contents of the array should be in ascending sorted order according
@@ -64,9 +59,7 @@ to the comparison function referenced by
64.Fa compar . 59.Fa compar .
65The 60The
66.Fa compar 61.Fa compar
67routine 62routine is expected to have two arguments which point to the
68is expected to have two
69two arguments which point to the
70.Fa key 63.Fa key
71object and to an array member, in that order, and should return an integer 64object and to an array member, in that order, and should return an integer
72less than, equal to, or greater than zero if the 65less than, equal to, or greater than zero if the
@@ -83,7 +76,7 @@ If two members compare as equal, which member is matched is unspecified.
83.Xr db 3 , 76.Xr db 3 ,
84.Xr lsearch 3 , 77.Xr lsearch 3 ,
85.Xr qsort 3 , 78.Xr qsort 3 ,
86.\" .Xr tsearch 3 79.Xr tsearch 3
87.Sh STANDARDS 80.Sh STANDARDS
88The 81The
89.Fn bsearch 82.Fn bsearch
diff --git a/src/lib/libc/stdlib/bsearch.c b/src/lib/libc/stdlib/bsearch.c
index fac03f694f..9bfbf64256 100644
--- a/src/lib/libc/stdlib/bsearch.c
+++ b/src/lib/libc/stdlib/bsearch.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,8 +28,7 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)bsearch.c 5.4 (Berkeley) 2/23/91";*/ 31static char *rcsid = "$OpenBSD: bsearch.c,v 1.4 2003/06/02 20:18:37 millert Exp $";
36static char *rcsid = "$Id: bsearch.c,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
39#include <stdlib.h> 34#include <stdlib.h>
@@ -60,7 +55,7 @@ bsearch(key, base0, nmemb, size, compar)
60 const void *base0; 55 const void *base0;
61 size_t nmemb; 56 size_t nmemb;
62 register size_t size; 57 register size_t size;
63 register int (*compar) __P((const void *, const void *)); 58 register int (*compar)(const void *, const void *);
64{ 59{
65 register const char *base = base0; 60 register const char *base = base0;
66 register int lim, cmp; 61 register int lim, cmp;
diff --git a/src/lib/libc/stdlib/calloc.c b/src/lib/libc/stdlib/calloc.c
index 3353fab052..b0703cc884 100644
--- a/src/lib/libc/stdlib/calloc.c
+++ b/src/lib/libc/stdlib/calloc.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,12 +28,13 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)calloc.c 5.6 (Berkeley) 2/23/91";*/ 31static char *rcsid = "$OpenBSD: calloc.c,v 1.8 2003/06/02 20:18:37 millert Exp $";
36static char *rcsid = "$Id: calloc.c,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
39#include <stdlib.h> 34#include <stdlib.h>
40#include <string.h> 35#include <string.h>
36#include <limits.h>
37#include <errno.h>
41 38
42void * 39void *
43calloc(num, size) 40calloc(num, size)
@@ -46,8 +43,13 @@ calloc(num, size)
46{ 43{
47 register void *p; 44 register void *p;
48 45
46 if (num && size && SIZE_T_MAX / num < size) {
47 errno = ENOMEM;
48 return NULL;
49 }
49 size *= num; 50 size *= num;
50 if (p = malloc(size)) 51 p = malloc(size);
51 memset(p, '\0', size); 52 if (p)
53 memset(p, 0, size);
52 return(p); 54 return(p);
53} 55}
diff --git a/src/lib/libc/stdlib/cfree.c b/src/lib/libc/stdlib/cfree.c
new file mode 100644
index 0000000000..ecbc11d6c3
--- /dev/null
+++ b/src/lib/libc/stdlib/cfree.c
@@ -0,0 +1,45 @@
1/* $OpenBSD: cfree.c,v 1.3 2003/07/18 23:05:13 david 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 *
16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
17 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
18 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
19 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#if defined(LIBC_SCCS) && !defined(lint)
29static char rcsid[] = "$OpenBSD: cfree.c,v 1.3 2003/07/18 23:05:13 david Exp $";
30#endif /* LIBC_SCCS and not lint */
31
32#include <sys/cdefs.h>
33#include <stdlib.h>
34
35#ifdef __indr_reference
36__indr_reference(free, cfree);
37#else
38
39void
40cfree(p)
41 void *p;
42{
43 free(p);
44}
45#endif
diff --git a/src/lib/libc/stdlib/div.3 b/src/lib/libc/stdlib/div.3
index a4730694a5..a75614310e 100644
--- a/src/lib/libc/stdlib/div.3
+++ b/src/lib/libc/stdlib/div.3
@@ -11,11 +11,7 @@
11.\" 2. Redistributions in binary form must reproduce the above copyright 11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the 12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution. 13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software 14.\" 3. Neither the name of the University nor the names of its contributors
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 15.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission. 16.\" without specific prior written permission.
21.\" 17.\"
@@ -31,8 +27,7 @@
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE. 28.\" SUCH DAMAGE.
33.\" 29.\"
34.\" from: @(#)div.3 5.2 (Berkeley) 4/19/91 30.\" $OpenBSD: div.3,v 1.7 2004/01/23 23:08:46 jmc Exp $
35.\" $Id: div.3,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $
36.\" 31.\"
37.Dd April 19, 1991 32.Dd April 19, 1991
38.Dt DIV 3 33.Dt DIV 3
@@ -47,24 +42,22 @@
47.Sh DESCRIPTION 42.Sh DESCRIPTION
48The 43The
49.Fn div 44.Fn div
50function 45function computes the value
51computes the value 46.Fa num Ns / Ns Fa denom
52.Fa num/denom
53and returns the quotient and remainder in a structure named 47and returns the quotient and remainder in a structure named
54.Fa div_t 48.Fa div_t
55that contains two 49that contains two
56.Em int 50.Li int
57members named 51members named
58.Fa quot 52.Fa quot
59and 53and
60.Fa rem . 54.Fa rem .
61.Sh SEE ALSO 55.Sh SEE ALSO
62.Xr ldiv 3 , 56.Xr ldiv 3 ,
63.Xr qdiv 3 , 57.Xr math 3 ,
64.Xr math 3 58.Xr qdiv 3
65.Sh STANDARDS 59.Sh STANDARDS
66The 60The
67.Fn div 61.Fn div
68function 62function conforms to
69conforms to
70.St -ansiC . 63.St -ansiC .
diff --git a/src/lib/libc/stdlib/div.c b/src/lib/libc/stdlib/div.c
index 122ac0deec..9e070dcd64 100644
--- a/src/lib/libc/stdlib/div.c
+++ b/src/lib/libc/stdlib/div.c
@@ -13,11 +13,7 @@
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software 16 * 3. Neither the name of the University nor the names of its contributors
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 17 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission. 18 * without specific prior written permission.
23 * 19 *
@@ -35,8 +31,7 @@
35 */ 31 */
36 32
37#if defined(LIBC_SCCS) && !defined(lint) 33#if defined(LIBC_SCCS) && !defined(lint)
38/*static char *sccsid = "from: @(#)div.c 5.2 (Berkeley) 4/16/91";*/ 34static char *rcsid = "$OpenBSD: div.c,v 1.3 2003/06/02 20:18:37 millert Exp $";
39static char *rcsid = "$Id: div.c,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */ 35#endif /* LIBC_SCCS and not lint */
41 36
42#include <stdlib.h> /* div_t */ 37#include <stdlib.h> /* div_t */
diff --git a/src/lib/libc/stdlib/drand48.c b/src/lib/libc/stdlib/drand48.c
index ae1a8634dc..02886d5b62 100644
--- a/src/lib/libc/stdlib/drand48.c
+++ b/src/lib/libc/stdlib/drand48.c
@@ -11,6 +11,10 @@
11 * to anyone/anything when using this software. 11 * to anyone/anything when using this software.
12 */ 12 */
13 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
14#include "rand48.h" 18#include "rand48.h"
15 19
16extern unsigned short __rand48_seed[3]; 20extern unsigned short __rand48_seed[3];
diff --git a/src/lib/libc/stdlib/ecvt.3 b/src/lib/libc/stdlib/ecvt.3
new file mode 100644
index 0000000000..689cb1c6f9
--- /dev/null
+++ b/src/lib/libc/stdlib/ecvt.3
@@ -0,0 +1,165 @@
1.\" $OpenBSD: ecvt.3,v 1.7 2004/01/25 14:48:32 jmc Exp $
2.\"
3.\" Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com>
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 THE AUTHOR DISCLAIMS ALL WARRANTIES
10.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16.\"
17.\" Sponsored in part by the Defense Advanced Research Projects
18.\" Agency (DARPA) and Air Force Research Laboratory, Air Force
19.\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
20.\"
21.Dd December 1, 2002
22.Dt ECVT 3
23.Os
24.Sh NAME
25.Nm ecvt ,
26.Nm fcvt ,
27.Nm gcvt
28.Nd convert double to
29.Tn ASCII
30string
31.Sh SYNOPSIS
32.Fd #include <stdlib.h>
33.Ft char *
34.Fn ecvt "double value" "int ndigit" "int *decpt" "int *sign"
35.Ft char *
36.Fn fcvt "double value" "int ndigit" "int *decpt" "int *sign"
37.Ft char *
38.Fn gcvt "double value" "int ndigit" "char *buf"
39.Sh DESCRIPTION
40.Bf -symbolic
41These functions are provided for compatibility with legacy code.
42New code should use the
43.Xr snprintf 3
44function for improved safety and portability.
45.Ef
46.Pp
47The
48.Fn ecvt ,
49.Fn fcvt
50and
51.Fn gcvt
52functions convert the double precision floating-point number
53.Fa value
54to a NUL-terminated
55.Tn ASCII
56string.
57.Pp
58The
59.Fn ecvt
60function converts
61.Fa value
62to a NUL-terminated string of exactly
63.Fa ndigit
64digits and returns a pointer to that string.
65The result is padded with zeroes from left to right as needed.
66There are no leading zeroes unless
67.Fa value
68itself is 0.
69The least significant digit is rounded in an implementation-dependent manner.
70The position of the decimal point relative to the beginning of the string
71is stored in
72.Fa decpt .
73A negative value indicates that the decimal point is located
74to the left of the returned digits (this occurs when there is no
75whole number component to
76.Fa value ) .
77If
78.Fa value
79is zero, it is unspecified whether the integer pointed to by
80.Fa decpt
81will be 0 or 1.
82The decimal point itself is not included in the returned string.
83If the sign of the result is negative, the integer pointed to by
84.Fa sign
85is non-zero; otherwise, it is 0.
86.Pp
87If the converted value is out of range or is not representable,
88the contents of the returned string are unspecified.
89.Pp
90The
91.Fn fcvt
92function is identical to
93.Fn ecvt
94with the exception that
95.Fa ndigit
96specifies the number of digits after the decimal point (zero-padded as
97needed).
98.Pp
99The
100.Fn gcvt
101function converts
102.Fa value
103to a NUL-terminated string similar to the %g
104.Xr printf 3
105format specifier and stores the result in
106.Fa buf .
107It produces
108.Fa ndigit
109significant digits similar to the %f
110.Xr printf 3
111format specifier where possible.
112If
113.Fa ndigit
114does allow sufficient precision, the result is stored in
115exponential notation similar to the %e
116.Xr printf 3
117format specifier.
118If
119.Fa value
120is less than zero,
121.Fa buf
122will be prefixed with a minus sign.
123A decimal point is included in the returned string if
124.Fa value
125is not a whole number.
126Unlike the
127.Fn ecvt
128and
129.Fn fcvt
130functions,
131.Fa buf
132is not zero-padded.
133.Sh RETURN VALUES
134The
135.Fn ecvt ,
136.Fn fcvt
137and
138.Fn gcvt
139functions return a NUL-terminated string representation of
140.Fa value .
141.Sh WARNINGS
142The
143.Fn ecvt
144and
145.Fn fcvt
146functions return a pointer to internal storage space that will be
147overwritten by subsequent calls to either function.
148.Pp
149The maximum possible precision of the return value is limited by the
150precision of a double and may not be the same on all architectures.
151.Pp
152The
153.Xr snprintf 3
154function is preferred over these functions for new code.
155.Sh SEE ALSO
156.Xr printf 3 ,
157.Xr strtod 3
158.Sh STANDARDS
159The
160.Fn ecvt ,
161.Fn fcvt
162and
163.Fn gcvt
164functions conform to
165.St -p1003.1-2001 .
diff --git a/src/lib/libc/stdlib/ecvt.c b/src/lib/libc/stdlib/ecvt.c
new file mode 100644
index 0000000000..657c531808
--- /dev/null
+++ b/src/lib/libc/stdlib/ecvt.c
@@ -0,0 +1,103 @@
1/* $OpenBSD: ecvt.c,v 1.3 2003/06/17 21:56:24 millert Exp $ */
2
3/*
4 * Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com>
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 THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 *
18 * Sponsored in part by the Defense Advanced Research Projects
19 * Agency (DARPA) and Air Force Research Laboratory, Air Force
20 * Materiel Command, USAF, under agreement number F39502-99-1-0512.
21 */
22
23#if defined(LIBC_SCCS) && !defined(lint)
24static char rcsid[] = "$OpenBSD: ecvt.c,v 1.3 2003/06/17 21:56:24 millert Exp $";
25#endif /* LIBC_SCCS and not lint */
26
27#include <stdio.h>
28#include <stdlib.h>
29#include <string.h>
30
31extern char *__dtoa(double, int, int, int *, int *, char **);
32static char *__cvt(double, int, int *, int *, int, int);
33
34static char *
35__cvt(double value, int ndigit, int *decpt, int *sign, int fmode, int pad)
36{
37 static char *s;
38 char *p, *rve;
39 size_t siz;
40
41 if (ndigit == 0) {
42 *sign = value < 0.0;
43 *decpt = 0;
44 return ("");
45 }
46
47 if (s) {
48 free(s);
49 s = NULL;
50 }
51
52 if (ndigit < 0)
53 siz = -ndigit + 1;
54 else
55 siz = ndigit + 1;
56
57
58 /* __dtoa() doesn't allocate space for 0 so we do it by hand */
59 if (value == 0.0) {
60 *decpt = 1 - fmode; /* 1 for 'e', 0 for 'f' */
61 *sign = 0;
62 if ((rve = s = (char *)malloc(siz)) == NULL)
63 return(NULL);
64 *rve++ = '0';
65 *rve = '\0';
66 } else {
67 p = __dtoa(value, fmode + 2, ndigit, decpt, sign, &rve);
68 if (*decpt == 9999) {
69 /* Nan or Infinity */
70 *decpt = 0;
71 return(p);
72 }
73 /* make a local copy and adjust rve to be in terms of s */
74 if (pad && fmode)
75 siz += *decpt;
76 if ((s = (char *)malloc(siz)) == NULL)
77 return(NULL);
78 (void) strlcpy(s, p, siz);
79 rve = s + (rve - p);
80 }
81
82 /* Add trailing zeros (unless we got NaN or Inf) */
83 if (pad && *decpt != 9999) {
84 siz -= rve - s;
85 while (--siz)
86 *rve++ = '0';
87 *rve = '\0';
88 }
89
90 return(s);
91}
92
93char *
94ecvt(double value, int ndigit, int *decpt, int *sign)
95{
96 return(__cvt(value, ndigit, decpt, sign, 0, 1));
97}
98
99char *
100fcvt(double value, int ndigit, int *decpt, int *sign)
101{
102 return(__cvt(value, ndigit, decpt, sign, 1, 1));
103}
diff --git a/src/lib/libc/stdlib/erand48.c b/src/lib/libc/stdlib/erand48.c
index cc9fbf770c..b92dacffcc 100644
--- a/src/lib/libc/stdlib/erand48.c
+++ b/src/lib/libc/stdlib/erand48.c
@@ -11,6 +11,10 @@
11 * to anyone/anything when using this software. 11 * to anyone/anything when using this software.
12 */ 12 */
13 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
14#include "rand48.h" 18#include "rand48.h"
15 19
16double 20double
diff --git a/src/lib/libc/stdlib/exit.3 b/src/lib/libc/stdlib/exit.3
index adb81ffcb4..8c4b2eed2c 100644
--- a/src/lib/libc/stdlib/exit.3
+++ b/src/lib/libc/stdlib/exit.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,8 +29,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)exit.3 6.6 (Berkeley) 6/29/91 32.\" $OpenBSD: exit.3,v 1.9 2003/06/02 20:18:37 millert Exp $
37.\" $Id: exit.3,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd June 29, 1991
40.Dt EXIT 3 35.Dt EXIT 3
@@ -47,8 +42,9 @@
47.Ft void 42.Ft void
48.Fn exit "int status" 43.Fn exit "int status"
49.Sh DESCRIPTION 44.Sh DESCRIPTION
50.Fn Exit 45The
51terminates a process. 46.Fn exit
47function terminates a process.
52.Pp 48.Pp
53Before termination it performs the following functions in the 49Before termination it performs the following functions in the
54order listed: 50order listed:
@@ -66,19 +62,28 @@ Unlink all files created with the
66.Xr tmpfile 3 62.Xr tmpfile 3
67function. 63function.
68.El 64.El
65.Pp
66Following this,
67.Fn exit
68calls
69.Xr _exit 2 .
70Note that typically
71.Xr _exit 2
72only passes the lower 8 bits of
73.Fa status
74on to the parent, thus negative values have less meaning.
69.Sh RETURN VALUES 75.Sh RETURN VALUES
70The 76The
71.Fn exit 77.Fn exit
72function 78function never returns.
73never returns.
74.Sh SEE ALSO 79.Sh SEE ALSO
75.Xr _exit 2 , 80.Xr _exit 2 ,
76.Xr atexit 3 , 81.Xr atexit 3 ,
77.Xr intro 3 , 82.Xr intro 3 ,
83.Xr sysexits 3 ,
78.Xr tmpfile 3 84.Xr tmpfile 3
79.Sh STANDARDS 85.Sh STANDARDS
80The 86The
81.Fn exit 87.Fn exit
82function 88function conforms to
83conforms to
84.St -ansiC . 89.St -ansiC .
diff --git a/src/lib/libc/stdlib/exit.c b/src/lib/libc/stdlib/exit.c
index b1412f42bb..a75b32abeb 100644
--- a/src/lib/libc/stdlib/exit.c
+++ b/src/lib/libc/stdlib/exit.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,15 +28,24 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)exit.c 5.4 (Berkeley) 2/23/91";*/ 31static char *rcsid = "$OpenBSD: exit.c,v 1.9 2003/06/02 20:18:37 millert Exp $";
36static char *rcsid = "$Id: exit.c,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
34#include <sys/types.h>
35#include <sys/mman.h>
39#include <stdlib.h> 36#include <stdlib.h>
40#include <unistd.h> 37#include <unistd.h>
41#include "atexit.h" 38#include "atexit.h"
39#include "thread_private.h"
42 40
43void (*__cleanup)(); 41/*
42 * This variable is zero until a process has created a thread.
43 * It is used to avoid calling locking functions in libc when they
44 * are not required. By default, libc is intended to be(come)
45 * thread-safe, but without a (significant) penalty to non-threaded
46 * processes.
47 */
48int __isthreaded = 0;
44 49
45/* 50/*
46 * Exit, flushing stdio buffers if necessary. 51 * Exit, flushing stdio buffers if necessary.
@@ -49,13 +54,20 @@ void
49exit(status) 54exit(status)
50 int status; 55 int status;
51{ 56{
52 register struct atexit *p; 57 register struct atexit *p, *q;
53 register int n; 58 register int n, pgsize = getpagesize();
54 59
55 for (p = __atexit; p; p = p->next) 60 if (!__atexit_invalid) {
56 for (n = p->ind; --n >= 0;) 61 p = __atexit;
57 (*p->fns[n])(); 62 while (p != NULL) {
58 if (__cleanup) 63 for (n = p->ind; --n >= 0;)
59 (*__cleanup)(); 64 if (p->fns[n] != NULL)
65 (*p->fns[n])();
66 q = p;
67 p = p->next;
68 munmap(q, pgsize);
69 }
70 }
71 /* cleanup, if registered, was called through fns[0] in the last page */
60 _exit(status); 72 _exit(status);
61} 73}
diff --git a/src/lib/libc/stdlib/free.3 b/src/lib/libc/stdlib/free.3
deleted file mode 100644
index 3d0131d7de..0000000000
--- a/src/lib/libc/stdlib/free.3
+++ /dev/null
@@ -1,82 +0,0 @@
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.\" from: @(#)free.3 5.2 (Berkeley) 6/29/91
37.\" $Id: free.3,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $
38.\"
39.Dd June 29, 1991
40.Dt FREE 3
41.Os
42.Sh NAME
43.Nm free
44.Nd free up memory allocated with malloc, calloc or realloc
45.Sh SYNOPSIS
46.Fd #include <stdlib.h>
47.Ft void
48.Fn free "void *ptr"
49.Sh DESCRIPTION
50The
51.Fn free
52function causes the space pointed to by
53.Fa ptr
54to be deallocated, that is, made available
55for further allocation.
56If
57.Fa ptr
58is a null pointer, no action occurs.
59Otherwise, if the argument does not match a pointer earlier
60returned by the
61.Xr calloc ,
62.Xr malloc ,
63or
64.Xr realloc
65function, or if the space has been deallocated by a call to
66.Fn free
67or
68.Xr realloc ,
69general havoc may occur.
70.Sh RETURN VALUES
71The
72.Fn free
73function returns no value.
74.Sh SEE ALSO
75.Xr calloc 3 ,
76.Xr malloc 3 ,
77.Xr realloc 3
78.Sh STANDARDS
79The
80.Fn free
81function conforms to
82.St -ansiC .
diff --git a/src/lib/libc/stdlib/gcvt.c b/src/lib/libc/stdlib/gcvt.c
new file mode 100644
index 0000000000..9fd664b346
--- /dev/null
+++ b/src/lib/libc/stdlib/gcvt.c
@@ -0,0 +1,99 @@
1/* $OpenBSD: gcvt.c,v 1.5 2003/06/17 21:56:24 millert Exp $ */
2
3/*
4 * Copyright (c) 2002, 2003 Todd C. Miller <Todd.Miller@courtesan.com>
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 THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 *
18 * Sponsored in part by the Defense Advanced Research Projects
19 * Agency (DARPA) and Air Force Research Laboratory, Air Force
20 * Materiel Command, USAF, under agreement number F39502-99-1-0512.
21 */
22
23#if defined(LIBC_SCCS) && !defined(lint)
24static char rcsid[] = "$OpenBSD: gcvt.c,v 1.5 2003/06/17 21:56:24 millert Exp $";
25#endif /* LIBC_SCCS and not lint */
26
27#include <stdio.h>
28#include <stdlib.h>
29#include <string.h>
30
31extern char *__dtoa(double, int, int, int *, int *, char **);
32
33char *
34gcvt(double value, int ndigit, char *buf)
35{
36 char *digits, *dst, *src;
37 int i, decpt, sign;
38
39 if (ndigit == 0) {
40 buf[0] = '\0';
41 return (buf);
42 }
43
44 digits = __dtoa(value, 2, ndigit, &decpt, &sign, NULL);
45 if (decpt == 9999) {
46 /* Infinity or NaN, assume buffer is at least ndigit long. */
47 strlcpy(buf, digits, ndigit + 1);
48 return (buf);
49 }
50
51 dst = buf;
52 if (sign)
53 *dst++ = '-';
54
55 if (decpt < 0 || decpt > ndigit) {
56 /* exponential format */
57 if (--decpt < 0) {
58 sign = 1;
59 decpt = -decpt;
60 } else
61 sign = 0;
62 for (src = digits; *src != '\0'; )
63 *dst++ = *src++;
64 *dst++ = 'e';
65 if (sign)
66 *dst++ = '-';
67 else
68 *dst++ = '+';
69 if (decpt < 10) {
70 *dst++ = '0';
71 *dst++ = '0' + decpt;
72 *dst = '\0';
73 } else {
74 /* XXX - optimize */
75 for (sign = decpt, i = 0; (sign /= 10) != 0; i++)
76 sign /= 10;
77 while (decpt != 0) {
78 dst[i--] = '0' + decpt % 10;
79 decpt /= 10;
80 }
81 }
82 } else {
83 /* standard format */
84 for (i = 0, src = digits; i < decpt; i++) {
85 if (*src != '\0')
86 *dst++ = *src++;
87 else
88 *dst++ = '0';
89 }
90 if (*src != '\0') {
91 *dst++ = '.'; /* XXX - locale-specific (LC_NUMERIC) */
92 for (i = decpt; digits[i] != '\0'; i++) {
93 *dst++ = digits[i];
94 }
95 }
96 *dst = '\0';
97 }
98 return (buf);
99}
diff --git a/src/lib/libc/stdlib/getenv.3 b/src/lib/libc/stdlib/getenv.3
index 411eb35da4..054004e1d8 100644
--- a/src/lib/libc/stdlib/getenv.3
+++ b/src/lib/libc/stdlib/getenv.3
@@ -1,5 +1,5 @@
1.\" Copyright (c) 1988, 1991 The Regents of the University of California. 1.\" Copyright (c) 1988, 1991, 1993
2.\" All rights reserved. 2.\" The Regents of the University of California. All rights reserved.
3.\" 3.\"
4.\" This code is derived from software contributed to Berkeley by 4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information 5.\" the American National Standards Committee X3, on Information
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,10 +29,9 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)getenv.3 6.11 (Berkeley) 6/29/91 32.\" $OpenBSD: getenv.3,v 1.9 2004/01/23 23:08:46 jmc Exp $
37.\" $Id: getenv.3,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd December 11, 1993
40.Dt GETENV 3 35.Dt GETENV 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
@@ -56,59 +51,51 @@
56.Ft void 51.Ft void
57.Fn unsetenv "const char *name" 52.Fn unsetenv "const char *name"
58.Sh DESCRIPTION 53.Sh DESCRIPTION
59These functions set, unset and fetch environment variables from the 54These functions set, unset, and fetch environment variables from the host
60host
61.Em environment list . 55.Em environment list .
62For compatibility with differing environment conventions, 56For compatibility with differing environment conventions, the given arguments
63the given arguments 57.Fa name
64.Ar name
65and 58and
66.Ar value 59.Fa value
67may be appended and prepended, 60may be appended and prepended, respectively, with an equal sign
68respectively,
69with an equal sign
70.Dq Li \&= . 61.Dq Li \&= .
71.Pp 62.Pp
72The 63The
73.Fn getenv 64.Fn getenv
74function obtains the current value of the environment variable, 65function obtains the current value of the environment variable,
75.Ar name . 66.Fa name .
76If the variable 67If the variable
77.Ar name 68.Fa name
78is not in the current environment , 69is not in the current environment, a null pointer is returned.
79a null pointer is returned.
80.Pp 70.Pp
81The 71The
82.Fn setenv 72.Fn setenv
83function inserts or resets the environment variable 73function inserts or resets the environment variable
84.Ar name 74.Fa name
85in the current environment list. 75in the current environment list.
86If the variable 76If the variable
87.Ar name 77.Fa name
88does not exist in the list, 78does not exist in the list, it is inserted with the given
89it is inserted with the given 79.Fa value .
90.Ar value.
91If the variable does exist, the argument 80If the variable does exist, the argument
92.Ar overwrite 81.Fa overwrite
93is tested; if 82is tested; if
94.Ar overwrite is 83.Fa overwrite
95zero, the 84is zero, the variable is not reset, otherwise it is reset to the given
96variable is not reset, otherwise it is reset 85.Fa value .
97to the given
98.Ar value .
99.Pp 86.Pp
100The 87The
101.Fn putenv 88.Fn putenv
102function takes an argument of the form ``name=value'' and is 89function takes an argument of the form
103equivalent to: 90.Ar name Ns = Ns Ar value
91and is equivalent to:
104.Bd -literal -offset indent 92.Bd -literal -offset indent
105setenv(name, value, 1); 93setenv(name, value, 1);
106.Ed 94.Ed
107.Pp 95.Pp
108The 96The
109.Fn unsetenv 97.Fn unsetenv
110function 98function deletes all instances of the variable name pointed to by
111deletes all instances of the variable name pointed to by
112.Fa name 99.Fa name
113from the list. 100from the list.
114.Sh RETURN VALUES 101.Sh RETURN VALUES
@@ -118,10 +105,13 @@ and
118.Fn putenv 105.Fn putenv
119return zero if successful; otherwise the global variable 106return zero if successful; otherwise the global variable
120.Va errno 107.Va errno
121is set to indicate the error and a 108is set to indicate the error and \-1 is returned.
122\-1 is returned. 109.Pp
110If
111.Fn getenv
112is successful, the string returned should be considered read-only.
123.Sh ERRORS 113.Sh ERRORS
124.Bl -tag -width Er 114.Bl -tag -width [ENOMEM]
125.It Bq Er ENOMEM 115.It Bq Er ENOMEM
126The function 116The function
127.Fn setenv 117.Fn setenv
diff --git a/src/lib/libc/stdlib/getenv.c b/src/lib/libc/stdlib/getenv.c
index 09d47f2149..c597e468a9 100644
--- a/src/lib/libc/stdlib/getenv.c
+++ b/src/lib/libc/stdlib/getenv.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright (c) 1987 Regents of the University of California. 2 * Copyright (c) 1987, 1993
3 * All rights reserved. 3 * The Regents of the University of California. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,26 +28,13 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)getenv.c 5.8 (Berkeley) 2/23/91";*/ 31static char *rcsid = "$OpenBSD: getenv.c,v 1.6 2003/06/02 20:18:37 millert Exp $";
36static char *rcsid = "$Id: getenv.c,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
39#include <stdlib.h> 34#include <stdlib.h>
40#include <string.h> 35#include <string.h>
41 36
42/* 37char *__findenv(const char *name, int *offset);
43 * getenv --
44 * Returns ptr to value associated with name, if any, else NULL.
45 */
46char *
47getenv(name)
48 const char *name;
49{
50 int offset;
51 char *__findenv();
52
53 return(__findenv(name, &offset));
54}
55 38
56/* 39/*
57 * __findenv -- 40 * __findenv --
@@ -63,20 +46,39 @@ getenv(name)
63 * This routine *should* be a static; don't use it. 46 * This routine *should* be a static; don't use it.
64 */ 47 */
65char * 48char *
66__findenv(name, offset) 49__findenv(const char *name, int *offset)
67 register char *name;
68 int *offset;
69{ 50{
70 extern char **environ; 51 extern char **environ;
71 register int len; 52 register int len, i;
72 register char **P, *C; 53 register const char *np;
54 register char **p, *cp;
55
56 if (name == NULL || environ == NULL)
57 return (NULL);
58 for (np = name; *np && *np != '='; ++np)
59 ;
60 len = np - name;
61 for (p = environ; (cp = *p) != NULL; ++p) {
62 for (np = name, i = len; i && *cp; i--)
63 if (*cp++ != *np++)
64 break;
65 if (i == 0 && *cp++ == '=') {
66 *offset = p - environ;
67 return (cp);
68 }
69 }
70 return (NULL);
71}
72
73/*
74 * getenv --
75 * Returns ptr to value associated with name, if any, else NULL.
76 */
77char *
78getenv(name)
79 const char *name;
80{
81 int offset;
73 82
74 for (C = name, len = 0; *C && *C != '='; ++C, ++len); 83 return (__findenv(name, &offset));
75 for (P = environ; *P; ++P)
76 if (!strncmp(*P, name, len))
77 if (*(C = *P + len) == '=') {
78 *offset = P - environ;
79 return(++C);
80 }
81 return(NULL);
82} 84}
diff --git a/src/lib/libc/stdlib/getopt.3 b/src/lib/libc/stdlib/getopt.3
index f843881afd..d210852c6b 100644
--- a/src/lib/libc/stdlib/getopt.3
+++ b/src/lib/libc/stdlib/getopt.3
@@ -9,11 +9,7 @@
9.\" 2. Redistributions in binary form must reproduce the above copyright 9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\" notice, this list of conditions and the following disclaimer in the 10.\" notice, this list of conditions and the following disclaimer in the
11.\" documentation and/or other materials provided with the distribution. 11.\" documentation and/or other materials provided with the distribution.
12.\" 3. All advertising materials mentioning features or use of this software 12.\" 3. Neither the name of the University nor the names of its contributors
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 13.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission. 14.\" without specific prior written permission.
19.\" 15.\"
@@ -29,11 +25,11 @@
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE. 26.\" SUCH DAMAGE.
31.\" 27.\"
32.\" @(#)getopt.3 8.4 (Berkeley) 4/19/94 28.\" $OpenBSD: getopt.3,v 1.28 2003/09/22 23:47:26 millert Exp $
33.\" 29.\"
34.Dd April 19, 1994 30.Dd December 17, 2002
35.Dt GETOPT 3 31.Dt GETOPT 3
36.Os BSD 4.3 32.Os
37.Sh NAME 33.Sh NAME
38.Nm getopt 34.Nm getopt
39.Nd get option character from command line argument list 35.Nd get option character from command line argument list
@@ -61,20 +57,24 @@ if it has been specified in the string of accepted option characters,
61.Pp 57.Pp
62The option string 58The option string
63.Fa optstring 59.Fa optstring
64may contain the following elements: individual characters, and 60may contain the following elements: individual characters,
65characters followed by a colon to indicate an option argument 61characters followed by a colon, and characters followed by two colons.
66is to follow. 62A character followed by a single colon indicates that an argument
63is to follow the option on the command line.
64Two colons indicates that the argument is optional--this is an
65extension not covered by
66.Px .
67For example, an option string 67For example, an option string
68.Li "\&""x"" 68.Qq x
69recognizes an option 69recognizes an option
70.Dq Fl x , 70.Fl x ,
71and an option string 71and an option string
72.Li "\&""x:"" 72.Qq Li x:
73recognizes an option and argument 73recognizes an option and argument
74.Dq Fl x Ar argument . 74.Fl x Ar argument .
75It does not matter to 75It does not matter to
76.Fn getopt 76.Fn getopt
77if a following argument has leading white space. 77if a following argument has leading whitespace.
78.Pp 78.Pp
79On return from 79On return from
80.Fn getopt , 80.Fn getopt ,
@@ -87,14 +87,8 @@ contains the index to the next
87argument for a subsequent call 87argument for a subsequent call
88to 88to
89.Fn getopt . 89.Fn getopt .
90The variable
91.Va optopt
92saves the last
93.Em known
94option character returned by
95.Fn getopt .
96.Pp 90.Pp
97The variable 91The variables
98.Va opterr 92.Va opterr
99and 93and
100.Va optind 94.Va optind
@@ -119,63 +113,62 @@ must be reinitialized.
119.Pp 113.Pp
120The 114The
121.Fn getopt 115.Fn getopt
122function 116function returns \-1 when the argument list is exhausted.
123returns \-1
124when the argument list is exhausted, or a non-recognized
125option is encountered.
126The interpretation of options in the argument list may be cancelled 117The interpretation of options in the argument list may be cancelled
127by the option 118by the option
128.Ql -- 119.Ql --
129(double dash) which causes 120(double dash) which causes
130.Fn getopt 121.Fn getopt
131to signal the end of argument processing and returns \-1. 122to signal the end of argument processing and return \-1.
132When all options have been processed (i.e., up to the first non-option 123When all options have been processed (i.e., up to the first non-option
133argument), 124argument),
134.Fn getopt 125.Fn getopt
135returns \-1. 126returns \-1.
136.Sh DIAGNOSTICS 127.Sh RETURN VALUES
137If the 128The
138.Fn getopt 129.Fn getopt
139function encounters a character not found in the string 130function returns the next known option character in
140.Va optarg 131.Fa optstring .
141or detects
142a missing option argument it writes an error message and returns
143.Ql ?
144to the
145.Em stderr .
146Setting
147.Va opterr
148to a zero will disable these error messages.
149If 132If
150.Va optstring 133.Fn getopt
151has a leading 134encounters a character not found in
152.Ql \&: 135.Fa optstring
153then a missing option argument causes a 136or if it detects a missing option argument,
154.Ql \&: 137it returns
155to be returned in addition to suppressing any error messages. 138.Sq \&?
156.Pp 139(question mark).
157Option arguments are allowed to begin with 140If
158.Dq Li \- ; 141.Fa optstring
159this is reasonable but 142has a leading
160reduces the amount of error checking possible. 143.Sq \&:
161.Sh EXTENSIONS 144then a missing option argument causes
145.Sq \&:
146to be returned instead of
147.Sq \&? .
148In either case, the variable
149.Va optopt
150is set to the character that caused the error.
162The 151The
163.Va optreset
164variable was added to make it possible to call the
165.Fn getopt 152.Fn getopt
166function multiple times. 153function returns \-1 when the argument list is exhausted.
167This is an extension to the 154.Sh ENVIRONMENT
168.St -p1003.2 155.Bl -tag -width POSIXLY_CORRECTXX
169specification. 156.It Ev POSIXLY_CORRECT
170.Sh EXAMPLE 157If set, a leading
158.Sq -
159in
160.Ar optstring
161is ignored.
162.El
163.Sh EXAMPLES
171.Bd -literal -compact 164.Bd -literal -compact
172extern char *optarg; 165extern char *optarg;
173extern int optind; 166extern int optind;
174int bflag, ch, fd; 167int bflag, ch, fd;
175 168
176bflag = 0; 169bflag = 0;
177while ((ch = getopt(argc, argv, "bf:")) != -1) 170while ((ch = getopt(argc, argv, "bf:")) != -1) {
178 switch(ch) { 171 switch (ch) {
179 case 'b': 172 case 'b':
180 bflag = 1; 173 bflag = 1;
181 break; 174 break;
@@ -189,31 +182,76 @@ while ((ch = getopt(argc, argv, "bf:")) != -1)
189 case '?': 182 case '?':
190 default: 183 default:
191 usage(); 184 usage();
185 }
192} 186}
193argc -= optind; 187argc -= optind;
194argv += optind; 188argv += optind;
195.Ed 189.Ed
196.Sh HISTORY 190.Sh DIAGNOSTICS
197The 191If the
198.Fn getopt 192.Fn getopt
199function appeared 193function encounters a character not found in the string
200.Bx 4.3 . 194.Fa optstring
201.Sh BUGS 195or detects
196a missing option argument it writes an error message to
197.Em stderr
198and returns
199.Ql \&? .
200Setting
201.Va opterr
202to a zero will disable these error messages.
203If
204.Fa optstring
205has a leading
206.Ql \&:
207then a missing option argument causes a
208.Ql \&:
209to be returned in addition to suppressing any error messages.
210.Pp
211Option arguments are allowed to begin with
212.Ql - ;
213this is reasonable but reduces the amount of error checking possible.
214.Sh SEE ALSO
215.Xr getopt 1 ,
216.Xr getopt_long 3 ,
217.Xr getsubopt 3
218.Sh STANDARDS
202The 219The
203.Fn getopt 220.Fn getopt
204function was once specified to return 221function implements a superset of the functionality specified by
205.Dv EOF 222.St -p1003.1 .
206instead of \-1.
207This was changed by
208.St -p1003.2-92
209to decouple
210.Fn getopt
211from
212.Pa <stdio.h> .
213.Pp 223.Pp
224The following extensions are supported:
225.Bl -tag -width "xxx"
226.It Li o
227The
228.Va optreset
229variable was added to make it possible to call the
230.Fn getopt
231function multiple times.
232.It Li o
233If the first character of
234.Fa optstring
235is a plus sign
236.Pq Ql + ,
237it will be ignored.
238This is for compatibility with
239.Tn GNU
240.Fn getopt .
241.It Li o
242If the first character of
243.Fa optstring
244is a dash
245.Pq Ql - ,
246non-options will be returned as arguments to the option character
247.Ql \e1 .
248This is for compatibility with
249.Tn GNU
250.Fn getopt .
251.It Li o
214A single dash 252A single dash
215.Dq Li - 253.Pq Ql -
216may be specified as an character in 254may be specified as a character in
217.Fa optstring , 255.Fa optstring ,
218however it should 256however it should
219.Em never 257.Em never
@@ -221,39 +259,81 @@ have an argument associated with it.
221This allows 259This allows
222.Fn getopt 260.Fn getopt
223to be used with programs that expect 261to be used with programs that expect
224.Dq Li - 262.Ql -
225as an option flag. 263as an option flag.
226This practice is wrong, and should not be used in any current development. 264This practice is wrong, and should not be used in any current development.
227It is provided for backward compatibility 265It is provided for backward compatibility
228.Em only . 266.Em only .
267Care should be taken not to use
268.Ql -
269as the first character in
270.Fa optstring
271to avoid a semantic conflict with
272.Tn GNU
273.Fn getopt
274semantics (see above).
229By default, a single dash causes 275By default, a single dash causes
230.Fn getopt 276.Fn getopt
231to return \-1. 277to return \-1.
232This is, we believe, compatible with System V. 278.El
279.Pp
280Unlike
281.Tn GNU
282.Fn getopt ,
283.Ox
284does not permute the argument vector to allow non-options to be
285interspersed with options on the command line.
286Programs requiring this behavior should use
287.Xr getopt_long 3
288instead.
289Because of this (and unlike
290.Tn GNU ) ,
291the
292.Ox
293.Fn getopt
294supports optional arguments separated by whitespace.
295.Sh HISTORY
296The
297.Fn getopt
298function appeared in
299.Bx 4.3 .
300.Sh BUGS
301The
302.Fn getopt
303function was once specified to return
304.Dv EOF
305instead of \-1.
306This was changed by
307.St -p1003.2-92
308to decouple
309.Fn getopt
310from
311.Aq Pa stdio.h .
233.Pp 312.Pp
234It is also possible to handle digits as option letters. 313It is possible to handle digits as option letters.
235This allows 314This allows
236.Fn getopt 315.Fn getopt
237to be used with programs that expect a number 316to be used with programs that expect a number
238.Pq Dq Li \&-\&3 317.Pq Dq Li \-3
239as an option. 318as an option.
240This practice is wrong, and should not be used in any current development. 319This practice is wrong, and should not be used in any current development.
241It is provided for backward compatibility 320It is provided for backward compatibility
242.Em only . 321.Em only .
243The following code fragment works in most cases. 322The following code fragment works in most cases.
244.Bd -literal -offset indent 323.Bd -literal -offset indent
245int length; 324int ch;
325long length;
246char *p; 326char *p;
247 327
248while ((c = getopt(argc, argv, "0123456789")) != -1) 328while ((ch = getopt(argc, argv, "0123456789")) != -1) {
249 switch (c) { 329 switch (ch) {
250 case '0': case '1': case '2': case '3': case '4': 330 case '0': case '1': case '2': case '3': case '4':
251 case '5': case '6': case '7': case '8': case '9': 331 case '5': case '6': case '7': case '8': case '9':
252 p = argv[optind - 1]; 332 p = argv[optind - 1];
253 if (p[0] == '-' && p[1] == ch && !p[2]) 333 if (p[0] == '-' && p[1] == ch && !p[2])
254 length = atoi(++p); 334 length = ch - '0';
255 else 335 else
256 length = atoi(argv[optind] + 1); 336 length = strtol(argv[optind] + 1, NULL, 10);
257 break; 337 break;
258 } 338 }
259} 339}
diff --git a/src/lib/libc/stdlib/getopt.c b/src/lib/libc/stdlib/getopt.c
deleted file mode 100644
index 63c5e6a479..0000000000
--- a/src/lib/libc/stdlib/getopt.c
+++ /dev/null
@@ -1,118 +0,0 @@
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)
35/* static char sccsid[] = "from: @(#)getopt.c 8.2 (Berkeley) 4/2/94"; */
36static char *rcsid = "$Id: getopt.c,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */
38
39#include <stdio.h>
40#include <stdlib.h>
41#include <string.h>
42
43int opterr = 1, /* if error message should be printed */
44 optind = 1, /* index into parent argv vector */
45 optopt, /* character checked for validity */
46 optreset; /* reset getopt */
47char *optarg; /* argument associated with option */
48
49#define BADCH (int)'?'
50#define BADARG (int)':'
51#define EMSG ""
52
53/*
54 * getopt --
55 * Parse argc/argv argument vector.
56 */
57int
58getopt(nargc, nargv, ostr)
59 int nargc;
60 char * const *nargv;
61 const char *ostr;
62{
63 extern char *__progname;
64 static char *place = EMSG; /* option letter processing */
65 char *oli; /* option letter list index */
66
67 if (optreset || !*place) { /* update scanning pointer */
68 optreset = 0;
69 if (optind >= nargc || *(place = nargv[optind]) != '-') {
70 place = EMSG;
71 return (-1);
72 }
73 if (place[1] && *++place == '-') { /* found "--" */
74 ++optind;
75 place = EMSG;
76 return (-1);
77 }
78 } /* option letter okay? */
79 if ((optopt = (int)*place++) == (int)':' ||
80 !(oli = strchr(ostr, optopt))) {
81 /*
82 * if the user didn't specify '-' as an option,
83 * assume it means -1.
84 */
85 if (optopt == (int)'-')
86 return (-1);
87 if (!*place)
88 ++optind;
89 if (opterr && *ostr != ':')
90 (void)fprintf(stderr,
91 "%s: illegal option -- %c\n", __progname, optopt);
92 return (BADCH);
93 }
94 if (*++oli != ':') { /* don't need argument */
95 optarg = NULL;
96 if (!*place)
97 ++optind;
98 }
99 else { /* need an argument */
100 if (*place) /* no white space */
101 optarg = place;
102 else if (nargc <= ++optind) { /* no arg */
103 place = EMSG;
104 if (*ostr == ':')
105 return (BADARG);
106 if (opterr)
107 (void)fprintf(stderr,
108 "%s: option requires an argument -- %c\n",
109 __progname, optopt);
110 return (BADCH);
111 }
112 else /* white space */
113 optarg = nargv[optind];
114 place = EMSG;
115 ++optind;
116 }
117 return (optopt); /* dump back option letter */
118}
diff --git a/src/lib/libc/stdlib/getopt_long.3 b/src/lib/libc/stdlib/getopt_long.3
new file mode 100644
index 0000000000..978583ef96
--- /dev/null
+++ b/src/lib/libc/stdlib/getopt_long.3
@@ -0,0 +1,377 @@
1.\" $OpenBSD: getopt_long.3,v 1.10 2004/01/06 23:44:28 fgsch Exp $
2.\" $NetBSD: getopt_long.3,v 1.11 2002/10/02 10:54:19 wiz Exp $
3.\"
4.\" Copyright (c) 1988, 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. Neither the name of the University 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 REGENTS 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 REGENTS 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.\" @(#)getopt.3 8.5 (Berkeley) 4/27/95
32.\"
33.Dd April 1, 2000
34.Dt GETOPT_LONG 3
35.Os
36.Sh NAME
37.Nm getopt_long ,
38.Nm getopt_long_only
39.Nd get long options from command line argument list
40.Sh SYNOPSIS
41.Fd #include <getopt.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_long "int argc" "char * const *argv" "const char *optstring" "const struct option *longopts" "int *longindex"
49.Ft int
50.Fn getopt_long_only "int argc" "char * const *argv" "const char *optstring" "const struct option *longopts" "int *longindex"
51.Sh DESCRIPTION
52The
53.Fn getopt_long
54function is similar to
55.Xr getopt 3
56but it accepts options in two forms: words and characters.
57The
58.Fn getopt_long
59function provides a superset of the functionality of
60.Xr getopt 3 .
61.Fn getopt_long
62can be used in two ways.
63In the first way, every long option understood by the program has a
64corresponding short option, and the option structure is only used to
65translate from long options to short options.
66When used in this fashion,
67.Fn getopt_long
68behaves identically to
69.Xr getopt 3 .
70This is a good way to add long option processing to an existing program
71with the minimum of rewriting.
72.Pp
73In the second mechanism, a long option sets a flag in the
74.Fa option
75structure passed, or will store a pointer to the command line argument
76in the
77.Fa option
78structure passed to it for options that take arguments.
79Additionally, the long option's argument may be specified as a single
80argument with an equal sign, e.g.
81.Bd -literal
82myprogram --myoption=somevalue
83.Ed
84.Pp
85When a long option is processed the call to
86.Fn getopt_long
87will return 0.
88For this reason, long option processing without
89shortcuts is not backwards compatible with
90.Xr getopt 3 .
91.Pp
92It is possible to combine these methods, providing for long options
93processing with short option equivalents for some options.
94Less frequently used options would be processed as long options only.
95.Pp
96The
97.Fn getopt_long
98call requires a structure to be initialized describing the long
99options.
100The structure is:
101.Bd -literal
102struct option {
103 char *name;
104 int has_arg;
105 int *flag;
106 int val;
107};
108.Ed
109.Pp
110The
111.Fa name
112field should contain the option name without the leading double dash.
113.Pp
114The
115.Fa has_arg
116field should be one of:
117.Bl -tag -width "optional_argument"
118.It Li no_argument
119no argument to the option is expect.
120.It Li required_argument
121an argument to the option is required.
122.It Li optional_argument
123an argument to the option may be presented.
124.El
125.Pp
126If
127.Fa flag
128is not
129.Dv NULL ,
130then the integer pointed to by it will be set to the value in the
131.Fa val
132field.
133If the
134.Fa flag
135field is
136.Dv NULL ,
137then the
138.Fa val
139field will be returned.
140Setting
141.Fa flag
142to
143.Dv NULL
144and setting
145.Fa val
146to the corresponding short option will make this function act just
147like
148.Xr getopt 3 .
149.Pp
150If the
151.Fa longindex
152field is not
153.Dv NULL ,
154then the integer pointed to by it will be set to the index of the long
155option relative to
156.Fa longopts .
157.Pp
158The last element of the
159.Fa longopts
160array has to be filled with zeroes.
161.Pp
162The
163.Fn getopt_long_only
164function behaves identically to
165.Fn getopt_long
166with the exception that long options may start with
167.Sq -
168in addition to
169.Sq -- .
170If an option starting with
171.Sq -
172does not match a long option but does match a single-character option,
173the single-character option is returned.
174.Sh RETURN VALUES
175If the
176.Fa flag
177field in
178.Li struct option
179is
180.Dv NULL ,
181.Fn getopt_long
182and
183.Fn getopt_long_only
184return the value specified in the
185.Fa val
186field, which is usually just the corresponding short option.
187If
188.Fa flag
189is not
190.Dv NULL ,
191these functions return 0 and store
192.Fa val
193in the location pointed to by
194.Fa flag .
195These functions return
196.Sq \:
197if there was a missing option argument,
198.Sq \&?
199if the user specified an unknown or ambiguous option, and
200\-1 when the argument list has been exhausted.
201.Sh EXAMPLES
202.Bd -literal -compact
203int bflag, ch, fd;
204int daggerset;
205
206/* options descriptor */
207static struct option longopts[] = {
208 { "buffy", no_argument, NULL, 'b' },
209 { "fluoride", required_argument, NULL, 'f' },
210 { "daggerset", no_argument, &daggerset, 1 },
211 { NULL, 0, NULL, 0 }
212};
213
214bflag = 0;
215while ((ch = getopt_long(argc, argv, "bf:", longopts, NULL)) != -1)
216 switch (ch) {
217 case 'b':
218 bflag = 1;
219 break;
220 case 'f':
221 if ((fd = open(optarg, O_RDONLY, 0)) == -1)
222 err(1, "unable to open %s", optarg);
223 break;
224 case 0:
225 if (daggerset) {
226 fprintf(stderr,"Buffy will use her dagger to "
227 "apply fluoride to dracula's teeth\en");
228 }
229 break;
230 default:
231 usage();
232}
233argc -= optind;
234argv += optind;
235.Ed
236.Sh IMPLEMENTATION DIFFERENCES
237This section describes differences to the GNU implementation
238found in glibc-2.1.3:
239.Bl -tag -width "xxx"
240.It Li o
241handling of - as first char of option string in presence of
242environment variable POSIXLY_CORRECT:
243.Bl -tag -width "OpenBSD"
244.It Li GNU
245ignores POSIXLY_CORRECT and returns non-options as
246arguments to option '\e1'.
247.It Li OpenBSD
248honors POSIXLY_CORRECT and stops at the first non-option.
249.El
250.It Li o
251handling of - within the option string (not the first character):
252.Bl -tag -width "OpenBSD"
253.It Li GNU
254treats a
255.Ql -
256on the command line as a non-argument.
257.It Li OpenBSD
258a
259.Ql -
260within the option string matches a
261.Ql -
262(single dash) on the command line.
263This functionality is provided for backward compatibility with
264programs, such as
265.Xr su 1 ,
266that use
267.Ql -
268as an option flag.
269This practice is wrong, and should not be used in any current development.
270.El
271.It Li o
272handling of :: in options string in presence of POSIXLY_CORRECT:
273.Bl -tag -width "OpenBSD"
274.It Li Both
275GNU and OpenBSD ignore POSIXLY_CORRECT here and take :: to
276mean the preceding option takes an optional argument.
277.El
278.It Li o
279return value in case of missing argument if first character
280(after + or -) in option string is not ':':
281.Bl -tag -width "OpenBSD"
282.It Li GNU
283returns '?'
284.It OpenBSD
285returns ':' (since OpenBSD's getopt does).
286.El
287.It Li o
288handling of --a in getopt:
289.Bl -tag -width "OpenBSD"
290.It Li GNU
291parses this as option '-', option 'a'.
292.It Li OpenBSD
293parses this as '--', and returns \-1 (ignoring the a).
294(Because the original getopt does.)
295.El
296.It Li o
297setting of optopt for long options with flag !=
298.Dv NULL :
299.Bl -tag -width "OpenBSD"
300.It Li GNU
301sets optopt to val.
302.It Li OpenBSD
303sets optopt to 0 (since val would never be returned).
304.El
305.It Li o
306handling of -W with W; in option string in getopt (not getopt_long):
307.Bl -tag -width "OpenBSD"
308.It Li GNU
309causes a segfault.
310.It Li OpenBSD
311no special handling is done;
312.Dq W;
313is interpreted as two separate options, neither of which take an argument.
314.El
315.It Li o
316setting of optarg for long options without an argument that are
317invoked via -W (W; in option string):
318.Bl -tag -width "OpenBSD"
319.It Li GNU
320sets optarg to the option name (the argument of -W).
321.It Li OpenBSD
322sets optarg to
323.Dv NULL
324(the argument of the long option).
325.El
326.It Li o
327handling of -W with an argument that is not (a prefix to) a known
328long option (W; in option string):
329.Bl -tag -width "OpenBSD"
330.It Li GNU
331returns -W with optarg set to the unknown option.
332.It Li OpenBSD
333treats this as an error (unknown option) and returns '?' with
334optopt set to 0 and optarg set to
335.Dv NULL
336(as GNU's man page documents).
337.El
338.It Li o
339The error messages are different.
340.It Li o
341OpenBSD does not permute the argument vector at the same points in
342the calling sequence as GNU does.
343The aspects normally used by the caller
344(ordering after \-1 is returned, value of optind relative
345to current positions) are the same, though.
346(We do fewer variable swaps.)
347.El
348.Sh ENVIRONMENT
349.Bl -tag -width POSIXLY_CORRECT
350.It Ev POSIXLY_CORRECT
351If set, option processing stops when the first non-option is found and
352a leading
353.Sq -
354or
355.Sq +
356in the
357.Ar optstring
358is ignored.
359.El
360.Sh SEE ALSO
361.Xr getopt 3
362.Sh HISTORY
363The
364.Fn getopt_long
365and
366.Fn getopt_long_only
367functions first appeared in GNU libiberty.
368This implementation first appeared in
369.Ox 3.3 .
370.Sh BUGS
371The
372.Ar argv
373argument is not really
374.Dv const
375as its elements may be permuted (unless
376.Ev POSIXLY_CORRECT
377is set).
diff --git a/src/lib/libc/stdlib/getopt_long.c b/src/lib/libc/stdlib/getopt_long.c
new file mode 100644
index 0000000000..6079ce3503
--- /dev/null
+++ b/src/lib/libc/stdlib/getopt_long.c
@@ -0,0 +1,544 @@
1/* $OpenBSD: getopt_long.c,v 1.16 2004/02/04 18:17:25 millert Exp $ */
2/* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */
3
4/*
5 * Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com>
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 *
19 * Sponsored in part by the Defense Advanced Research Projects
20 * Agency (DARPA) and Air Force Research Laboratory, Air Force
21 * Materiel Command, USAF, under agreement number F39502-99-1-0512.
22 */
23/*-
24 * Copyright (c) 2000 The NetBSD Foundation, Inc.
25 * All rights reserved.
26 *
27 * This code is derived from software contributed to The NetBSD Foundation
28 * by Dieter Baron and Thomas Klausner.
29 *
30 * Redistribution and use in source and binary forms, with or without
31 * modification, are permitted provided that the following conditions
32 * are met:
33 * 1. Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * 2. Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in the
37 * documentation and/or other materials provided with the distribution.
38 * 3. All advertising materials mentioning features or use of this software
39 * must display the following acknowledgement:
40 * This product includes software developed by the NetBSD
41 * Foundation, Inc. and its contributors.
42 * 4. Neither the name of The NetBSD Foundation nor the names of its
43 * contributors may be used to endorse or promote products derived
44 * from this software without specific prior written permission.
45 *
46 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
47 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
48 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
49 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
50 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
51 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
52 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
53 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
54 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
55 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
56 * POSSIBILITY OF SUCH DAMAGE.
57 */
58
59#if defined(LIBC_SCCS) && !defined(lint)
60static char *rcsid = "$OpenBSD: getopt_long.c,v 1.16 2004/02/04 18:17:25 millert Exp $";
61#endif /* LIBC_SCCS and not lint */
62
63#include <err.h>
64#include <errno.h>
65#include <getopt.h>
66#include <stdlib.h>
67#include <string.h>
68
69#define REPLACE_GETOPT /* use this getopt as the system getopt(3) */
70
71#ifdef REPLACE_GETOPT
72int opterr = 1; /* if error message should be printed */
73int optind = 1; /* index into parent argv vector */
74int optopt = '?'; /* character checked for validity */
75int optreset; /* reset getopt */
76char *optarg; /* argument associated with option */
77#endif
78
79#define PRINT_ERROR ((opterr) && (*options != ':'))
80
81#define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */
82#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */
83#define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */
84
85/* return values */
86#define BADCH (int)'?'
87#define BADARG ((*options == ':') ? (int)':' : (int)'?')
88#define INORDER (int)1
89
90#define EMSG ""
91
92static int getopt_internal(int, char * const *, const char *,
93 const struct option *, int *, int);
94static int parse_long_options(char * const *, const char *,
95 const struct option *, int *, int);
96static int gcd(int, int);
97static void permute_args(int, int, int, char * const *);
98
99static char *place = EMSG; /* option letter processing */
100
101/* XXX: set optreset to 1 rather than these two */
102static int nonopt_start = -1; /* first non option argument (for permute) */
103static int nonopt_end = -1; /* first option after non options (for permute) */
104
105/* Error messages */
106static const char recargchar[] = "option requires an argument -- %c";
107static const char recargstring[] = "option requires an argument -- %s";
108static const char ambig[] = "ambiguous option -- %.*s";
109static const char noarg[] = "option doesn't take an argument -- %.*s";
110static const char illoptchar[] = "unknown option -- %c";
111static const char illoptstring[] = "unknown option -- %s";
112
113/*
114 * Compute the greatest common divisor of a and b.
115 */
116static int
117gcd(int a, int b)
118{
119 int c;
120
121 c = a % b;
122 while (c != 0) {
123 a = b;
124 b = c;
125 c = a % b;
126 }
127
128 return (b);
129}
130
131/*
132 * Exchange the block from nonopt_start to nonopt_end with the block
133 * from nonopt_end to opt_end (keeping the same order of arguments
134 * in each block).
135 */
136static void
137permute_args(int panonopt_start, int panonopt_end, int opt_end,
138 char * const *nargv)
139{
140 int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;
141 char *swap;
142
143 /*
144 * compute lengths of blocks and number and size of cycles
145 */
146 nnonopts = panonopt_end - panonopt_start;
147 nopts = opt_end - panonopt_end;
148 ncycle = gcd(nnonopts, nopts);
149 cyclelen = (opt_end - panonopt_start) / ncycle;
150
151 for (i = 0; i < ncycle; i++) {
152 cstart = panonopt_end+i;
153 pos = cstart;
154 for (j = 0; j < cyclelen; j++) {
155 if (pos >= panonopt_end)
156 pos -= nnonopts;
157 else
158 pos += nopts;
159 swap = nargv[pos];
160 /* LINTED const cast */
161 ((char **) nargv)[pos] = nargv[cstart];
162 /* LINTED const cast */
163 ((char **)nargv)[cstart] = swap;
164 }
165 }
166}
167
168/*
169 * parse_long_options --
170 * Parse long options in argc/argv argument vector.
171 * Returns -1 if short_too is set and the option does not match long_options.
172 */
173static int
174parse_long_options(char * const *nargv, const char *options,
175 const struct option *long_options, int *idx, int short_too)
176{
177 char *current_argv, *has_equal;
178 size_t current_argv_len;
179 int i, match;
180
181 current_argv = place;
182 match = -1;
183
184 optind++;
185
186 if ((has_equal = strchr(current_argv, '=')) != NULL) {
187 /* argument found (--option=arg) */
188 current_argv_len = has_equal - current_argv;
189 has_equal++;
190 } else
191 current_argv_len = strlen(current_argv);
192
193 for (i = 0; long_options[i].name; i++) {
194 /* find matching long option */
195 if (strncmp(current_argv, long_options[i].name,
196 current_argv_len))
197 continue;
198
199 if (strlen(long_options[i].name) == current_argv_len) {
200 /* exact match */
201 match = i;
202 break;
203 }
204 /*
205 * If this is a known short option, don't allow
206 * a partial match of a single character.
207 */
208 if (short_too && current_argv_len == 1)
209 continue;
210
211 if (match == -1) /* partial match */
212 match = i;
213 else {
214 /* ambiguous abbreviation */
215 if (PRINT_ERROR)
216 warnx(ambig, (int)current_argv_len,
217 current_argv);
218 optopt = 0;
219 return (BADCH);
220 }
221 }
222 if (match != -1) { /* option found */
223 if (long_options[match].has_arg == no_argument
224 && has_equal) {
225 if (PRINT_ERROR)
226 warnx(noarg, (int)current_argv_len,
227 current_argv);
228 /*
229 * XXX: GNU sets optopt to val regardless of flag
230 */
231 if (long_options[match].flag == NULL)
232 optopt = long_options[match].val;
233 else
234 optopt = 0;
235 return (BADARG);
236 }
237 if (long_options[match].has_arg == required_argument ||
238 long_options[match].has_arg == optional_argument) {
239 if (has_equal)
240 optarg = has_equal;
241 else if (long_options[match].has_arg ==
242 required_argument) {
243 /*
244 * optional argument doesn't use next nargv
245 */
246 optarg = nargv[optind++];
247 }
248 }
249 if ((long_options[match].has_arg == required_argument)
250 && (optarg == NULL)) {
251 /*
252 * Missing argument; leading ':' indicates no error
253 * should be generated.
254 */
255 if (PRINT_ERROR)
256 warnx(recargstring,
257 current_argv);
258 /*
259 * XXX: GNU sets optopt to val regardless of flag
260 */
261 if (long_options[match].flag == NULL)
262 optopt = long_options[match].val;
263 else
264 optopt = 0;
265 --optind;
266 return (BADARG);
267 }
268 } else { /* unknown option */
269 if (short_too) {
270 --optind;
271 return (-1);
272 }
273 if (PRINT_ERROR)
274 warnx(illoptstring, current_argv);
275 optopt = 0;
276 return (BADCH);
277 }
278 if (idx)
279 *idx = match;
280 if (long_options[match].flag) {
281 *long_options[match].flag = long_options[match].val;
282 return (0);
283 } else
284 return (long_options[match].val);
285}
286
287/*
288 * getopt_internal --
289 * Parse argc/argv argument vector. Called by user level routines.
290 */
291static int
292getopt_internal(int nargc, char * const *nargv, const char *options,
293 const struct option *long_options, int *idx, int flags)
294{
295 char *oli; /* option letter list index */
296 int optchar, short_too;
297 static int posixly_correct = -1;
298
299 if (options == NULL)
300 return (-1);
301
302 /*
303 * Disable GNU extensions if POSIXLY_CORRECT is set or options
304 * string begins with a '+'.
305 */
306 if (posixly_correct == -1)
307 posixly_correct = (getenv("POSIXLY_CORRECT") != NULL);
308 if (posixly_correct || *options == '+')
309 flags &= ~FLAG_PERMUTE;
310 else if (*options == '-')
311 flags |= FLAG_ALLARGS;
312 if (*options == '+' || *options == '-')
313 options++;
314
315 /*
316 * XXX Some GNU programs (like cvs) set optind to 0 instead of
317 * XXX using optreset. Work around this braindamage.
318 */
319 if (optind == 0)
320 optind = optreset = 1;
321
322 optarg = NULL;
323 if (optreset)
324 nonopt_start = nonopt_end = -1;
325start:
326 if (optreset || !*place) { /* update scanning pointer */
327 optreset = 0;
328 if (optind >= nargc) { /* end of argument vector */
329 place = EMSG;
330 if (nonopt_end != -1) {
331 /* do permutation, if we have to */
332 permute_args(nonopt_start, nonopt_end,
333 optind, nargv);
334 optind -= nonopt_end - nonopt_start;
335 }
336 else if (nonopt_start != -1) {
337 /*
338 * If we skipped non-options, set optind
339 * to the first of them.
340 */
341 optind = nonopt_start;
342 }
343 nonopt_start = nonopt_end = -1;
344 return (-1);
345 }
346 if (*(place = nargv[optind]) != '-' ||
347 (place[1] == '\0' && strchr(options, '-') == NULL)) {
348 place = EMSG; /* found non-option */
349 if (flags & FLAG_ALLARGS) {
350 /*
351 * GNU extension:
352 * return non-option as argument to option 1
353 */
354 optarg = nargv[optind++];
355 return (INORDER);
356 }
357 if (!(flags & FLAG_PERMUTE)) {
358 /*
359 * If no permutation wanted, stop parsing
360 * at first non-option.
361 */
362 return (-1);
363 }
364 /* do permutation */
365 if (nonopt_start == -1)
366 nonopt_start = optind;
367 else if (nonopt_end != -1) {
368 permute_args(nonopt_start, nonopt_end,
369 optind, nargv);
370 nonopt_start = optind -
371 (nonopt_end - nonopt_start);
372 nonopt_end = -1;
373 }
374 optind++;
375 /* process next argument */
376 goto start;
377 }
378 if (nonopt_start != -1 && nonopt_end == -1)
379 nonopt_end = optind;
380
381 /*
382 * If we have "-" do nothing, if "--" we are done.
383 */
384 if (place[1] != '\0' && *++place == '-' && place[1] == '\0') {
385 optind++;
386 place = EMSG;
387 /*
388 * We found an option (--), so if we skipped
389 * non-options, we have to permute.
390 */
391 if (nonopt_end != -1) {
392 permute_args(nonopt_start, nonopt_end,
393 optind, nargv);
394 optind -= nonopt_end - nonopt_start;
395 }
396 nonopt_start = nonopt_end = -1;
397 return (-1);
398 }
399 }
400
401 /*
402 * Check long options if:
403 * 1) we were passed some
404 * 2) the arg is not just "-"
405 * 3) either the arg starts with -- we are getopt_long_only()
406 */
407 if (long_options != NULL && place != nargv[optind] &&
408 (*place == '-' || (flags & FLAG_LONGONLY))) {
409 short_too = 0;
410 if (*place == '-')
411 place++; /* --foo long option */
412 else if (*place != ':' && strchr(options, *place) != NULL)
413 short_too = 1; /* could be short option too */
414
415 optchar = parse_long_options(nargv, options, long_options,
416 idx, short_too);
417 if (optchar != -1) {
418 place = EMSG;
419 return (optchar);
420 }
421 }
422
423 if ((optchar = (int)*place++) == (int)':' ||
424 optchar == (int)'-' && *place != '\0' ||
425 (oli = strchr(options, optchar)) == NULL) {
426 /*
427 * If the user specified "-" and '-' isn't listed in
428 * options, return -1 (non-option) as per POSIX.
429 * Otherwise, it is an unknown option character (or ':').
430 */
431 if (optchar == (int)'-' && *place == '\0')
432 return (-1);
433 if (!*place)
434 ++optind;
435 if (PRINT_ERROR)
436 warnx(illoptchar, optchar);
437 optopt = optchar;
438 return (BADCH);
439 }
440 if (long_options != NULL && optchar == 'W' && oli[1] == ';') {
441 /* -W long-option */
442 if (*place) /* no space */
443 /* NOTHING */;
444 else if (++optind >= nargc) { /* no arg */
445 place = EMSG;
446 if (PRINT_ERROR)
447 warnx(recargchar, optchar);
448 optopt = optchar;
449 return (BADARG);
450 } else /* white space */
451 place = nargv[optind];
452 optchar = parse_long_options(nargv, options, long_options,
453 idx, 0);
454 place = EMSG;
455 return (optchar);
456 }
457 if (*++oli != ':') { /* doesn't take argument */
458 if (!*place)
459 ++optind;
460 } else { /* takes (optional) argument */
461 optarg = NULL;
462 if (*place) /* no white space */
463 optarg = place;
464 /* XXX: disable test for :: if PC? (GNU doesn't) */
465 else if (oli[1] != ':') { /* arg not optional */
466 if (++optind >= nargc) { /* no arg */
467 place = EMSG;
468 if (PRINT_ERROR)
469 warnx(recargchar, optchar);
470 optopt = optchar;
471 return (BADARG);
472 } else
473 optarg = nargv[optind];
474 } else if (!(flags & FLAG_PERMUTE)) {
475 /*
476 * If permutation is disabled, we can accept an
477 * optional arg separated by whitespace.
478 */
479 if (optind + 1 < nargc)
480 optarg = nargv[++optind];
481 }
482 place = EMSG;
483 ++optind;
484 }
485 /* dump back option letter */
486 return (optchar);
487}
488
489#ifdef REPLACE_GETOPT
490/*
491 * getopt --
492 * Parse argc/argv argument vector.
493 *
494 * [eventually this will replace the BSD getopt]
495 */
496int
497getopt(int nargc, char * const *nargv, const char *options)
498{
499
500 /*
501 * We dont' pass FLAG_PERMUTE to getopt_internal() since
502 * the BSD getopt(3) (unlike GNU) has never done this.
503 *
504 * Furthermore, since many privileged programs call getopt()
505 * before dropping privileges it makes sense to keep things
506 * as simple (and bug-free) as possible.
507 */
508 return (getopt_internal(nargc, nargv, options, NULL, NULL, 0));
509}
510#endif /* REPLACE_GETOPT */
511
512/*
513 * getopt_long --
514 * Parse argc/argv argument vector.
515 */
516int
517getopt_long(nargc, nargv, options, long_options, idx)
518 int nargc;
519 char * const *nargv;
520 const char *options;
521 const struct option *long_options;
522 int *idx;
523{
524
525 return (getopt_internal(nargc, nargv, options, long_options, idx,
526 FLAG_PERMUTE));
527}
528
529/*
530 * getopt_long_only --
531 * Parse argc/argv argument vector.
532 */
533int
534getopt_long_only(nargc, nargv, options, long_options, idx)
535 int nargc;
536 char * const *nargv;
537 const char *options;
538 const struct option *long_options;
539 int *idx;
540{
541
542 return (getopt_internal(nargc, nargv, options, long_options, idx,
543 FLAG_PERMUTE|FLAG_LONGONLY));
544}
diff --git a/src/lib/libc/stdlib/getsubopt.3 b/src/lib/libc/stdlib/getsubopt.3
new file mode 100644
index 0000000000..8513cfb66a
--- /dev/null
+++ b/src/lib/libc/stdlib/getsubopt.3
@@ -0,0 +1,143 @@
1.\" $OpenBSD: getsubopt.3,v 1.8 2004/01/23 23:08:46 jmc 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. Neither the name of the University nor the names of its contributors
15.\" may be used to endorse or promote products derived from this software
16.\" without specific prior written permission.
17.\"
18.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28.\" SUCH DAMAGE.
29.\"
30.\" @(#)getsubopt.3 8.1 (Berkeley) 6/9/93
31.\"
32.Dd June 9, 1993
33.Dt GETSUBOPT 3
34.Os
35.Sh NAME
36.Nm getsubopt
37.Nd get sub options from an argument
38.Sh SYNOPSIS
39.Fd #include <stdlib.h>
40.Vt extern char *suboptarg;
41.Ft int
42.Fn getsubopt "char **optionp" "char * const *tokens" "char **valuep"
43.Sh DESCRIPTION
44The
45.Fn getsubopt
46function parses a string containing tokens delimited by one or more
47tab, space or comma
48.Pq Ql \&,
49characters.
50It is intended for use in parsing groups of option arguments provided
51as part of a utility command line.
52.Pp
53The argument
54.Fa optionp
55is a pointer to a pointer to the string.
56The argument
57.Fa tokens
58is a pointer to a null-terminated array of pointers to strings.
59.Pp
60The
61.Fn getsubopt
62function returns the zero-based offset of the pointer in the
63.Fa tokens
64array referencing a string which matches the first token
65in the string, or \-1 if the string contains no tokens or
66.Fa tokens
67does not contain a matching string.
68.Pp
69If the token is of the form
70.Ar name Ns = Ns Ar value ,
71the location referenced by
72.Fa valuep
73will be set to point to the start of the
74.Dq value
75portion of the token.
76.Pp
77On return from
78.Fn getsubopt ,
79.Fa optionp
80will be set to point to the start of the next token in the string,
81or the null at the end of the string if no more tokens are present.
82The external variable
83.Fa suboptarg
84will be set to point to the start of the current token, or
85.Dv NULL
86if no tokens were present.
87The argument
88.Fa valuep
89will be set to point to the value portion of the token, or
90.Dv NULL
91if no value portion was present.
92.Sh EXAMPLES
93.Bd -literal -compact
94char *tokens[] = {
95 #define ONE 0
96 "one",
97 #define TWO 1
98 "two",
99 NULL
100};
101
102\&...
103
104extern char *optarg, *suboptarg;
105char *options, *value;
106
107while ((ch = getopt(argc, argv, "ab:")) != \-1) {
108 switch(ch) {
109 case 'a':
110 /* process ``a'' option */
111 break;
112 case 'b':
113 options = optarg;
114 while (*options) {
115 switch(getsubopt(&options, tokens, &value)) {
116 case ONE:
117 /* process ``one'' sub option */
118 break;
119 case TWO:
120 /* process ``two'' sub option */
121 if (!value)
122 error("no value for two");
123 i = atoi(value);
124 break;
125 case \-1:
126 if (suboptarg)
127 error("illegal sub option %s",
128 suboptarg);
129 else
130 error("missing sub option");
131 break;
132 }
133 break;
134 }
135.Ed
136.Sh SEE ALSO
137.Xr getopt 3 ,
138.Xr strsep 3
139.Sh HISTORY
140The
141.Fn getsubopt
142function first appeared in
143.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..308458ea75
--- /dev/null
+++ b/src/lib/libc/stdlib/getsubopt.c
@@ -0,0 +1,102 @@
1/* $OpenBSD: getsubopt.c,v 1.2 2003/06/02 20:18:37 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. Neither the name of the University 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 REGENTS 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 REGENTS 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#ifndef lint
33#if 0
34static char sccsid[] = "@(#)getsubopt.c 8.1 (Berkeley) 6/4/93";
35#else
36static char rcsid[] = "$OpenBSD: getsubopt.c,v 1.2 2003/06/02 20:18:37 millert Exp $";
37#endif
38#endif /* not lint */
39
40#include <unistd.h>
41#include <stdlib.h>
42#include <string.h>
43
44/*
45 * The SVID interface to getsubopt provides no way of figuring out which
46 * part of the suboptions list wasn't matched. This makes error messages
47 * tricky... The extern variable suboptarg is a pointer to the token
48 * which didn't match.
49 */
50char *suboptarg;
51
52int
53getsubopt(optionp, tokens, valuep)
54 register char **optionp, **valuep;
55 register char * const *tokens;
56{
57 register int cnt;
58 register char *p;
59
60 suboptarg = *valuep = NULL;
61
62 if (!optionp || !*optionp)
63 return(-1);
64
65 /* skip leading white-space, commas */
66 for (p = *optionp; *p && (*p == ',' || *p == ' ' || *p == '\t'); ++p);
67
68 if (!*p) {
69 *optionp = p;
70 return(-1);
71 }
72
73 /* save the start of the token, and skip the rest of the token. */
74 for (suboptarg = p;
75 *++p && *p != ',' && *p != '=' && *p != ' ' && *p != '\t';);
76
77 if (*p) {
78 /*
79 * If there's an equals sign, set the value pointer, and
80 * skip over the value part of the token. Terminate the
81 * token.
82 */
83 if (*p == '=') {
84 *p = '\0';
85 for (*valuep = ++p;
86 *p && *p != ',' && *p != ' ' && *p != '\t'; ++p);
87 if (*p)
88 *p++ = '\0';
89 } else
90 *p++ = '\0';
91 /* Skip any whitespace or commas after this token. */
92 for (; *p && (*p == ',' || *p == ' ' || *p == '\t'); ++p);
93 }
94
95 /* set optionp for next round. */
96 *optionp = p;
97
98 for (cnt = 0; *tokens; ++tokens, ++cnt)
99 if (!strcmp(suboptarg, *tokens))
100 return(cnt);
101 return(-1);
102}
diff --git a/src/lib/libc/stdlib/heapsort.c b/src/lib/libc/stdlib/heapsort.c
index bd998fa357..f4aeeef7a3 100644
--- a/src/lib/libc/stdlib/heapsort.c
+++ b/src/lib/libc/stdlib/heapsort.c
@@ -13,11 +13,7 @@
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software 16 * 3. Neither the name of the University nor the names of its contributors
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 17 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission. 18 * without specific prior written permission.
23 * 19 *
@@ -35,8 +31,7 @@
35 */ 31 */
36 32
37#if defined(LIBC_SCCS) && !defined(lint) 33#if defined(LIBC_SCCS) && !defined(lint)
38/*static char sccsid[] = "from: @(#)heapsort.c 8.1 (Berkeley) 6/4/93";*/ 34static char *rcsid = "$OpenBSD: heapsort.c,v 1.6 2003/09/08 16:24:05 deraadt Exp $";
39static char *rcsid = "$Id: heapsort.c,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */ 35#endif /* LIBC_SCCS and not lint */
41 36
42#include <sys/types.h> 37#include <sys/types.h>
@@ -73,7 +68,7 @@ static char *rcsid = "$Id: heapsort.c,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp
73 * Build the list into a heap, where a heap is defined such that for 68 * Build the list into a heap, where a heap is defined such that for
74 * the records K1 ... KN, Kj/2 >= Kj for 1 <= j/2 <= j <= N. 69 * the records K1 ... KN, Kj/2 >= Kj for 1 <= j/2 <= j <= N.
75 * 70 *
76 * There two cases. If j == nmemb, select largest of Ki and Kj. If 71 * There are two cases. If j == nmemb, select largest of Ki and Kj. If
77 * j < nmemb, select largest of Ki, Kj and Kj+1. 72 * j < nmemb, select largest of Ki, Kj and Kj+1.
78 */ 73 */
79#define CREATE(initval, nmemb, par_i, child_i, par, child, size, count, tmp) { \ 74#define CREATE(initval, nmemb, par_i, child_i, par, child, size, count, tmp) { \
@@ -95,12 +90,12 @@ static char *rcsid = "$Id: heapsort.c,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp
95 * Select the top of the heap and 'heapify'. Since by far the most expensive 90 * Select the top of the heap and 'heapify'. Since by far the most expensive
96 * action is the call to the compar function, a considerable optimization 91 * action is the call to the compar function, a considerable optimization
97 * in the average case can be achieved due to the fact that k, the displaced 92 * in the average case can be achieved due to the fact that k, the displaced
98 * elememt, is ususally quite small, so it would be preferable to first 93 * element, is usually quite small, so it would be preferable to first
99 * heapify, always maintaining the invariant that the larger child is copied 94 * heapify, always maintaining the invariant that the larger child is copied
100 * over its parent's record. 95 * over its parent's record.
101 * 96 *
102 * Then, starting from the *bottom* of the heap, finding k's correct place, 97 * Then, starting from the *bottom* of the heap, finding k's correct place,
103 * again maintianing the invariant. As a result of the invariant no element 98 * again maintaining the invariant. As a result of the invariant no element
104 * is 'lost' when k is assigned its correct place in the heap. 99 * is 'lost' when k is assigned its correct place in the heap.
105 * 100 *
106 * The time savings from this optimization are on the order of 15-20% for the 101 * The time savings from this optimization are on the order of 15-20% for the
@@ -142,7 +137,7 @@ int
142heapsort(vbase, nmemb, size, compar) 137heapsort(vbase, nmemb, size, compar)
143 void *vbase; 138 void *vbase;
144 size_t nmemb, size; 139 size_t nmemb, size;
145 int (*compar) __P((const void *, const void *)); 140 int (*compar)(const void *, const void *);
146{ 141{
147 register int cnt, i, j, l; 142 register int cnt, i, j, l;
148 register char tmp, *tmp1, *tmp2; 143 register char tmp, *tmp1, *tmp2;
diff --git a/src/lib/libc/stdlib/insque.3 b/src/lib/libc/stdlib/insque.3
new file mode 100644
index 0000000000..cd8110ed90
--- /dev/null
+++ b/src/lib/libc/stdlib/insque.3
@@ -0,0 +1,100 @@
1.\" $OpenBSD: insque.3,v 1.3 2004/01/25 14:48:32 jmc Exp $
2.\" Copyright (c) 1993 John Brezak
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. The name of the author may be used to endorse or promote products
14.\" derived from this software without specific prior written permission.
15.\"
16.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND
17.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
20.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26.\" SUCH DAMAGE.
27.\"
28.\"
29.Dd August 12, 1993
30.Dt INSQUE 3
31.Os
32.Sh NAME
33.Nm insque ,
34.Nm remque
35.Nd insert/remove element from a queue
36.Sh SYNOPSIS
37.Fd #include <search.h>
38.Ft void
39.Fn insque "void *elem" "void *pred"
40.Ft void
41.Fn remque "void *elem"
42.Sh DESCRIPTION
43.Bf -symbolic
44These interfaces have been superceded by the
45.Xr queue 3
46macros and are provided for compatibility with legacy code.
47.Ef
48.Pp
49.Fn insque
50and
51.Fn remque
52manipulate queues built from doubly linked lists.
53The queue can be either circular or linear.
54Each element in the queue must be of the following form:
55.Bd -literal
56struct qelem {
57 struct qelem *q_forw;
58 struct qelem *q_back;
59 char q_data[];
60};
61.Ed
62.Pp
63The first two elements in the struct must be pointers of the
64same type that point to the previous and next elements in
65the queue respectively.
66Any subsequent data in the struct is application-dependent.
67.Pp
68The
69.Fn insque
70function inserts
71.Fa elem
72into a queue immediately after
73.Fa pred .
74.Pp
75The
76.Fn remque
77function removes
78.Fa elem
79from the queue.
80.Sh DIAGNOSTICS
81These functions are not atomic unless that machine architecture allows it.
82.Sh SEE ALSO
83.Xr queue 3
84.Sh STANDARDS
85The
86.Fn lsearch
87and
88.Fn lfind
89functions conform to the
90.St -p1003.1-2001
91and
92.St -xpg4.3 .
93specifications.
94.Sh HISTORY
95The
96.Fn insque
97and
98.Fn remque
99functions are derived from the insque and remque instructions on a
100.Tn VAX .
diff --git a/src/lib/libc/stdlib/insque.c b/src/lib/libc/stdlib/insque.c
new file mode 100644
index 0000000000..549246c71f
--- /dev/null
+++ b/src/lib/libc/stdlib/insque.c
@@ -0,0 +1,52 @@
1/* $OpenBSD: insque.c,v 1.1 2003/05/08 23:26:30 millert Exp $ */
2
3/*
4 * Copyright (c) 1993 John Brezak
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 be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
22 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#if defined(LIBC_SCCS) && !defined(lint)
32static char *rcsid = "$OpenBSD: insque.c,v 1.1 2003/05/08 23:26:30 millert Exp $";
33#endif /* LIBC_SCCS and not lint */
34
35#include <search.h>
36
37struct qelem {
38 struct qelem *q_forw;
39 struct qelem *q_back;
40};
41
42void
43insque(void *entry, void *pred)
44{
45 struct qelem *e = (struct qelem *) entry;
46 struct qelem *p = (struct qelem *) pred;
47
48 e->q_forw = p->q_forw;
49 e->q_back = p;
50 p->q_forw->q_back = e;
51 p->q_forw = e;
52}
diff --git a/src/lib/libc/stdlib/jrand48.c b/src/lib/libc/stdlib/jrand48.c
index 205781e0ee..99cddb71e5 100644
--- a/src/lib/libc/stdlib/jrand48.c
+++ b/src/lib/libc/stdlib/jrand48.c
@@ -11,6 +11,10 @@
11 * to anyone/anything when using this software. 11 * to anyone/anything when using this software.
12 */ 12 */
13 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
14#include "rand48.h" 18#include "rand48.h"
15 19
16long 20long
diff --git a/src/lib/libc/stdlib/l64a.c b/src/lib/libc/stdlib/l64a.c
index 3069b31bf6..4e99391254 100644
--- a/src/lib/libc/stdlib/l64a.c
+++ b/src/lib/libc/stdlib/l64a.c
@@ -4,13 +4,14 @@
4 */ 4 */
5 5
6#if defined(LIBC_SCCS) && !defined(lint) 6#if defined(LIBC_SCCS) && !defined(lint)
7static char *rcsid = "$NetBSD: l64a.c,v 1.4 1995/05/11 23:04:52 jtc Exp $"; 7static char *rcsid = "$OpenBSD: l64a.c,v 1.3 1997/08/17 22:58:34 millert Exp $";
8#endif 8#endif /* LIBC_SCCS and not lint */
9 9
10#include <errno.h>
10#include <stdlib.h> 11#include <stdlib.h>
11 12
12char * 13char *
13l64a (value) 14l64a(value)
14 long value; 15 long value;
15{ 16{
16 static char buf[8]; 17 static char buf[8];
@@ -18,8 +19,10 @@ l64a (value)
18 int digit; 19 int digit;
19 int i; 20 int i;
20 21
21 if (!value) 22 if (value < 0) {
22 return NULL; 23 errno = EINVAL;
24 return(NULL);
25 }
23 26
24 for (i = 0; value != 0 && i < 6; i++) { 27 for (i = 0; value != 0 && i < 6; i++) {
25 digit = value & 0x3f; 28 digit = value & 0x3f;
@@ -39,5 +42,5 @@ l64a (value)
39 42
40 *s = '\0'; 43 *s = '\0';
41 44
42 return buf; 45 return(buf);
43} 46}
diff --git a/src/lib/libc/stdlib/labs.3 b/src/lib/libc/stdlib/labs.3
index 28e4d2053c..742f3eedba 100644
--- a/src/lib/libc/stdlib/labs.3
+++ b/src/lib/libc/stdlib/labs.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,35 +29,40 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)labs.3 5.3 (Berkeley) 6/29/91 32.\" $OpenBSD: labs.3,v 1.7 2003/07/21 20:20:04 millert Exp $
37.\" $Id: labs.3,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd May 14, 2003
40.Dt LABS 3 35.Dt LABS 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
43.Nm labs 38.Nm labs, llabs
44.Nd return the absolute value of a long integer 39.Nd return the absolute value of a long integer
45.Sh SYNOPSIS 40.Sh SYNOPSIS
46.Fd #include <stdlib.h> 41.Fd #include <stdlib.h>
47.Ft long 42.Ft long
48.Fn labs "long j" 43.Fn labs "long i"
44.Ft long long
45.Fn llabs "long long j"
49.Sh DESCRIPTION 46.Sh DESCRIPTION
50The 47The
51.Fn labs 48.Fn labs
52function 49function returns the absolute value of the long integer
53returns the absolute value of the long integer 50.Fa i .
54.Ar j . 51The
52.Fn llabs
53function returns the absolute value of the long long integer
54.Fa j .
55.Sh SEE ALSO 55.Sh SEE ALSO
56.Xr abs 3 , 56.Xr abs 3 ,
57.Xr floor 3 ,
58.Xr cabs 3 , 57.Xr cabs 3 ,
58.Xr floor 3 ,
59.Xr math 3 59.Xr math 3
60.Sh STANDARDS 60.Sh STANDARDS
61The 61The
62.Fn labs 62.Fn labs
63function 63and
64conforms to 64.Fn llabs
65.St -ansiC . 65functions conform to
66.St -ansiC-99 .
66.Sh BUGS 67.Sh BUGS
67The absolute value of the most negative integer remains negative. 68The 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
index ccf1415792..51ef490d97 100644
--- a/src/lib/libc/stdlib/labs.c
+++ b/src/lib/libc/stdlib/labs.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,8 +28,7 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)labs.c 5.2 (Berkeley) 5/17/90";*/ 31static char *rcsid = "$OpenBSD: labs.c,v 1.3 2003/06/02 20:18:37 millert Exp $";
36static char *rcsid = "$Id: labs.c,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
39#include <stdlib.h> 34#include <stdlib.h>
diff --git a/src/lib/libc/stdlib/lcong48.c b/src/lib/libc/stdlib/lcong48.c
index 965d46b17a..44bd74e48a 100644
--- a/src/lib/libc/stdlib/lcong48.c
+++ b/src/lib/libc/stdlib/lcong48.c
@@ -11,6 +11,10 @@
11 * to anyone/anything when using this software. 11 * to anyone/anything when using this software.
12 */ 12 */
13 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
14#include "rand48.h" 18#include "rand48.h"
15 19
16extern unsigned short __rand48_seed[3]; 20extern unsigned short __rand48_seed[3];
diff --git a/src/lib/libc/stdlib/ldiv.3 b/src/lib/libc/stdlib/ldiv.3
index a7b5ccf878..63e1f2165c 100644
--- a/src/lib/libc/stdlib/ldiv.3
+++ b/src/lib/libc/stdlib/ldiv.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,8 +29,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)ldiv.3 5.3 (Berkeley) 6/29/91 32.\" $OpenBSD: ldiv.3,v 1.7 2004/01/23 23:08:46 jmc Exp $
37.\" $Id: ldiv.3,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd June 29, 1991
40.Dt LDIV 3 35.Dt LDIV 3
@@ -49,24 +44,22 @@
49.Sh DESCRIPTION 44.Sh DESCRIPTION
50The 45The
51.Fn ldiv 46.Fn ldiv
52function 47function computes the value
53computes the value 48.Fa num Ns / Ns Fa denom
54.Ar num/denom
55and returns the quotient and remainder in a structure named 49and returns the quotient and remainder in a structure named
56.Ar ldiv_t 50.Li ldiv_t
57that contains two 51that contains two
58.Em long integer 52.Li long integer
59members named 53members named
60.Ar quot 54.Fa quot
61and 55and
62.Ar rem . 56.Fa rem .
63.Sh SEE ALSO 57.Sh SEE ALSO
64.Xr div 3 , 58.Xr div 3 ,
65.Xr qdiv 3 , 59.Xr math 3 ,
66.Xr math 3 60.Xr qdiv 3
67.Sh STANDARDS 61.Sh STANDARDS
68The 62The
69.Fn ldiv 63.Fn ldiv
70function 64function conforms to
71conforms to
72.St -ansiC . 65.St -ansiC .
diff --git a/src/lib/libc/stdlib/ldiv.c b/src/lib/libc/stdlib/ldiv.c
index f7074507e5..e005ff77de 100644
--- a/src/lib/libc/stdlib/ldiv.c
+++ b/src/lib/libc/stdlib/ldiv.c
@@ -13,11 +13,7 @@
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software 16 * 3. Neither the name of the University nor the names of its contributors
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 17 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission. 18 * without specific prior written permission.
23 * 19 *
@@ -35,8 +31,7 @@
35 */ 31 */
36 32
37#if defined(LIBC_SCCS) && !defined(lint) 33#if defined(LIBC_SCCS) && !defined(lint)
38/*static char *sccsid = "from: @(#)ldiv.c 5.2 (Berkeley) 4/16/91";*/ 34static char *rcsid = "$OpenBSD: ldiv.c,v 1.3 2003/06/02 20:18:37 millert Exp $";
39static char *rcsid = "$Id: ldiv.c,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */ 35#endif /* LIBC_SCCS and not lint */
41 36
42#include <stdlib.h> /* ldiv_t */ 37#include <stdlib.h> /* ldiv_t */
diff --git a/src/lib/libc/stdlib/llabs.c b/src/lib/libc/stdlib/llabs.c
new file mode 100644
index 0000000000..9611b5aefd
--- /dev/null
+++ b/src/lib/libc/stdlib/llabs.c
@@ -0,0 +1,45 @@
1/* $OpenBSD: llabs.c,v 1.1 2003/07/21 20:20:04 millert Exp $ */
2
3/*-
4 * Copyright (c) 1990 The Regents of the University of California.
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 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: llabs.c,v 1.1 2003/07/21 20:20:04 millert Exp $";
38#endif /* LIBC_SCCS and not lint */
39
40#include <stdlib.h>
41
42long long llabs(long long j)
43{
44 return (j < 0 ? -j : j);
45}
diff --git a/src/lib/libc/stdlib/lrand48.c b/src/lib/libc/stdlib/lrand48.c
index 8e7f26237f..6b7524a51b 100644
--- a/src/lib/libc/stdlib/lrand48.c
+++ b/src/lib/libc/stdlib/lrand48.c
@@ -11,6 +11,10 @@
11 * to anyone/anything when using this software. 11 * to anyone/anything when using this software.
12 */ 12 */
13 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
14#include "rand48.h" 18#include "rand48.h"
15 19
16extern unsigned short __rand48_seed[3]; 20extern unsigned short __rand48_seed[3];
diff --git a/src/lib/libc/stdlib/lsearch.3 b/src/lib/libc/stdlib/lsearch.3
new file mode 100644
index 0000000000..2adc51096d
--- /dev/null
+++ b/src/lib/libc/stdlib/lsearch.3
@@ -0,0 +1,103 @@
1.\" Copyright (c) 1989, 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. Neither the name of the University nor the names of its contributors
13.\" may be used to endorse or promote products derived from this software
14.\" without specific prior written permission.
15.\"
16.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
17.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
20.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26.\" SUCH DAMAGE.
27.\"
28.\" @(#)lsearch.3 8.1 (Berkeley) 6/4/93
29.\"
30.Dd June 4, 1993
31.Dt LSEARCH 3
32.Os
33.Sh NAME
34.Nm lsearch ,
35.Nm lfind
36.Nd linear searching routines
37.Sh SYNOPSIS
38.Ft char *
39.Fn lsearch "const void *key" "const void *base" "size_t *nelp" "size_t width" "int (*compar)(void *, void *)"
40.Ft char *
41.Fn lfind "const void *key" "const void *base" "size_t *nelp" "size_t width" "int (*compar)(void *, void *)"
42.Sh DESCRIPTION
43The functions
44.Fn lsearch ,
45and
46.Fn lfind
47provide basic linear searching functionality.
48.Pp
49.Fa base
50is the pointer to the beginning of an array.
51The argument
52.Fa nelp
53is the current number of elements in the array, where each element
54is
55.Fa width
56bytes long.
57The
58.Fa compar
59function
60is a comparison routine which is used to compare two elements.
61It takes two arguments which point to the
62.Fa key
63object and to an array member, in that order, and must return an integer
64less than, equivalent to, or greater than zero if the
65.Fa key
66object is considered, respectively, to be less than, equal to, or greater
67than the array member.
68.Pp
69The
70.Fn lsearch
71and
72.Fn lfind
73functions
74return a pointer into the array referenced by
75.Fa base
76where
77.Fa key
78is located.
79If
80.Fa key
81does not exist,
82.Fn lfind
83will return a null pointer and
84.Fn lsearch
85will add it to the array.
86When an element is added to the array by
87.Fn lsearch
88the location referenced by the argument
89.Fa nelp
90is incremented by one.
91.Sh SEE ALSO
92.Xr bsearch 3 ,
93.Xr db 3
94.Sh STANDARDS
95The
96.Fn lsearch
97and
98.Fn lfind
99functions conform to the
100.St -p1003.1-2001
101and
102.St -xpg4.3 .
103specifications.
diff --git a/src/lib/libc/stdlib/lsearch.c b/src/lib/libc/stdlib/lsearch.c
new file mode 100644
index 0000000000..82483d1c82
--- /dev/null
+++ b/src/lib/libc/stdlib/lsearch.c
@@ -0,0 +1,86 @@
1/*
2 * Copyright (c) 1989, 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 * Roger L. Snyder.
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 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
33#if defined(LIBC_SCCS) && !defined(lint)
34static char sccsid[] = "@(#)lsearch.c 8.1 (Berkeley) 6/4/93";
35#endif /* LIBC_SCCS and not lint */
36
37#include <sys/types.h>
38#include <string.h>
39#include <search.h>
40
41typedef int (*cmp_fn_t)(const void *, const void *);
42static void *linear_base(const void *, const void *, size_t *, size_t,
43 cmp_fn_t, int);
44
45void *
46lsearch(const void *key, const void *base, size_t *nelp, size_t width,
47 cmp_fn_t compar)
48{
49
50 return(linear_base(key, base, nelp, width, compar, 1));
51}
52
53void *
54lfind(const void *key, const void *base, size_t *nelp, size_t width,
55 cmp_fn_t compar)
56{
57 return(linear_base(key, base, nelp, width, compar, 0));
58}
59
60static void *
61linear_base(const void *key, const void *base, size_t *nelp, size_t width,
62 cmp_fn_t compar, int add_flag)
63{
64 const char *element, *end;
65
66 end = (const char *)base + *nelp * width;
67 for (element = base; element < end; element += width)
68 if (!compar(key, element)) /* key found */
69 return((void *)element);
70
71 if (!add_flag) /* key not found */
72 return(NULL);
73
74 /*
75 * The UNIX System User's Manual, 1986 edition claims that
76 * a NULL pointer is returned by lsearch with errno set
77 * appropriately, if there is not enough room in the table
78 * to add a new item. This can't be done as none of these
79 * routines have any method of determining the size of the
80 * table. This comment isn't in the 1986-87 System V
81 * manual.
82 */
83 ++*nelp;
84 memcpy((void *)end, key, width);
85 return((void *)end);
86}
diff --git a/src/lib/libc/stdlib/malloc.3 b/src/lib/libc/stdlib/malloc.3
index 3bbf2bf65e..1154537385 100644
--- a/src/lib/libc/stdlib/malloc.3
+++ b/src/lib/libc/stdlib/malloc.3
@@ -1,5 +1,6 @@
1.\" Copyright (c) 1980, 1991 Regents of the University of California. 1.\"
2.\" All rights reserved. 2.\" Copyright (c) 1980, 1991, 1993
3.\" The Regents of the University of California. All rights reserved.
3.\" 4.\"
4.\" This code is derived from software contributed to Berkeley by 5.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information 6.\" the American National Standards Committee X3, on Information
@@ -13,11 +14,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 14.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 15.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 16.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 17.\" 3. Neither the name of the University nor the names of its contributors
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 18.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 19.\" without specific prior written permission.
23.\" 20.\"
@@ -33,19 +30,32 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 31.\" SUCH DAMAGE.
35.\" 32.\"
36.\" from: @(#)malloc.3 6.7 (Berkeley) 6/29/91 33.\" $OpenBSD: malloc.3,v 1.36 2004/02/09 13:07:42 espie Exp $
37.\" $Id: malloc.3,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $
38.\" 34.\"
39.Dd June 29, 1991 35.Dd August 27, 1996
40.Dt MALLOC 3 36.Dt MALLOC 3
41.Os BSD 4 37.Os
42.Sh NAME 38.Sh NAME
43.Nm malloc 39.Nm malloc ,
44.Nd general memory allocation function 40.Nm calloc ,
41.Nm realloc ,
42.Nm free ,
43.Nm cfree
44.Nd memory allocation and deallocation
45.Sh SYNOPSIS 45.Sh SYNOPSIS
46.Fd #include <stdlib.h> 46.Fd #include <stdlib.h>
47.Ft void * 47.Ft void *
48.Fn malloc "size_t size" 48.Fn malloc "size_t size"
49.Ft void *
50.Fn calloc "size_t nmemb" "size_t size"
51.Ft void *
52.Fn realloc "void *ptr" "size_t size"
53.Ft void
54.Fn free "void *ptr"
55.Ft void
56.Fn cfree "void *ptr"
57.Ft char *
58.Va malloc_options ;
49.Sh DESCRIPTION 59.Sh DESCRIPTION
50The 60The
51.Fn malloc 61.Fn malloc
@@ -59,33 +69,364 @@ space from the appropriate list.
59.Pp 69.Pp
60The allocated space is 70The allocated space is
61suitably aligned (after possible pointer 71suitably aligned (after possible pointer
62coercion) for storage of any type of object. If the space is of 72coercion) for storage of any type of object.
73If the space is of
63.Em pagesize 74.Em pagesize
64or larger, the memory returned will be page-aligned. 75or larger, the memory returned will be page-aligned.
76.Pp
77Allocation of a zero size object returns a pointer to a zero size object.
78This zero size object is access protected, so any access to it will
79generate an exception (SIGSEGV).
80Many zero-sized objects can be placed consecutively in shared
81protected pages.
82The minimum size of the protection on each object is suitably aligned and
83sized as previously stated, but the protection may extend further depending
84on where in a protected zone the object lands.
85.Pp
86The
87.Fn calloc
88function allocates space for an array of
89.Fa nmemb
90objects, each of whose size is
91.Fa size .
92The space is initialized to all bits zero.
93.Pp
94The
95.Fn free
96function causes the space pointed to by
97.Fa ptr
98to be deallocated, that is, at least made available for further allocation,
99but if possible, it will passed back to the kernel with
100.Xr sbrk 2 .
101If
102.Fa ptr
103is a null pointer, no action occurs.
104.Pp
105A
106.Fn cfree
107function is also provided for compatibility with old systems and other
108.Nm malloc
109libraries; it is simply an alias for
110.Fn free .
111.Pp
112The
113.Fn realloc
114function changes the size of the object pointed to by
115.Fa ptr
116to
117.Fa size
118bytes and returns a pointer to the (possibly moved) object.
119The contents of the object are unchanged up to the lesser
120of the new and old sizes.
121If the new size is larger, the value of the newly allocated portion
122of the object is indeterminate and uninitialized.
123If
124.Fa ptr
125is a null pointer, the
126.Fn realloc
127function behaves like the
128.Fn malloc
129function for the specified size.
130If the space cannot be allocated, the object
131pointed to by
132.Fa ptr
133is unchanged.
134If
135.Fa size
136is zero and
137.Fa ptr
138is not a null pointer, the object it points to is freed and a new zero size
139object is returned.
140.Pp
141When using
142.Fn realloc
143one must be careful to avoid the following idiom:
144.Bd -literal -offset indent
145size += 50;
146if ((p = realloc(p, size)) == NULL)
147 return (NULL);
148.Ed
149.Pp
150Do not adjust the variable describing how much memory has been allocated
151until one knows the allocation has been successful.
152This can cause aberrant program behavior if the incorrect size value is used.
153In most cases, the above sample will also result in a leak of memory.
154As stated earlier, a return value of
155.Dv NULL
156indicates that the old object still remains allocated.
157Better code looks like this:
158.Bd -literal -offset indent
159newsize = size + 50;
160if ((newp = realloc(p, newsize)) == NULL) {
161 free(p);
162 p = NULL;
163 size = 0;
164 return (NULL);
165}
166p = newp;
167size = newsize;
168.Ed
169.Pp
170Malloc will first look for a symbolic link called
171.Pa /etc/malloc.conf
172and next check the environment for a variable called
173.Ev MALLOC_OPTIONS
174and finally for the global variable
175.Va malloc_options
176and scan them for flags in that order.
177Flags are single letters, uppercase means on, lowercase means off.
178.Bl -tag -width indent
179.It Cm A
180.Dq Abort .
181.Fn malloc
182will coredump the process, rather than tolerate failure.
183This is a very handy debugging aid, since the core file will represent the
184time of failure, rather than when the null pointer was accessed.
185.Pp
186.It Cm D
187.Dq Dump .
188.Fn malloc
189will dump statistics in a file called
190.Pa malloc.out
191at exit.
192This option requires the library to have been compiled with -DMALLOC_STATS in
193order to have any effect.
194.Pp
195.It Cm F
196.Dq Freeguard .
197Enable use after free protection.
198Unused pages on the freelist are read and write protected to
199cause a segmentation fault upon access.
200.Pp
201.It Cm G
202.Dq Guard .
203Enable guard pages and chunk randomization.
204Each page size or larger allocation is followed by a guard page that will
205cause a segmentation fault upon any access.
206Smaller than page size chunks are returned in a random order.
207.Pp
208.It Cm H
209.Dq Hint .
210Pass a hint to the kernel about pages we don't use.
211If the machine is paging a lot this may help a bit.
212.Pp
213.It Cm J
214.Dq Junk .
215Fill some junk into the area allocated.
216Currently junk is bytes of 0xd0; this is pronounced
217.Dq Duh .
218\&:-)
219.Pp
220.It Cm N
221Do not output warning messages when encountering possible corruption
222or bad pointers.
223.Pp
224.It Cm R
225.Dq realloc .
226Always reallocate when
227.Fn realloc
228is called, even if the initial allocation was big enough.
229This can substantially aid in compacting memory.
230.\".Pp
231.\".It Cm U
232.\".Dq utrace .
233.\"Generate entries for
234.\".Xr ktrace 1
235.\"for all operations.
236.\"Consult the source for this one.
237.Pp
238.It Cm X
239.Dq xmalloc .
240Rather than return failure,
241.Xr abort 3
242the program with a diagnostic message on stderr.
243It is the intention that this option be set at compile time by
244including in the source:
245.Bd -literal -offset indent
246extern char *malloc_options;
247malloc_options = "X";
248.Ed
249.Pp
250.It Cm Z
251.Dq Zero .
252Fill some junk into the area allocated (see
253.Cm J ) ,
254except for the exact length the user asked for, which is zeroed.
255.Pp
256.It Cm <
257.Dq Half the cache size .
258Reduce the size of the cache by a factor of two.
259.Pp
260.It Cm >
261.Dq Double the cache size .
262Double the size of the cache by a factor of two.
263.El
264.Pp
265So to set a systemwide reduction of cache size and coredumps on problems
266one would:
267.Li ln -s 'A<' /etc/malloc.conf
268.Pp
269The
270.Cm J
271and
272.Cm Z
273flags are mostly for testing and debugging.
274If a program changes behavior if either of these options are used,
275it is buggy.
276.Pp
277The default cache size is 16 pages.
65.Sh RETURN VALUES 278.Sh RETURN VALUES
66The 279The
67.Fn malloc 280.Fn malloc
68function returns 281and
69a pointer to the allocated space if successful; otherwise 282.Fn calloc
70a null pointer is returned. 283functions return a pointer to the allocated space if successful; otherwise,
284a null pointer is returned and
285.Va errno
286is set to
287.Er ENOMEM .
288.Pp
289The
290.Fn free
291and
292.Fn cfree
293functions return no value.
294.Pp
295The
296.Fn realloc
297function returns a pointer to the (possibly moved) allocated space
298if successful; otherwise, a null pointer is returned and
299.Va errno
300is set to
301.Er ENOMEM .
302.Sh ENVIRONMENT
303See above.
304.Sh FILES
305.Bl -tag -width "/etc/malloc.conf"
306.It Pa /etc/malloc.conf
307symbolic link to filename containing option flags
308.El
309.Sh DIAGNOSTICS
310If
311.Fn malloc ,
312.Fn calloc ,
313.Fn realloc ,
314or
315.Fn free
316detect an error or warning condition,
317a message will be printed to file descriptor
3182 (not using stdio).
319Errors will always result in the process being
320.Xr abort 3 'ed.
321If the
322.Cm A
323option has been specified, warnings will also
324.Xr abort 3
325the process.
326.Pp
327Here is a brief description of the error messages and what they mean:
328.Bl -tag -width Fl
329.It Dq (ES): mumble mumble mumble
330.Fn malloc
331has been compiled with
332.Dv \&-DEXTRA_SANITY
333and something looks fishy in there.
334Consult sources and/or wizards.
335.It Dq allocation failed
336If the
337.Cm A
338option is specified it is an error for
339.Fn malloc ,
340.Fn calloc ,
341or
342.Fn realloc
343to return
344.Dv NULL .
345.It Dq mmap(2) failed, check limits.
346This is a rather weird condition that is most likely to indicate a
347seriously overloaded system or a
348.Xr ulimit 1
349restriction.
350.It Dq freelist is destroyed.
351.Fn malloc Ns 's
352internal freelist has been stomped on.
353.El
354.Pp
355Here is a brief description of the warning messages and what they mean:
356.Bl -tag -width Fl
357.It Dq chunk/page is already free.
358There was an attempt to free a chunk that had already been freed.
359.It Dq junk pointer, too high to make sense.
360The pointer doesn't make sense.
361It's above the area of memory that
362.Fn malloc
363knows something about.
364This could be a pointer from some
365.Xr mmap 2 'ed
366memory.
367.It Dq junk pointer, too low to make sense.
368The pointer doesn't make sense.
369It's below the area of memory that
370.Fn malloc
371knows something about.
372This pointer probably came from your data or bss segments.
373.It Dq malloc() has never been called.
374Nothing has ever been allocated, yet something is being freed or
375realloc'ed.
376.It Dq modified (chunk-/page-) pointer.
377The pointer passed to free or realloc has been modified.
378.It Dq pointer to wrong page.
379The pointer that
380.Fn malloc
381is trying to free is not pointing to
382a sensible page.
383.It Dq recursive call.
384An attempt was made to call recursively into these functions, i.e., from a
385signal handler.
386This behavior is not supported.
387In particular, signal handlers should
388.Em not
389use any of the
390.Fn malloc
391functions nor utilize any other functions which may call
392.Fn malloc
393(e.g.,
394.Xr stdio 3
395routines).
396.It Dq unknown char in MALLOC_OPTIONS
397We found something we didn't understand.
398.El
71.Sh SEE ALSO 399.Sh SEE ALSO
72.Xr brk 2 , 400.Xr brk 2 ,
73.Xr getpagesize 2 ,
74.Xr free 3 ,
75.Xr calloc 3 ,
76.Xr alloca 3 , 401.Xr alloca 3 ,
77.Xr realloc 3 , 402.Xr getpagesize 3 ,
78.Xr memory 3 403.Xr memory 3
79.Sh STANDARDS 404.Sh STANDARDS
80The 405The
81.Fn malloc 406.Fn malloc
82function conforms to 407function conforms to
83.St -ansiC . 408.St -ansiC .
84.Sh BUGS 409.Sh HISTORY
85The current implementation of 410The present implementation of
86.Xr malloc 411.Fn malloc
87does not always fail gracefully when system 412started out as a filesystem on a drum
88memory limits are approached. 413attached to a 20-bit binary challenged computer built with discrete germanium
89It may fail to allocate memory when larger free blocks could be broken 414transistors, and it has since graduated to handle primary storage rather than
90up, or when limits are exceeded because the size is rounded up. 415secondary.
91It is optimized for sizes that are powers of two. 416.Pp
417The main difference from other
418.Fn malloc
419implementations are believed to be that
420the free pages are not accessed until allocated.
421Most
422.Fn malloc
423implementations will store a data structure containing a,
424possibly double-, linked list in the free chunks of memory, used to tie
425all the free memory together.
426That is a quite suboptimal thing to do.
427Every time the free-list is traversed, all the otherwise unused, and very
428likely paged out, pages get faulted into primary memory, just to see what
429lies after them in the list.
430.Pp
431On systems which are paging, this can increase the page-faults
432of a process by a factor of five.
diff --git a/src/lib/libc/stdlib/malloc.c b/src/lib/libc/stdlib/malloc.c
index 3c57fad024..f5704754a0 100644
--- a/src/lib/libc/stdlib/malloc.c
+++ b/src/lib/libc/stdlib/malloc.c
@@ -1,421 +1,1327 @@
1/* 1/*
2 * Copyright (c) 1983 Regents of the University of California. 2 * ----------------------------------------------------------------------------
3 * All rights reserved. 3 * "THE BEER-WARE LICENSE" (Revision 42):
4 * 4 * <phk@FreeBSD.ORG> wrote this file. As long as you retain this notice you
5 * Redistribution and use in source and binary forms, with or without 5 * can do whatever you want with this stuff. If we meet some day, and you think
6 * modification, are permitted provided that the following conditions 6 * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
7 * are met: 7 * ----------------------------------------------------------------------------
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 */ 8 */
33 9
34#if defined(LIBC_SCCS) && !defined(lint) 10#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)malloc.c 5.11 (Berkeley) 2/23/91";*/ 11static char rcsid[] = "$OpenBSD: malloc.c,v 1.66 2004/02/19 23:20:53 tdeval Exp $";
36static char *rcsid = "$Id: malloc.c,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 12#endif /* LIBC_SCCS and not lint */
38 13
39/* 14/*
40 * malloc.c (Caltech) 2/21/82 15 * Defining MALLOC_EXTRA_SANITY will enable extra checks which are
41 * Chris Kingsley, kingsley@cit-20. 16 * related to internal conditions and consistency in malloc.c. This has
42 * 17 * a noticeable runtime performance hit, and generally will not do you
43 * This is a very fast storage allocator. It allocates blocks of a small 18 * any good unless you fiddle with the internals of malloc or want
44 * number of different sizes, and keeps free lists of each size. Blocks that 19 * to catch random pointer corruption as early as possible.
45 * don't exactly fit are passed up to the next larger size. In this 20 */
46 * implementation, the available sizes are 2^n-4 (or 2^n-10) bytes long. 21#ifndef MALLOC_EXTRA_SANITY
47 * This is designed for use in a virtual memory environment. 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.
48 */ 37 */
38#define SOME_JUNK 0xd0 /* as in "Duh" :-) */
49 39
50#include <sys/types.h> 40#include <sys/types.h>
41#include <sys/param.h>
42#include <sys/mman.h>
43#include <sys/uio.h>
44#include <stdio.h>
51#include <stdlib.h> 45#include <stdlib.h>
52#include <string.h> 46#include <string.h>
53#include <unistd.h> 47#include <unistd.h>
48#include <fcntl.h>
49#include <limits.h>
50#include <errno.h>
54 51
55#define NULL 0 52#include "thread_private.h"
56 53
57static void morecore(); 54/*
58static int findbucket(); 55 * The basic parameters you can tweak.
56 *
57 * malloc_pageshift pagesize = 1 << malloc_pageshift
58 * It's probably best if this is the native
59 * page size, but it shouldn't have to be.
60 *
61 * malloc_minsize minimum size of an allocation in bytes.
62 * If this is too small it's too much work
63 * to manage them. This is also the smallest
64 * unit of alignment used for the storage
65 * returned by malloc/realloc.
66 *
67 */
68
69#if defined(__OpenBSD__) && defined(__sparc__)
70# define malloc_pageshift 13U
71#endif /* __OpenBSD__ */
59 72
60/* 73/*
61 * The overhead on a block is at least 4 bytes. When free, this space 74 * No user serviceable parts behind this point.
62 * contains a pointer to the next free block, and the bottom two bits must 75 *
63 * be zero. When in use, the first byte is set to MAGIC, and the second 76 * This structure describes a page worth of chunks.
64 * byte is the size index. The remaining bytes are for alignment.
65 * If range checking is enabled then a second word holds the size of the
66 * requested block, less 1, rounded up to a multiple of sizeof(RMAGIC).
67 * The order of elements is critical: ov_magic must overlay the low order
68 * bits of ov_next, and ov_magic can not be a valid ov_next bit pattern.
69 */ 77 */
70union overhead { 78
71 union overhead *ov_next; /* when free */ 79struct pginfo {
72 struct { 80 struct pginfo *next; /* next on the free list */
73 u_char ovu_magic; /* magic number */ 81 void *page; /* Pointer to the page */
74 u_char ovu_index; /* bucket # */ 82 u_short size; /* size of this page's chunks */
75#ifdef RCHECK 83 u_short shift; /* How far to shift for this size chunks */
76 u_short ovu_rmagic; /* range magic number */ 84 u_short free; /* How many free chunks */
77 u_long ovu_size; /* actual block size */ 85 u_short total; /* How many chunk */
78#endif 86 u_long bits[1]; /* Which chunks are free */
79 } ovu;
80#define ov_magic ovu.ovu_magic
81#define ov_index ovu.ovu_index
82#define ov_rmagic ovu.ovu_rmagic
83#define ov_size ovu.ovu_size
84}; 87};
85 88
86#define MAGIC 0xef /* magic # on accounting info */ 89/*
87#define RMAGIC 0x5555 /* magic # on range info */ 90 * This structure describes a number of free pages.
91 */
92
93struct pgfree {
94 struct pgfree *next; /* next run of free pages */
95 struct pgfree *prev; /* prev run of free pages */
96 void *page; /* pointer to free pages */
97 void *end; /* pointer to end of free pages */
98 u_long size; /* number of bytes free */
99};
100
101/*
102 * How many bits per u_long in the bitmap.
103 * Change only if not 8 bits/byte
104 */
105#define MALLOC_BITS (8*sizeof(u_long))
106
107/*
108 * Magic values to put in the page_directory
109 */
110#define MALLOC_NOT_MINE ((struct pginfo*) 0)
111#define MALLOC_FREE ((struct pginfo*) 1)
112#define MALLOC_FIRST ((struct pginfo*) 2)
113#define MALLOC_FOLLOW ((struct pginfo*) 3)
114#define MALLOC_MAGIC ((struct pginfo*) 4)
115
116#ifndef malloc_pageshift
117#define malloc_pageshift (PGSHIFT)
118#endif
119
120#ifndef malloc_minsize
121#define malloc_minsize 16U
122#endif
123
124#ifndef malloc_pageshift
125#error "malloc_pageshift undefined"
126#endif
127
128#if !defined(malloc_pagesize)
129#define malloc_pagesize (1UL<<malloc_pageshift)
130#endif
131
132#if ((1UL<<malloc_pageshift) != malloc_pagesize)
133#error "(1UL<<malloc_pageshift) != malloc_pagesize"
134#endif
135
136#ifndef malloc_maxsize
137#define malloc_maxsize ((malloc_pagesize)>>1)
138#endif
139
140/* A mask for the offset inside a page. */
141#define malloc_pagemask ((malloc_pagesize)-1)
142
143#define pageround(foo) (((foo) + (malloc_pagemask))&(~(malloc_pagemask)))
144#define ptr2index(foo) (((u_long)(foo) >> malloc_pageshift)-malloc_origo)
88 145
89#ifdef RCHECK 146/* fd of /dev/zero */
90#define RSLOP sizeof (u_short) 147#ifdef USE_DEV_ZERO
148static int fdzero;
149#define MMAP_FD fdzero
150#define INIT_MMAP() \
151 { if ((fdzero=open("/dev/zero", O_RDWR, 0000)) == -1) \
152 wrterror("open of /dev/zero\n"); }
91#else 153#else
92#define RSLOP 0 154#define MMAP_FD (-1)
155#define INIT_MMAP()
156#endif
157
158/* Set when initialization has been done */
159static unsigned int malloc_started;
160
161/* Number of free pages we cache */
162static unsigned int malloc_cache = 16;
163
164/* The offset from pagenumber to index into the page directory */
165static u_long malloc_origo;
166
167/* The last index in the page directory we care about */
168static u_long last_index;
169
170/* Pointer to page directory. Allocated "as if with" malloc */
171static struct pginfo **page_dir;
172
173/* How many slots in the page directory */
174static size_t malloc_ninfo;
175
176/* Free pages line up here */
177static struct pgfree free_list;
178
179/* Abort(), user doesn't handle problems. */
180static int malloc_abort = 2;
181
182/* Are we trying to die ? */
183static int suicide;
184
185#ifdef MALLOC_STATS
186/* dump statistics */
187static int malloc_stats;
93#endif 188#endif
94 189
190/* avoid outputting warnings? */
191static int malloc_silent;
192
193/* always realloc ? */
194static int malloc_realloc;
195
196/* mprotect free pages PROT_NONE? */
197static int malloc_freeprot;
198
199/* use guard pages after allocations? */
200static int malloc_guard = 0;
201
202#if defined(__FreeBSD__) || (defined(__OpenBSD__) && defined(MADV_FREE))
203/* pass the kernel a hint on free pages ? */
204static int malloc_hint;
205#endif
206
207/* xmalloc behaviour ? */
208static int malloc_xmalloc;
209
210/* zero fill ? */
211static int malloc_zero;
212
213/* junk fill ? */
214static int malloc_junk;
215
216#ifdef __FreeBSD__
217/* utrace ? */
218static int malloc_utrace;
219
220struct ut { void *p; size_t s; void *r; };
221
222void utrace(struct ut *, int);
223
224#define UTRACE(a, b, c) \
225 if (malloc_utrace) \
226 {struct ut u; u.p=a; u.s = b; u.r=c; utrace(&u, sizeof u);}
227#else /* !__FreeBSD__ */
228#define UTRACE(a,b,c)
229#endif
230
231/* my last break. */
232static void *malloc_brk;
233
234/* one location cache for free-list holders */
235static struct pgfree *px;
236
237/* compile-time options */
238char *malloc_options;
239
240/* Name of the current public function */
241static char *malloc_func;
242
243/* Macro for mmap */
244#define MMAP(size) \
245 mmap((void *)0, (size), PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, \
246 MMAP_FD, (off_t)0)
247
95/* 248/*
96 * nextf[i] is the pointer to the next free block of size 2^(i+3). The 249 * Necessary function declarations
97 * smallest allocatable block is 8 bytes. The overhead information
98 * precedes the data area returned to the user.
99 */ 250 */
100#define NBUCKETS 30 251static int extend_pgdir(u_long index);
101static union overhead *nextf[NBUCKETS]; 252static void *imalloc(size_t size);
102extern char *sbrk(); 253static void ifree(void *ptr);
254static void *irealloc(void *ptr, size_t size);
255static void *malloc_bytes(size_t size);
256
257#ifdef MALLOC_STATS
258void
259malloc_dump(FILE *fd)
260{
261 struct pginfo **pd;
262 struct pgfree *pf;
263 int j;
264
265 pd = page_dir;
266
267 /* print out all the pages */
268 for(j=0;j<=last_index;j++) {
269 fprintf(fd, "%08lx %5d ", (j+malloc_origo) << malloc_pageshift, j);
270 if (pd[j] == MALLOC_NOT_MINE) {
271 for(j++;j<=last_index && pd[j] == MALLOC_NOT_MINE;j++)
272 ;
273 j--;
274 fprintf(fd, ".. %5d not mine\n", j);
275 } else if (pd[j] == MALLOC_FREE) {
276 for(j++;j<=last_index && pd[j] == MALLOC_FREE;j++)
277 ;
278 j--;
279 fprintf(fd, ".. %5d free\n", j);
280 } else if (pd[j] == MALLOC_FIRST) {
281 for(j++;j<=last_index && pd[j] == MALLOC_FOLLOW;j++)
282 ;
283 j--;
284 fprintf(fd, ".. %5d in use\n", j);
285 } else if (pd[j] < MALLOC_MAGIC) {
286 fprintf(fd, "(%p)\n", pd[j]);
287 } else {
288 fprintf(fd, "%p %d (of %d) x %d @ %p --> %p\n",
289 pd[j], pd[j]->free, pd[j]->total,
290 pd[j]->size, pd[j]->page, pd[j]->next);
291 }
292 }
293
294 for(pf=free_list.next; pf; pf=pf->next) {
295 fprintf(fd, "Free: @%p [%p...%p[ %ld ->%p <-%p\n",
296 pf, pf->page, pf->end, pf->size, pf->prev, pf->next);
297 if (pf == pf->next) {
298 fprintf(fd, "Free_list loops\n");
299 break;
300 }
301 }
302
303 /* print out various info */
304 fprintf(fd, "Minsize\t%d\n", malloc_minsize);
305 fprintf(fd, "Maxsize\t%d\n", malloc_maxsize);
306 fprintf(fd, "Pagesize\t%lu\n", (u_long)malloc_pagesize);
307 fprintf(fd, "Pageshift\t%d\n", malloc_pageshift);
308 fprintf(fd, "FirstPage\t%ld\n", malloc_origo);
309 fprintf(fd, "LastPage\t%ld %lx\n", last_index+malloc_pageshift,
310 (last_index + malloc_pageshift) << malloc_pageshift);
311 fprintf(fd, "Break\t%ld\n", (u_long)sbrk(0) >> malloc_pageshift);
312}
313#endif /* MALLOC_STATS */
314
315extern char *__progname;
316
317static void
318wrterror(char *p)
319{
320 char *q = " error: ";
321 struct iovec iov[4];
322
323 iov[0].iov_base = __progname;
324 iov[0].iov_len = strlen(__progname);
325 iov[1].iov_base = malloc_func;
326 iov[1].iov_len = strlen(malloc_func);
327 iov[2].iov_base = q;
328 iov[2].iov_len = strlen(q);
329 iov[3].iov_base = p;
330 iov[3].iov_len = strlen(p);
331 writev(STDERR_FILENO, iov, 4);
332
333 suicide = 1;
334#ifdef MALLOC_STATS
335 if (malloc_stats)
336 malloc_dump(stderr);
337#endif /* MALLOC_STATS */
338 abort();
339}
340
341static void
342wrtwarning(char *p)
343{
344 char *q = " warning: ";
345 struct iovec iov[4];
346
347 if (malloc_abort)
348 wrterror(p);
349 else if (malloc_silent)
350 return;
351
352 iov[0].iov_base = __progname;
353 iov[0].iov_len = strlen(__progname);
354 iov[1].iov_base = malloc_func;
355 iov[1].iov_len = strlen(malloc_func);
356 iov[2].iov_base = q;
357 iov[2].iov_len = strlen(q);
358 iov[3].iov_base = p;
359 iov[3].iov_len = strlen(p);
360 writev(STDERR_FILENO, iov, 4);
361}
362
363#ifdef MALLOC_STATS
364static void
365malloc_exit(void)
366{
367 FILE *fd = fopen("malloc.out", "a");
368 char *q = "malloc() warning: Couldn't dump stats\n";
369 if (fd != NULL) {
370 malloc_dump(fd);
371 fclose(fd);
372 } else
373 write(STDERR_FILENO, q, strlen(q));
374}
375#endif /* MALLOC_STATS */
103 376
104static int pagesz; /* page size */
105static int pagebucket; /* page size bucket */
106 377
107#ifdef MSTATS
108/* 378/*
109 * nmalloc[i] is the difference between the number of mallocs and frees 379 * Allocate a number of pages from the OS
110 * for a given block size.
111 */ 380 */
112static u_int nmalloc[NBUCKETS]; 381static void *
113#include <stdio.h> 382map_pages(size_t pages)
114#endif 383{
384 caddr_t result, tail;
115 385
116#if defined(DEBUG) || defined(RCHECK) 386 result = (caddr_t)pageround((u_long)sbrk(0));
117#define ASSERT(p) if (!(p)) botch("p") 387 pages <<= malloc_pageshift;
118#include <stdio.h> 388 if (pages > SIZE_T_MAX - (size_t)result) {
119static 389#ifdef MALLOC_EXTRA_SANITY
120botch(s) 390 wrtwarning("(ES): overflow in map_pages fails\n");
121 char *s; 391#endif /* MALLOC_EXTRA_SANITY */
392 errno = ENOMEM;
393 return (NULL);
394 }
395 tail = result + pages + malloc_guard;
396
397 if (brk(tail) == (char *)-1) {
398#ifdef MALLOC_EXTRA_SANITY
399 wrtwarning("(ES): map_pages fails\n");
400#endif /* MALLOC_EXTRA_SANITY */
401 return (NULL);
402 }
403 if (malloc_guard)
404 mprotect(result + pages, malloc_pagesize, PROT_NONE);
405
406 last_index = ptr2index(tail) - 1;
407 malloc_brk = tail;
408
409 if ((last_index+1) >= malloc_ninfo && !extend_pgdir(last_index))
410 return (NULL);
411
412 return (result);
413}
414
415/*
416 * Extend page directory
417 */
418static int
419extend_pgdir(u_long index)
420{
421 struct pginfo **new, **old;
422 size_t i, oldlen;
423
424 /* Make it this many pages */
425 i = index * sizeof *page_dir;
426 i /= malloc_pagesize;
427 i += 2;
428
429 /* remember the old mapping size */
430 oldlen = malloc_ninfo * sizeof *page_dir;
431
432 /*
433 * NOTE: we allocate new pages and copy the directory rather than tempt
434 * fate by trying to "grow" the region.. There is nothing to prevent
435 * us from accidently re-mapping space that's been allocated by our caller
436 * via dlopen() or other mmap().
437 *
438 * The copy problem is not too bad, as there is 4K of page index per
439 * 4MB of malloc arena.
440 *
441 * We can totally avoid the copy if we open a file descriptor to associate
442 * the anon mappings with. Then, when we remap the pages at the new
443 * address, the old pages will be "magically" remapped.. But this means
444 * keeping open a "secret" file descriptor.....
445 */
446
447 /* Get new pages */
448 new = (struct pginfo**) MMAP(i * malloc_pagesize);
449 if (new == MAP_FAILED)
450 return (0);
451
452 /* Copy the old stuff */
453 memcpy(new, page_dir,
454 malloc_ninfo * sizeof *page_dir);
455
456 /* register the new size */
457 malloc_ninfo = i * malloc_pagesize / sizeof *page_dir;
458
459 /* swap the pointers */
460 old = page_dir;
461 page_dir = new;
462
463 /* Now free the old stuff */
464 munmap(old, oldlen);
465 return (1);
466}
467
468/*
469 * Initialize the world
470 */
471static void
472malloc_init(void)
122{ 473{
123 fprintf(stderr, "\r\nassertion botched: %s\r\n", s); 474 char *p, b[64];
124 (void) fflush(stderr); /* just in case user buffered it */ 475 int i, j;
476 int save_errno = errno;
477
478 _MALLOC_LOCK_INIT();
479
480 INIT_MMAP();
481
482#ifdef MALLOC_EXTRA_SANITY
483 malloc_junk = 1;
484#endif /* MALLOC_EXTRA_SANITY */
485
486 for (i = 0; i < 3; i++) {
487 if (i == 0) {
488 j = readlink("/etc/malloc.conf", b, sizeof b - 1);
489 if (j <= 0)
490 continue;
491 b[j] = '\0';
492 p = b;
493 } else if (i == 1) {
494 if (issetugid() == 0)
495 p = getenv("MALLOC_OPTIONS");
496 else
497 continue;
498 } else if (i == 2) {
499 p = malloc_options;
500 }
501 for (; p != NULL && *p != '\0'; p++) {
502 switch (*p) {
503 case '>': malloc_cache <<= 1; break;
504 case '<': malloc_cache >>= 1; break;
505 case 'a': malloc_abort = 0; break;
506 case 'A': malloc_abort = 1; break;
507#ifdef MALLOC_STATS
508 case 'd': malloc_stats = 0; break;
509 case 'D': malloc_stats = 1; break;
510#endif /* MALLOC_STATS */
511 case 'f': malloc_freeprot = 0; break;
512 case 'F': malloc_freeprot = 1; break;
513 case 'g': malloc_guard = 0; break;
514 case 'G': malloc_guard = malloc_pagesize; break;
515#if defined(__FreeBSD__) || (defined(__OpenBSD__) && defined(MADV_FREE))
516 case 'h': malloc_hint = 0; break;
517 case 'H': malloc_hint = 1; break;
518#endif /* __FreeBSD__ */
519 case 'r': malloc_realloc = 0; break;
520 case 'R': malloc_realloc = 1; break;
521 case 'j': malloc_junk = 0; break;
522 case 'J': malloc_junk = 1; break;
523 case 'n': malloc_silent = 0; break;
524 case 'N': malloc_silent = 1; break;
525#ifdef __FreeBSD__
526 case 'u': malloc_utrace = 0; break;
527 case 'U': malloc_utrace = 1; break;
528#endif /* __FreeBSD__ */
529 case 'x': malloc_xmalloc = 0; break;
530 case 'X': malloc_xmalloc = 1; break;
531 case 'z': malloc_zero = 0; break;
532 case 'Z': malloc_zero = 1; break;
533 default:
534 j = malloc_abort;
535 malloc_abort = 0;
536 wrtwarning("unknown char in MALLOC_OPTIONS\n");
537 malloc_abort = j;
538 break;
539 }
540 }
541 }
542
543 UTRACE(0, 0, 0);
544
545 /*
546 * We want junk in the entire allocation, and zero only in the part
547 * the user asked for.
548 */
549 if (malloc_zero)
550 malloc_junk=1;
551
552#ifdef MALLOC_STATS
553 if (malloc_stats && (atexit(malloc_exit) == -1))
554 wrtwarning("atexit(2) failed. Will not be able to dump malloc stats on exit\n");
555#endif /* MALLOC_STATS */
556
557 /* Allocate one page for the page directory */
558 page_dir = (struct pginfo **) MMAP(malloc_pagesize);
559
560 if (page_dir == MAP_FAILED)
561 wrterror("mmap(2) failed, check limits\n");
562
563 /*
564 * We need a maximum of malloc_pageshift buckets, steal these from the
565 * front of the page_directory;
566 */
567 malloc_origo = ((u_long)pageround((u_long)sbrk(0))) >> malloc_pageshift;
568 malloc_origo -= malloc_pageshift;
569
570 malloc_ninfo = malloc_pagesize / sizeof *page_dir;
571
572 /* Been here, done that */
573 malloc_started++;
574
575 /* Recalculate the cache size in bytes, and make sure it's nonzero */
576
577 if (!malloc_cache)
578 malloc_cache++;
579
580 malloc_cache <<= malloc_pageshift;
581
582 /*
583 * This is a nice hack from Kaleb Keithly (kaleb@x.org).
584 * We can sbrk(2) further back when we keep this on a low address.
585 */
586 px = (struct pgfree *) imalloc (sizeof *px);
587 errno = save_errno;
588}
589
590/*
591 * Allocate a number of complete pages
592 */
593static void *
594malloc_pages(size_t size)
595{
596 void *p, *delay_free = NULL;
597 int i;
598 struct pgfree *pf;
599 u_long index;
600
601 size = pageround(size) + malloc_guard;
602
603 p = NULL;
604 /* Look for free pages before asking for more */
605 for(pf = free_list.next; pf; pf = pf->next) {
606
607#ifdef MALLOC_EXTRA_SANITY
608 if (pf->size & malloc_pagemask)
609 wrterror("(ES): junk length entry on free_list\n");
610 if (!pf->size)
611 wrterror("(ES): zero length entry on free_list\n");
612 if (pf->page == pf->end)
613 wrterror("(ES): zero entry on free_list\n");
614 if (pf->page > pf->end)
615 wrterror("(ES): sick entry on free_list\n");
616 if ((void*)pf->page >= (void*)sbrk(0))
617 wrterror("(ES): entry on free_list past brk\n");
618 if (page_dir[ptr2index(pf->page)] != MALLOC_FREE)
619 wrterror("(ES): non-free first page on free-list\n");
620 if (page_dir[ptr2index(pf->end)-1] != MALLOC_FREE)
621 wrterror("(ES): non-free last page on free-list\n");
622#endif /* MALLOC_EXTRA_SANITY */
623
624 if (pf->size < size)
625 continue;
626
627 if (pf->size == size) {
628 p = pf->page;
629 if (pf->next != NULL)
630 pf->next->prev = pf->prev;
631 pf->prev->next = pf->next;
632 delay_free = pf;
633 break;
634 }
635
636 p = pf->page;
637 pf->page = (char *)pf->page + size;
638 pf->size -= size;
639 break;
640 }
641
642 size -= malloc_guard;
643
644#ifdef MALLOC_EXTRA_SANITY
645 if (p != NULL && page_dir[ptr2index(p)] != MALLOC_FREE)
646 wrterror("(ES): allocated non-free page on free-list\n");
647#endif /* MALLOC_EXTRA_SANITY */
648
649 if ((malloc_guard || malloc_freeprot) && p != NULL)
650 mprotect(p, size, PROT_READ|PROT_WRITE);
651
652 size >>= malloc_pageshift;
653
654 /* Map new pages */
655 if (p == NULL)
656 p = map_pages(size);
657
658 if (p != NULL) {
659
660 index = ptr2index(p);
661 page_dir[index] = MALLOC_FIRST;
662 for (i=1;i<size;i++)
663 page_dir[index+i] = MALLOC_FOLLOW;
664
665 if (malloc_junk)
666 memset(p, SOME_JUNK, size << malloc_pageshift);
667 }
668
669 if (delay_free) {
670 if (px == NULL)
671 px = delay_free;
672 else
673 ifree(delay_free);
674 }
675
676 return (p);
677}
678
679/*
680 * Allocate a page of fragments
681 */
682
683static __inline__ int
684malloc_make_chunks(int bits)
685{
686 struct pginfo *bp;
687 void *pp;
688 int i, k, l;
689
690 /* Allocate a new bucket */
691 pp = malloc_pages((size_t)malloc_pagesize);
692 if (pp == NULL)
693 return (0);
694
695 /* Find length of admin structure */
696 l = sizeof *bp - sizeof(u_long);
697 l += sizeof(u_long) *
698 (((malloc_pagesize >> bits)+MALLOC_BITS-1) / MALLOC_BITS);
699
700 /* Don't waste more than two chunks on this */
701 /*
702 * If we are to allocate a memory protected page for the malloc(0)
703 * case (when bits=0), it must be from a different page than the
704 * pginfo page.
705 * --> Treat it like the big chunk alloc, get a second data page.
706 */
707 if (bits != 0 && (1UL<<(bits)) <= l+l) {
708 bp = (struct pginfo *)pp;
709 } else {
710 bp = (struct pginfo *)imalloc(l);
711 if (bp == NULL) {
712 ifree(pp);
713 return (0);
714 }
715 }
716
717 /* memory protect the page allocated in the malloc(0) case */
718 if (bits == 0) {
719
720 bp->size = 0;
721 bp->shift = 1;
722 i = malloc_minsize-1;
723 while (i >>= 1)
724 bp->shift++;
725 bp->total = bp->free = malloc_pagesize >> bp->shift;
726 bp->page = pp;
727
728 k = mprotect(pp, malloc_pagesize, PROT_NONE);
729 if (k < 0) {
730 ifree(pp);
731 ifree(bp);
732 return (0);
733 }
734 } else {
735 bp->size = (1UL<<bits);
736 bp->shift = bits;
737 bp->total = bp->free = malloc_pagesize >> bits;
738 bp->page = pp;
739 }
740
741 /* set all valid bits in the bitmap */
742 k = bp->total;
743 i = 0;
744
745 /* Do a bunch at a time */
746 for(;k-i >= MALLOC_BITS; i += MALLOC_BITS)
747 bp->bits[i / MALLOC_BITS] = ~0UL;
748
749 for(; i < k; i++)
750 bp->bits[i/MALLOC_BITS] |= 1UL<<(i%MALLOC_BITS);
751
752 if (bp == bp->page) {
753 /* Mark the ones we stole for ourselves */
754 for(i=0;l > 0;i++) {
755 bp->bits[i/MALLOC_BITS] &= ~(1UL<<(i%MALLOC_BITS));
756 bp->free--;
757 bp->total--;
758 l -= (1 << bits);
759 }
760 }
761
762 /* MALLOC_LOCK */
763
764 page_dir[ptr2index(pp)] = bp;
765
766 bp->next = page_dir[bits];
767 page_dir[bits] = bp;
768
769 /* MALLOC_UNLOCK */
770
771 return (1);
772}
773
774/*
775 * Allocate a fragment
776 */
777static void *
778malloc_bytes(size_t size)
779{
780 int i,j;
781 u_long u;
782 struct pginfo *bp;
783 int k;
784 u_long *lp;
785
786 /* Don't bother with anything less than this */
787 /* unless we have a malloc(0) requests */
788 if (size != 0 && size < malloc_minsize)
789 size = malloc_minsize;
790
791 /* Find the right bucket */
792 if (size == 0)
793 j=0;
794 else {
795 j = 1;
796 i = size-1;
797 while (i >>= 1)
798 j++;
799 }
800
801 /* If it's empty, make a page more of that size chunks */
802 if (page_dir[j] == NULL && !malloc_make_chunks(j))
803 return (NULL);
804
805 bp = page_dir[j];
806
807 /* Find first word of bitmap which isn't empty */
808 for (lp = bp->bits; !*lp; lp++)
809 ;
810
811 /* Find that bit, and tweak it */
812 u = 1;
813 k = 0;
814 while (!(*lp & u)) {
815 u += u;
816 k++;
817 }
818
819 if (malloc_guard) {
820 /* Walk to a random position. */
821 i = arc4random() % bp->free;
822 while (i > 0) {
823 u += u;
824 k++;
825 if (k >= MALLOC_BITS) {
826 lp++;
827 u = 1;
828 k = 0;
829 }
830#ifdef MALLOC_EXTRA_SANITY
831 if (lp - bp->bits > (bp->total - 1) / MALLOC_BITS)
832 wrterror("chunk overflow\n");
833#endif /* MALLOC_EXTRA_SANITY */
834 if (*lp & u)
835 i--;
836 }
837 }
838 *lp ^= u;
839
840 /* If there are no more free, remove from free-list */
841 if (!--bp->free) {
842 page_dir[j] = bp->next;
843 bp->next = NULL;
844 }
845
846 /* Adjust to the real offset of that chunk */
847 k += (lp-bp->bits)*MALLOC_BITS;
848 k <<= bp->shift;
849
850 if (malloc_junk && bp->size != 0)
851 memset((char *)bp->page + k, SOME_JUNK, bp->size);
852
853 return ((u_char *)bp->page + k);
854}
855
856/*
857 * Allocate a piece of memory
858 */
859static void *
860imalloc(size_t size)
861{
862 void *result;
863
864 if (!malloc_started)
865 malloc_init();
866
867 if (suicide)
125 abort(); 868 abort();
869
870 if ((size + malloc_pagesize) < size) { /* Check for overflow */
871 result = NULL;
872 errno = ENOMEM;
873 }
874 else if (size <= malloc_maxsize)
875 result = malloc_bytes(size);
876 else
877 result = malloc_pages(size);
878
879 if (malloc_abort == 1 && result == NULL)
880 wrterror("allocation failed\n");
881
882 if (malloc_zero && result != NULL)
883 memset(result, 0, size);
884
885 return (result);
126} 886}
127#else
128#define ASSERT(p)
129#endif
130 887
131void * 888/*
132malloc(nbytes) 889 * Change the size of an allocation.
133 size_t nbytes; 890 */
891static void *
892irealloc(void *ptr, size_t size)
134{ 893{
135 register union overhead *op; 894 void *p;
136 register long bucket, n; 895 u_long osize, index;
137 register unsigned amt; 896 struct pginfo **mp;
897 int i;
138 898
139 /* 899 if (suicide)
140 * First time malloc is called, setup page size and 900 abort();
141 * align break pointer so all data will be page aligned. 901
142 */ 902 if (!malloc_started) {
143 if (pagesz == 0) { 903 wrtwarning("malloc() has never been called\n");
144 pagesz = n = getpagesize(); 904 return (NULL);
145 op = (union overhead *)sbrk(0); 905 }
146 n = n - sizeof (*op) - ((long)op & (n - 1)); 906
147 if (n < 0) 907 index = ptr2index(ptr);
148 n += pagesz; 908
149 if (n) { 909 if (index < malloc_pageshift) {
150 if (sbrk(n) == (char *)-1) 910 wrtwarning("junk pointer, too low to make sense\n");
151 return (NULL); 911 return (NULL);
152 } 912 }
153 bucket = 0; 913
154 amt = 8; 914 if (index > last_index) {
155 while (pagesz > amt) { 915 wrtwarning("junk pointer, too high to make sense\n");
156 amt <<= 1; 916 return (NULL);
157 bucket++; 917 }
158 } 918
159 pagebucket = bucket; 919 mp = &page_dir[index];
920
921 if (*mp == MALLOC_FIRST) { /* Page allocation */
922
923 /* Check the pointer */
924 if ((u_long)ptr & malloc_pagemask) {
925 wrtwarning("modified (page-) pointer\n");
926 return (NULL);
160 } 927 }
161 /* 928
162 * Convert amount of memory requested into closest block size 929 /* Find the size in bytes */
163 * stored in hash buckets which satisfies request. 930 for (osize = malloc_pagesize; *(++mp) == MALLOC_FOLLOW;)
164 * Account for space used per block for accounting. 931 osize += malloc_pagesize;
165 */ 932
166 if (nbytes <= (n = pagesz - sizeof (*op) - RSLOP)) { 933 if (!malloc_realloc && /* Unless we have to, */
167#ifndef RCHECK 934 size <= osize && /* .. or are too small, */
168 amt = 8; /* size of first bucket */ 935 size > (osize - malloc_pagesize)) { /* .. or can free a page, */
169 bucket = 0; 936 if (malloc_junk)
170#else 937 memset((char *)ptr + size, SOME_JUNK, osize-size);
171 amt = 16; /* size of first bucket */ 938 return (ptr); /* ..don't do anything else. */
172 bucket = 1;
173#endif
174 n = -((long)sizeof (*op) + RSLOP);
175 } else {
176 amt = pagesz;
177 bucket = pagebucket;
178 } 939 }
179 while (nbytes > amt + n) { 940
180 amt <<= 1; 941 } else if (*mp >= MALLOC_MAGIC) { /* Chunk allocation */
181 if (amt == 0) 942
182 return (NULL); 943 /* Check the pointer for sane values */
183 bucket++; 944 if ((u_long)ptr & ((1UL<<((*mp)->shift))-1)) {
945 wrtwarning("modified (chunk-) pointer\n");
946 return (NULL);
184 } 947 }
185 /* 948
186 * If nothing in hash bucket right now, 949 /* Find the chunk index in the page */
187 * request more memory from the system. 950 i = ((u_long)ptr & malloc_pagemask) >> (*mp)->shift;
188 */ 951
189 if ((op = nextf[bucket]) == NULL) { 952 /* Verify that it isn't a free chunk already */
190 morecore(bucket); 953 if ((*mp)->bits[i/MALLOC_BITS] & (1UL<<(i%MALLOC_BITS))) {
191 if ((op = nextf[bucket]) == NULL) 954 wrtwarning("chunk is already free\n");
192 return (NULL); 955 return (NULL);
193 } 956 }
194 /* remove from linked list */ 957
195 nextf[bucket] = op->ov_next; 958 osize = (*mp)->size;
196 op->ov_magic = MAGIC; 959
197 op->ov_index = bucket; 960 if (!malloc_realloc && /* Unless we have to, */
198#ifdef MSTATS 961 size <= osize && /* ..or are too small, */
199 nmalloc[bucket]++; 962 (size > osize/2 || /* ..or could use a smaller size, */
200#endif 963 osize == malloc_minsize)) { /* ..(if there is one) */
201#ifdef RCHECK 964 if (malloc_junk)
202 /* 965 memset((char *)ptr + size, SOME_JUNK, osize-size);
203 * Record allocated size of block and 966 return (ptr); /* ..don't do anything else. */
204 * bound space with magic numbers. 967 }
205 */ 968
206 op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1); 969 } else {
207 op->ov_rmagic = RMAGIC; 970 wrtwarning("pointer to wrong page\n");
208 *(u_short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC; 971 return (NULL);
209#endif 972 }
210 return ((char *)(op + 1)); 973
974 p = imalloc(size);
975
976 if (p != NULL) {
977 /* copy the lesser of the two sizes, and free the old one */
978 /* Don't move from/to 0 sized region !!! */
979 if (osize != 0 && size != 0) {
980 if (osize < size)
981 memcpy(p, ptr, osize);
982 else
983 memcpy(p, ptr, size);
984 }
985 ifree(ptr);
986 }
987 return (p);
211} 988}
212 989
213/* 990/*
214 * Allocate more memory to the indicated bucket. 991 * Free a sequence of pages
215 */ 992 */
216static void 993
217morecore(bucket) 994static __inline__ void
218 int bucket; 995free_pages(void *ptr, u_long index, struct pginfo *info)
219{ 996{
220 register union overhead *op; 997 u_long i, l;
221 register long sz; /* size of desired block */ 998 struct pgfree *pf, *pt=NULL;
222 long amt; /* amount to allocate */ 999 void *tail;
223 int nblks; /* how many blocks we get */
224 1000
225 /* 1001 if (info == MALLOC_FREE) {
226 * sbrk_size <= 0 only for big, FLUFFY, requests (about 1002 wrtwarning("page is already free\n");
227 * 2^30 bytes on a VAX, I think) or for a negative arg. 1003 return;
228 */ 1004 }
229 sz = 1 << (bucket + 3); 1005
230#ifdef DEBUG 1006 if (info != MALLOC_FIRST) {
231 ASSERT(sz > 0); 1007 wrtwarning("pointer to wrong page\n");
232#else 1008 return;
233 if (sz <= 0) 1009 }
234 return; 1010
1011 if ((u_long)ptr & malloc_pagemask) {
1012 wrtwarning("modified (page-) pointer\n");
1013 return;
1014 }
1015
1016 /* Count how many pages and mark them free at the same time */
1017 page_dir[index] = MALLOC_FREE;
1018 for (i = 1; page_dir[index+i] == MALLOC_FOLLOW; i++)
1019 page_dir[index + i] = MALLOC_FREE;
1020
1021 l = i << malloc_pageshift;
1022
1023 if (malloc_junk)
1024 memset(ptr, SOME_JUNK, l);
1025
1026#if defined(__FreeBSD__) || (defined(__OpenBSD__) && defined(MADV_FREE))
1027 if (malloc_hint)
1028 madvise(ptr, l, MADV_FREE);
235#endif 1029#endif
236 if (sz < pagesz) { 1030
237 amt = pagesz; 1031 if (malloc_guard) {
238 nblks = amt / sz; 1032 page_dir[index + i] = MALLOC_FREE;
1033 l += malloc_guard;
1034 }
1035 tail = (char *)ptr+l;
1036
1037 if (malloc_freeprot)
1038 mprotect(ptr, tail - ptr, PROT_NONE);
1039
1040 /* add to free-list */
1041 if (px == NULL)
1042 px = imalloc(sizeof *px); /* This cannot fail... */
1043 px->page = ptr;
1044 px->end = tail;
1045 px->size = l;
1046
1047 if (free_list.next == NULL) {
1048
1049 /* Nothing on free list, put this at head */
1050 px->next = free_list.next;
1051 px->prev = &free_list;
1052 free_list.next = px;
1053 pf = px;
1054 px = NULL;
1055
1056 } else {
1057
1058 /* Find the right spot, leave pf pointing to the modified entry. */
1059
1060 for(pf = free_list.next; pf->end < ptr && pf->next != NULL;
1061 pf = pf->next)
1062 ; /* Race ahead here */
1063
1064 if (pf->page > tail) {
1065 /* Insert before entry */
1066 px->next = pf;
1067 px->prev = pf->prev;
1068 pf->prev = px;
1069 px->prev->next = px;
1070 pf = px;
1071 px = NULL;
1072 } else if (pf->end == ptr ) {
1073 /* Append to the previous entry */
1074 pf->end = (char *)pf->end + l;
1075 pf->size += l;
1076 if (pf->next != NULL && pf->end == pf->next->page ) {
1077 /* And collapse the next too. */
1078 pt = pf->next;
1079 pf->end = pt->end;
1080 pf->size += pt->size;
1081 pf->next = pt->next;
1082 if (pf->next != NULL)
1083 pf->next->prev = pf;
1084 }
1085 } else if (pf->page == tail) {
1086 /* Prepend to entry */
1087 pf->size += l;
1088 pf->page = ptr;
1089 } else if (pf->next == NULL) {
1090 /* Append at tail of chain */
1091 px->next = NULL;
1092 px->prev = pf;
1093 pf->next = px;
1094 pf = px;
1095 px = NULL;
239 } else { 1096 } else {
240 amt = sz + pagesz; 1097 wrterror("freelist is destroyed\n");
241 nblks = 1;
242 } 1098 }
243 op = (union overhead *)sbrk(amt); 1099 }
244 /* no more room! */ 1100
245 if ((long)op == -1) 1101 /* Return something to OS ? */
246 return; 1102 if (pf->next == NULL && /* If we're the last one, */
1103 pf->size > malloc_cache && /* ..and the cache is full, */
1104 pf->end == malloc_brk && /* ..and none behind us, */
1105 malloc_brk == sbrk(0)) { /* ..and it's OK to do... */
1106
247 /* 1107 /*
248 * Add new memory allocated to that on 1108 * Keep the cache intact. Notice that the '>' above guarantees that
249 * free list for this hash bucket. 1109 * the pf will always have at least one page afterwards.
250 */ 1110 */
251 nextf[bucket] = op; 1111 pf->end = (char *)pf->page + malloc_cache;
252 while (--nblks > 0) { 1112 pf->size = malloc_cache;
253 op->ov_next = (union overhead *)((caddr_t)op + sz);
254 op = (union overhead *)((caddr_t)op + sz);
255 }
256}
257 1113
258void 1114 brk(pf->end);
259free(cp) 1115 malloc_brk = pf->end;
260 void *cp; 1116
261{ 1117 index = ptr2index(pf->end);
262 register long size; 1118
263 register union overhead *op; 1119 for(i=index;i <= last_index;)
264 1120 page_dir[i++] = MALLOC_NOT_MINE;
265 if (cp == NULL) 1121
266 return; 1122 last_index = index - 1;
267 op = (union overhead *)((caddr_t)cp - sizeof (union overhead)); 1123
268#ifdef DEBUG 1124 /* XXX: We could realloc/shrink the pagedir here I guess. */
269 ASSERT(op->ov_magic == MAGIC); /* make sure it was in use */ 1125 }
270#else 1126 if (pt != NULL)
271 if (op->ov_magic != MAGIC) 1127 ifree(pt);
272 return; /* sanity */
273#endif
274#ifdef RCHECK
275 ASSERT(op->ov_rmagic == RMAGIC);
276 ASSERT(*(u_short *)((caddr_t)(op + 1) + op->ov_size) == RMAGIC);
277#endif
278 size = op->ov_index;
279 ASSERT(size < NBUCKETS);
280 op->ov_next = nextf[size]; /* also clobbers ov_magic */
281 nextf[size] = op;
282#ifdef MSTATS
283 nmalloc[size]--;
284#endif
285} 1128}
286 1129
287/* 1130/*
288 * When a program attempts "storage compaction" as mentioned in the 1131 * Free a chunk, and possibly the page it's on, if the page becomes empty.
289 * old malloc man page, it realloc's an already freed block. Usually
290 * this is the last block it freed; occasionally it might be farther
291 * back. We have to search all the free lists for the block in order
292 * to determine its bucket: 1st we make one pass thru the lists
293 * checking only the first block in each; if that fails we search
294 * ``realloc_srchlen'' blocks in each list for a match (the variable
295 * is extern so the caller can modify it). If that fails we just copy
296 * however many bytes was given to realloc() and hope it's not huge.
297 */ 1132 */
298int realloc_srchlen = 4; /* 4 should be plenty, -1 =>'s whole list */
299 1133
300void * 1134/* ARGSUSED */
301realloc(cp, nbytes) 1135static __inline__ void
302 void *cp; 1136free_bytes(void *ptr, int index, struct pginfo *info)
303 size_t nbytes; 1137{
304{ 1138 int i;
305 register u_long onb; 1139 struct pginfo **mp;
306 register long i; 1140 void *vp;
307 union overhead *op; 1141
308 char *res; 1142 /* Find the chunk number on the page */
309 int was_alloced = 0; 1143 i = ((u_long)ptr & malloc_pagemask) >> info->shift;
310 1144
311 if (cp == NULL) 1145 if ((u_long)ptr & ((1UL<<(info->shift))-1)) {
312 return (malloc(nbytes)); 1146 wrtwarning("modified (chunk-) pointer\n");
313 op = (union overhead *)((caddr_t)cp - sizeof (union overhead)); 1147 return;
314 if (op->ov_magic == MAGIC) { 1148 }
315 was_alloced++; 1149
316 i = op->ov_index; 1150 if (info->bits[i/MALLOC_BITS] & (1UL<<(i%MALLOC_BITS))) {
317 } else { 1151 wrtwarning("chunk is already free\n");
318 /* 1152 return;
319 * Already free, doing "compaction". 1153 }
320 * 1154
321 * Search for the old block of memory on the 1155 if (malloc_junk && info->size != 0)
322 * free list. First, check the most common 1156 memset(ptr, SOME_JUNK, info->size);
323 * case (last element free'd), then (this failing) 1157
324 * the last ``realloc_srchlen'' items free'd. 1158 info->bits[i/MALLOC_BITS] |= 1UL<<(i%MALLOC_BITS);
325 * If all lookups fail, then assume the size of 1159 info->free++;
326 * the memory block being realloc'd is the 1160
327 * largest possible (so that all "nbytes" of new 1161 if (info->size != 0)
328 * memory are copied into). Note that this could cause 1162 mp = page_dir + info->shift;
329 * a memory fault if the old area was tiny, and the moon 1163 else
330 * is gibbous. However, that is very unlikely. 1164 mp = page_dir;
331 */ 1165
332 if ((i = findbucket(op, 1)) < 0 && 1166 if (info->free == 1) {
333 (i = findbucket(op, realloc_srchlen)) < 0) 1167
334 i = NBUCKETS; 1168 /* Page became non-full */
335 } 1169
336 onb = 1 << (i + 3); 1170 /* Insert in address order */
337 if (onb < pagesz) 1171 while (*mp && (*mp)->next && (*mp)->next->page < info->page)
338 onb -= sizeof (*op) + RSLOP; 1172 mp = &(*mp)->next;
339 else 1173 info->next = *mp;
340 onb += pagesz - sizeof (*op) - RSLOP; 1174 *mp = info;
341 /* avoid the copy if same size block */ 1175 return;
342 if (was_alloced) { 1176 }
343 if (i) { 1177
344 i = 1 << (i + 2); 1178 if (info->free != info->total)
345 if (i < pagesz) 1179 return;
346 i -= sizeof (*op) + RSLOP; 1180
347 else 1181 /* Find & remove this page in the queue */
348 i += pagesz - sizeof (*op) - RSLOP; 1182 while (*mp != info) {
349 } 1183 mp = &((*mp)->next);
350 if (nbytes <= onb && nbytes > i) { 1184#ifdef MALLOC_EXTRA_SANITY
351#ifdef RCHECK 1185 if (!*mp)
352 op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1); 1186 wrterror("(ES): Not on queue\n");
353 *(u_short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC; 1187#endif /* MALLOC_EXTRA_SANITY */
354#endif 1188 }
355 return(cp); 1189 *mp = info->next;
356 } else 1190
357 free(cp); 1191 /* Free the page & the info structure if need be */
358 } 1192 page_dir[ptr2index(info->page)] = MALLOC_FIRST;
359 if ((res = malloc(nbytes)) == NULL) 1193
360 return (NULL); 1194 /* If the page was mprotected, unprotect it before releasing it */
361 if (cp != res) /* common optimization if "compacting" */ 1195 if (info->size == 0) {
362 bcopy(cp, res, (nbytes < onb) ? nbytes : onb); 1196 mprotect(info->page, malloc_pagesize, PROT_READ|PROT_WRITE);
363 return (res); 1197 /* Do we have to care if mprotect succeeds here ? */
1198 }
1199
1200 vp = info->page; /* Order is important ! */
1201 if(vp != (void*)info)
1202 ifree(info);
1203 ifree(vp);
1204}
1205
1206static void
1207ifree(void *ptr)
1208{
1209 struct pginfo *info;
1210 u_long index;
1211
1212 /* This is legal */
1213 if (ptr == NULL)
1214 return;
1215
1216 if (!malloc_started) {
1217 wrtwarning("malloc() has never been called\n");
1218 return;
1219 }
1220
1221 /* If we're already sinking, don't make matters any worse. */
1222 if (suicide)
1223 return;
1224
1225 index = ptr2index(ptr);
1226
1227 if (index < malloc_pageshift) {
1228 wrtwarning("junk pointer, too low to make sense\n");
1229 return;
1230 }
1231
1232 if (index > last_index) {
1233 wrtwarning("junk pointer, too high to make sense\n");
1234 return;
1235 }
1236
1237 info = page_dir[index];
1238
1239 if (info < MALLOC_MAGIC)
1240 free_pages(ptr, index, info);
1241 else
1242 free_bytes(ptr, index, info);
1243 return;
364} 1244}
365 1245
1246static int malloc_active;
1247
366/* 1248/*
367 * Search ``srchlen'' elements of each free list for a block whose 1249 * Common function for handling recursion. Only
368 * header starts at ``freep''. If srchlen is -1 search the whole list. 1250 * print the error message once, to avoid making the problem
369 * Return bucket number, or -1 if not found. 1251 * potentially worse.
370 */ 1252 */
371static 1253static void
372findbucket(freep, srchlen) 1254malloc_recurse(void)
373 union overhead *freep;
374 int srchlen;
375{ 1255{
376 register union overhead *p; 1256 static int noprint;
377 register int i, j; 1257
378 1258 if (noprint == 0)
379 for (i = 0; i < NBUCKETS; i++) { 1259 wrtwarning("recursive call\n");
380 j = 0; 1260 noprint = 1;
381 for (p = nextf[i]; p && j != srchlen; p = p->ov_next) { 1261 malloc_active--;
382 if (p == freep) 1262 _MALLOC_UNLOCK();
383 return (i); 1263 errno = EDEADLK;
384 j++;
385 }
386 }
387 return (-1);
388} 1264}
389 1265
390#ifdef MSTATS
391/* 1266/*
392 * mstats - print out statistics about malloc 1267 * These are the public exported interface routines.
393 *
394 * Prints two lines of numbers, one showing the length of the free list
395 * for each size category, the second showing the number of mallocs -
396 * frees for each size category.
397 */ 1268 */
398mstats(s) 1269void *
399 char *s; 1270malloc(size_t size)
400{ 1271{
401 register int i, j; 1272 void *r;
402 register union overhead *p; 1273
403 int totfree = 0, 1274 _MALLOC_LOCK();
404 totused = 0; 1275 malloc_func = " in malloc():";
405 1276 if (malloc_active++) {
406 fprintf(stderr, "Memory allocation statistics %s\nfree:\t", s); 1277 malloc_recurse();
407 for (i = 0; i < NBUCKETS; i++) { 1278 return (NULL);
408 for (j = 0, p = nextf[i]; p; p = p->ov_next, j++) 1279 }
409 ; 1280 r = imalloc(size);
410 fprintf(stderr, " %d", j); 1281 UTRACE(0, size, r);
411 totfree += j * (1 << (i + 3)); 1282 malloc_active--;
412 } 1283 _MALLOC_UNLOCK();
413 fprintf(stderr, "\nused:\t"); 1284 if (malloc_xmalloc && r == NULL)
414 for (i = 0; i < NBUCKETS; i++) { 1285 wrterror("out of memory\n");
415 fprintf(stderr, " %d", nmalloc[i]); 1286 return (r);
416 totused += nmalloc[i] * (1 << (i + 3)); 1287}
417 } 1288
418 fprintf(stderr, "\n\tTotal in use: %d, total free: %d\n", 1289void
419 totused, totfree); 1290free(void *ptr)
1291{
1292 _MALLOC_LOCK();
1293 malloc_func = " in free():";
1294 if (malloc_active++) {
1295 malloc_recurse();
1296 return;
1297 }
1298 ifree(ptr);
1299 UTRACE(ptr, 0, 0);
1300 malloc_active--;
1301 _MALLOC_UNLOCK();
1302 return;
1303}
1304
1305void *
1306realloc(void *ptr, size_t size)
1307{
1308 void *r;
1309
1310 _MALLOC_LOCK();
1311 malloc_func = " in realloc():";
1312 if (malloc_active++) {
1313 malloc_recurse();
1314 return (NULL);
1315 }
1316 if (ptr == NULL) {
1317 r = imalloc(size);
1318 } else {
1319 r = irealloc(ptr, size);
1320 }
1321 UTRACE(ptr, size, r);
1322 malloc_active--;
1323 _MALLOC_UNLOCK();
1324 if (malloc_xmalloc && r == NULL)
1325 wrterror("out of memory\n");
1326 return (r);
420} 1327}
421#endif
diff --git a/src/lib/libc/stdlib/memory.3 b/src/lib/libc/stdlib/memory.3
deleted file mode 100644
index 735252c837..0000000000
--- a/src/lib/libc/stdlib/memory.3
+++ /dev/null
@@ -1,71 +0,0 @@
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.\" from: @(#)memory.3 5.1 (Berkeley) 5/2/91
33.\" $Id: memory.3,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $
34.\"
35.Dd May 2, 1991
36.Dt MEMORY 3
37.Os BSD 4
38.Sh NAME
39.Nm malloc ,
40.Nm free ,
41.Nm realloc ,
42.Nm calloc ,
43.Nm alloca
44.Nd general memory allocation operations
45.Sh SYNOPSIS
46.Fd #include <stdlib.h>
47.Ft void *
48.Fn malloc "size_t size"
49.Ft void
50.Fn free "void *ptr"
51.Ft void *
52.Fn realloc "void *ptr" "size_t size"
53.Ft void *
54.Fn calloc "size_t nelem" "size_t elsize"
55.Ft void *
56.Fn alloca "size_t size"
57.Sh DESCRIPTION
58These functions allocate and free memory for the calling process.
59They are described in the
60individual manual pages.
61.Sh SEE ALSO
62.Xr calloc 3 ,
63.Xr free 3 ,
64.Xr malloc 3 ,
65.Xr realloc 3 ,
66.Xr alloca 3 ,
67.Sh STANDARDS
68These functions, with the exception of
69.Fn alloca
70conform to
71.St -ansiC .
diff --git a/src/lib/libc/stdlib/merge.c b/src/lib/libc/stdlib/merge.c
index 381fdc0830..1826acc369 100644
--- a/src/lib/libc/stdlib/merge.c
+++ b/src/lib/libc/stdlib/merge.c
@@ -13,11 +13,7 @@
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software 16 * 3. Neither the name of the University nor the names of its contributors
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 17 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission. 18 * without specific prior written permission.
23 * 19 *
@@ -35,8 +31,7 @@
35 */ 31 */
36 32
37#if defined(LIBC_SCCS) && !defined(lint) 33#if defined(LIBC_SCCS) && !defined(lint)
38/*static char sccsid[] = "from: @(#)merge.c 8.2 (Berkeley) 2/14/94";*/ 34static char *rcsid = "$OpenBSD: merge.c,v 1.6 2003/06/02 20:18:38 millert Exp $";
39static char *rcsid = "$Id: merge.c,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */ 35#endif /* LIBC_SCCS and not lint */
41 36
42/* 37/*
@@ -59,8 +54,8 @@ static char *rcsid = "$Id: merge.c,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $";
59#include <stdlib.h> 54#include <stdlib.h>
60#include <string.h> 55#include <string.h>
61 56
62static void setup __P((u_char *, u_char *, size_t, size_t, int (*)())); 57static void setup(u_char *, u_char *, size_t, size_t, int (*)());
63static void insertionsort __P((u_char *, size_t, size_t, int (*)())); 58static void insertionsort(u_char *, size_t, size_t, int (*)());
64 59
65#define ISIZE sizeof(int) 60#define ISIZE sizeof(int)
66#define PSIZE sizeof(u_char *) 61#define PSIZE sizeof(u_char *)
@@ -100,7 +95,7 @@ mergesort(base, nmemb, size, cmp)
100 void *base; 95 void *base;
101 size_t nmemb; 96 size_t nmemb;
102 register size_t size; 97 register size_t size;
103 int (*cmp) __P((const void *, const void *)); 98 int (*cmp)(const void *, const void *);
104{ 99{
105 register int i, sense; 100 register int i, sense;
106 int big, iflag; 101 int big, iflag;
@@ -148,7 +143,7 @@ mergesort(base, nmemb, size, cmp)
148 sense = 0; 143 sense = 0;
149 } 144 }
150 if (!big) { /* here i = 0 */ 145 if (!big) { /* here i = 0 */
151LINEAR: while ((b += size) < t && cmp(q, b) >sense) 146 while ((b += size) < t && cmp(q, b) >sense)
152 if (++i == 6) { 147 if (++i == 6) {
153 big = 1; 148 big = 1;
154 goto EXPONENTIAL; 149 goto EXPONENTIAL;
@@ -169,7 +164,7 @@ EXPONENTIAL: for (i = size; ; i <<= 1)
169 goto FASTCASE; 164 goto FASTCASE;
170 } else 165 } else
171 b = p; 166 b = p;
172SLOWCASE: while (t > b+size) { 167 while (t > b+size) {
173 i = (((t - b) / size) >> 1) * size; 168 i = (((t - b) / size) >> 1) * size;
174 if ((*cmp)(q, p = b + i) <= sense) 169 if ((*cmp)(q, p = b + i) <= sense)
175 t = p; 170 t = p;
@@ -258,7 +253,7 @@ COPY: b = t;
258void 253void
259setup(list1, list2, n, size, cmp) 254setup(list1, list2, n, size, cmp)
260 size_t n, size; 255 size_t n, size;
261 int (*cmp) __P((const void *, const void *)); 256 int (*cmp)(const void *, const void *);
262 u_char *list1, *list2; 257 u_char *list1, *list2;
263{ 258{
264 int i, length, size2, tmp, sense; 259 int i, length, size2, tmp, sense;
@@ -333,7 +328,7 @@ static void
333insertionsort(a, n, size, cmp) 328insertionsort(a, n, size, cmp)
334 u_char *a; 329 u_char *a;
335 size_t n, size; 330 size_t n, size;
336 int (*cmp) __P((const void *, const void *)); 331 int (*cmp)(const void *, const void *);
337{ 332{
338 u_char *ai, *s, *t, *u, tmp; 333 u_char *ai, *s, *t, *u, tmp;
339 int i; 334 int i;
diff --git a/src/lib/libc/stdlib/mrand48.c b/src/lib/libc/stdlib/mrand48.c
index 43356e66b3..cd34260b5c 100644
--- a/src/lib/libc/stdlib/mrand48.c
+++ b/src/lib/libc/stdlib/mrand48.c
@@ -11,6 +11,10 @@
11 * to anyone/anything when using this software. 11 * to anyone/anything when using this software.
12 */ 12 */
13 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
14#include "rand48.h" 18#include "rand48.h"
15 19
16extern unsigned short __rand48_seed[3]; 20extern unsigned short __rand48_seed[3];
diff --git a/src/lib/libc/stdlib/multibyte.c b/src/lib/libc/stdlib/multibyte.c
index fe1cd5781b..ba878b8fdc 100644
--- a/src/lib/libc/stdlib/multibyte.c
+++ b/src/lib/libc/stdlib/multibyte.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,8 +28,7 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)multibyte.c 5.1 (Berkeley) 2/18/91";*/ 31static char *rcsid = "$OpenBSD: multibyte.c,v 1.4 2003/06/02 20:18:38 millert Exp $";
36static char *rcsid = "$Id: multibyte.c,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
39#include <stdlib.h> 34#include <stdlib.h>
@@ -74,13 +69,7 @@ mbtowc(pwc, s, n)
74 69
75/*ARGSUSED*/ 70/*ARGSUSED*/
76int 71int
77#ifdef __STDC__
78wctomb(char *s, wchar_t wchar) 72wctomb(char *s, wchar_t wchar)
79#else
80wctomb(s, wchar)
81 char *s;
82 wchar_t wchar;
83#endif
84{ 73{
85 if (s == NULL) 74 if (s == NULL)
86 return 0; 75 return 0;
diff --git a/src/lib/libc/stdlib/nrand48.c b/src/lib/libc/stdlib/nrand48.c
index 63f839cb05..b1ec2cebb1 100644
--- a/src/lib/libc/stdlib/nrand48.c
+++ b/src/lib/libc/stdlib/nrand48.c
@@ -11,6 +11,10 @@
11 * to anyone/anything when using this software. 11 * to anyone/anything when using this software.
12 */ 12 */
13 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
14#include "rand48.h" 18#include "rand48.h"
15 19
16long 20long
diff --git a/src/lib/libc/stdlib/putenv.c b/src/lib/libc/stdlib/putenv.c
index 2194c2c608..1789e686ef 100644
--- a/src/lib/libc/stdlib/putenv.c
+++ b/src/lib/libc/stdlib/putenv.c
@@ -1,6 +1,6 @@
1/*- 1/*-
2 * Copyright (c) 1988 The Regents of the University of California. 2 * Copyright (c) 1988, 1993
3 * All rights reserved. 3 * The Regents of the University of California. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,8 +28,7 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)putenv.c 5.4 (Berkeley) 2/23/91";*/ 31static char *rcsid = "$OpenBSD: putenv.c,v 1.3 2003/06/02 20:18:38 millert Exp $";
36static char *rcsid = "$Id: putenv.c,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
39#include <stdlib.h> 34#include <stdlib.h>
@@ -43,17 +38,17 @@ int
43putenv(str) 38putenv(str)
44 const char *str; 39 const char *str;
45{ 40{
46 register char *p, *equal; 41 char *p, *equal;
47 int rval; 42 int rval;
48 43
49 if (!(p = strdup(str))) 44 if ((p = strdup(str)) == NULL)
50 return(1); 45 return (-1);
51 if (!(equal = strchr(p, '='))) { 46 if ((equal = strchr(p, '=')) == NULL) {
52 (void)free(p); 47 (void)free(p);
53 return(1); 48 return (-1);
54 } 49 }
55 *equal = '\0'; 50 *equal = '\0';
56 rval = setenv(p, equal + 1, 1); 51 rval = setenv(p, equal + 1, 1);
57 (void)free(p); 52 (void)free(p);
58 return(rval); 53 return (rval);
59} 54}
diff --git a/src/lib/libc/stdlib/qabs.3 b/src/lib/libc/stdlib/qabs.3
index cb1e052191..093212edf5 100644
--- a/src/lib/libc/stdlib/qabs.3
+++ b/src/lib/libc/stdlib/qabs.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,8 +29,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)labs.3 5.3 (Berkeley) 6/29/91 32.\" $OpenBSD: qabs.3,v 1.6 2003/06/02 20:18:38 millert Exp $
37.\" $Id: qabs.3,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd June 29, 1991
40.Dt QABS 3 35.Dt QABS 3
@@ -49,14 +44,13 @@
49.Sh DESCRIPTION 44.Sh DESCRIPTION
50The 45The
51.Fn qabs 46.Fn qabs
52function 47function returns the absolute value of the quad integer
53returns the absolute value of the quad integer 48.Fa j .
54.Ar j .
55.Sh SEE ALSO 49.Sh SEE ALSO
56.Xr abs 3 , 50.Xr abs 3 ,
57.Xr labs 3 ,
58.Xr floor 3 ,
59.Xr cabs 3 , 51.Xr cabs 3 ,
52.Xr floor 3 ,
53.Xr labs 3 ,
60.Xr math 3 54.Xr math 3
61.Sh BUGS 55.Sh BUGS
62The absolute value of the most negative integer remains negative. 56The 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
index 9c51a8baa9..296d2d4742 100644
--- a/src/lib/libc/stdlib/qabs.c
+++ b/src/lib/libc/stdlib/qabs.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,8 +28,7 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)labs.c 5.2 (Berkeley) 5/17/90";*/ 31static char *rcsid = "$OpenBSD: qabs.c,v 1.3 2003/06/02 20:18:38 millert Exp $";
36static char *rcsid = "$Id: qabs.c,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
39#include <stdlib.h> 34#include <stdlib.h>
diff --git a/src/lib/libc/stdlib/qdiv.3 b/src/lib/libc/stdlib/qdiv.3
index 0efcfc96ef..5f17ec17d4 100644
--- a/src/lib/libc/stdlib/qdiv.3
+++ b/src/lib/libc/stdlib/qdiv.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,8 +29,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)qdiv.3 5.3 (Berkeley) 6/29/91 32.\" $OpenBSD: qdiv.3,v 1.6 2004/01/23 23:08:46 jmc Exp $
37.\" $Id: qdiv.3,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd June 29, 1991
40.Dt QDIV 3 35.Dt QDIV 3
@@ -49,17 +44,16 @@
49.Sh DESCRIPTION 44.Sh DESCRIPTION
50The 45The
51.Fn qdiv 46.Fn qdiv
52function 47function computes the value
53computes the value 48.Fa num Ns / Ns Fa denom
54.Ar num/denom
55and returns the quotient and remainder in a structure named 49and returns the quotient and remainder in a structure named
56.Ar qdiv_t 50.Li qdiv_t
57that contains two 51that contains two
58.Em quad integer 52.Li quad integer
59members named 53members named
60.Ar quot 54.Fa quot
61and 55and
62.Ar rem . 56.Fa rem .
63.Sh SEE ALSO 57.Sh SEE ALSO
64.Xr div 3 , 58.Xr div 3 ,
65.Xr ldiv 3 , 59.Xr ldiv 3 ,
diff --git a/src/lib/libc/stdlib/qdiv.c b/src/lib/libc/stdlib/qdiv.c
index 8f8e3f89c4..6688ccb712 100644
--- a/src/lib/libc/stdlib/qdiv.c
+++ b/src/lib/libc/stdlib/qdiv.c
@@ -13,11 +13,7 @@
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software 16 * 3. Neither the name of the University nor the names of its contributors
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 17 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission. 18 * without specific prior written permission.
23 * 19 *
@@ -35,8 +31,7 @@
35 */ 31 */
36 32
37#if defined(LIBC_SCCS) && !defined(lint) 33#if defined(LIBC_SCCS) && !defined(lint)
38/*static char *sccsid = "from: @(#)ldiv.c 5.2 (Berkeley) 4/16/91";*/ 34static char *rcsid = "$OpenBSD: qdiv.c,v 1.3 2003/06/02 20:18:38 millert Exp $";
39static char *rcsid = "$Id: qdiv.c,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */ 35#endif /* LIBC_SCCS and not lint */
41 36
42#include <stdlib.h> /* qdiv_t */ 37#include <stdlib.h> /* qdiv_t */
diff --git a/src/lib/libc/stdlib/qsort.3 b/src/lib/libc/stdlib/qsort.3
index eb122cde12..668ea90243 100644
--- a/src/lib/libc/stdlib/qsort.3
+++ b/src/lib/libc/stdlib/qsort.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,14 +29,15 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)qsort.3 8.1 (Berkeley) 6/4/93 32.\" $OpenBSD: qsort.3,v 1.14 2003/10/01 08:11:58 jmc Exp $
37.\" $Id: qsort.3,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $
38.\" 33.\"
39.Dd June 4, 1993 34.Dd June 4, 1993
40.Dt QSORT 3 35.Dt QSORT 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
43.Nm qsort, heapsort, mergesort 38.Nm qsort ,
39.Nm heapsort ,
40.Nm mergesort
44.Nd sort functions 41.Nd sort functions
45.Sh SYNOPSIS 42.Sh SYNOPSIS
46.Fd #include <stdlib.h> 43.Fd #include <stdlib.h>
@@ -72,7 +69,7 @@ objects, the initial member of which is pointed to by
72.Fa base . 69.Fa base .
73The size of each object is specified by 70The size of each object is specified by
74.Fa size . 71.Fa size .
75.Fn Mergesort 72.Fn mergesort
76behaves similarly, but 73behaves similarly, but
77.Em requires 74.Em requires
78that 75that
@@ -106,51 +103,49 @@ is stable.
106.Pp 103.Pp
107The 104The
108.Fn qsort 105.Fn qsort
109function is an implementation of C.A.R. Hoare's ``quicksort'' algorithm, 106function is an implementation of C.A.R. Hoare's
107.Dq quicksort
108algorithm,
110a variant of partition-exchange sorting; in particular, see D.E. Knuth's 109a variant of partition-exchange sorting; in particular, see D.E. Knuth's
111Algorithm Q. 110Algorithm Q.
112.Fn Qsort 111.Fn qsort
113takes O N lg N average time. 112takes O N lg N average time.
114This implementation uses median selection to avoid its 113This implementation uses median selection to avoid its
115O N**2 worst-case behavior. 114O N**2 worst-case behavior.
116.Pp 115.Pp
117The 116The
118.Fn heapsort 117.Fn heapsort
119function is an implementation of J.W.J. William's ``heapsort'' algorithm, 118function is an implementation of J.W.J. William's
119.Dq heapsort
120algorithm,
120a variant of selection sorting; in particular, see D.E. Knuth's Algorithm H. 121a variant of selection sorting; in particular, see D.E. Knuth's Algorithm H.
121.Fn Heapsort 122.Fn heapsort
122takes O N lg N worst-case time. 123takes O N lg N worst-case time.
123Its 124This implementation of
124.Em only 125.Fn heapsort
125advantage over 126is implemented without recursive function calls.
126.Fn qsort
127is that it uses almost no additional memory; while
128.Fn qsort
129does not allocate memory, it is implemented using recursion.
130.Pp 127.Pp
131The function 128The function
132.Fn mergesort 129.Fn mergesort
133requires additional memory of size 130requires additional memory of size
134.Fa nmemb * 131.Fa nmemb *
135.Fa size 132.Fa size
136bytes; it should be used only when space is not at a premium. 133bytes; it should be used only when space is not at a premium.
137.Fn Mergesort 134.Fn mergesort
138is optimized for data with pre-existing order; its worst case 135is optimized for data with pre-existing order; its worst case
139time is O N lg N; its best case is O N. 136time is O N lg N; its best case is O N.
140.Pp 137.Pp
141Normally, 138Normally,
142.Fn qsort 139.Fn qsort
143is faster than 140is faster than
144.Fn mergesort 141.Fn mergesort ,
145is faster than 142which is faster than
146.Fn heapsort . 143.Fn heapsort .
147Memory availability and pre-existing order in the data can make this 144Memory availability and pre-existing order in the data can make this untrue.
148untrue.
149.Sh RETURN VALUES 145.Sh RETURN VALUES
150The 146The
151.Fn qsort 147.Fn qsort
152function 148function returns no value.
153returns no value.
154.Pp 149.Pp
155Upon successful completion, 150Upon successful completion,
156.Fn heapsort 151.Fn heapsort
@@ -163,30 +158,25 @@ is set to indicate the error.
163.Sh ERRORS 158.Sh ERRORS
164The 159The
165.Fn heapsort 160.Fn heapsort
166function succeeds unless: 161and
162.Fn mergesort
163functions succeed unless:
167.Bl -tag -width Er 164.Bl -tag -width Er
168.It Bq Er EINVAL 165.It Bq Er EINVAL
169The 166The
170.Fa size 167.Fa size
171argument is zero, or, 168argument is zero, or the
172the
173.Fa size 169.Fa size
174argument to 170argument to
175.Fn mergesort 171.Fn mergesort
176is less than 172is less than
177.Dq "sizeof(void *) / 2" . 173.Dq "sizeof(void *) / 2" .
178.It Bq Er ENOMEM 174.It Bq Er ENOMEM
179.Fn Heapsort 175.Fn heapsort
180or 176or
181.Fn mergesort 177.Fn mergesort
182were unable to allocate memory. 178were unable to allocate memory.
183.El 179.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 180.Sh SEE ALSO
191.Xr sort 1 , 181.Xr sort 1 ,
192.Xr radixsort 3 182.Xr radixsort 3
@@ -204,7 +194,7 @@ This is no longer true.
204.%T "Heapsort" 194.%T "Heapsort"
205.%J "Communications of the ACM" 195.%J "Communications of the ACM"
206.%V 7:1 196.%V 7:1
207.%P pp. 347-348 197.%P pp. 347\-348
208.Re 198.Re
209.Rs 199.Rs
210.%A Knuth, D.E. 200.%A Knuth, D.E.
@@ -212,23 +202,32 @@ This is no longer true.
212.%B "The Art of Computer Programming" 202.%B "The Art of Computer Programming"
213.%V Vol. 3 203.%V Vol. 3
214.%T "Sorting and Searching" 204.%T "Sorting and Searching"
215.%P pp. 114-123, 145-149 205.%P pp. 114\-123, 145\-149
216.Re 206.Re
217.Rs 207.Rs
218.%A Mcilroy, P.M. 208.%A McIlroy, P.M.
219.%T "Optimistic Sorting and Information Theoretic Complexity" 209.%T "Optimistic Sorting and Information Theoretic Complexity"
220.%J "Fourth Annual ACM-SIAM Symposium on Discrete Algorithms" 210.%J "Fourth Annual ACM-SIAM Symposium on Discrete Algorithms"
221.%V January 1992 211.%P pp. 467\-464
212.%D January 1993
222.Re 213.Re
223.Rs 214.Rs
224.%A Bentley, J.L. 215.%A Bentley, J.L.
216.%A McIlroy, M.D.
225.%T "Engineering a Sort Function" 217.%T "Engineering a Sort Function"
226.%J "bentley@research.att.com" 218.%J "Software \- Practice and Experience"
227.%V January 1992 219.%V Vol. 23(11)
220.%P pp. 1249\-1265
221.%D November 1993
228.Re 222.Re
229.Sh STANDARDS 223.Sh STANDARDS
224Previous versions of
225.Fn qsort
226did not permit the comparison routine itself to call
227.Fn qsort .
228This is no longer true.
229.Pp
230The 230The
231.Fn qsort 231.Fn qsort
232function 232function conforms to
233conforms to
234.St -ansiC . 233.St -ansiC .
diff --git a/src/lib/libc/stdlib/qsort.c b/src/lib/libc/stdlib/qsort.c
index c06bd54054..2a972c0eb0 100644
--- a/src/lib/libc/stdlib/qsort.c
+++ b/src/lib/libc/stdlib/qsort.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,15 +28,14 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char sccsid[] = "from: @(#)qsort.c 8.1 (Berkeley) 6/4/93";*/ 31static char *rcsid = "$OpenBSD: qsort.c,v 1.8 2003/06/02 20:18:38 millert Exp $";
36static char *rcsid = "$Id: qsort.c,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
39#include <sys/types.h> 34#include <sys/types.h>
40#include <stdlib.h> 35#include <stdlib.h>
41 36
42static inline char *med3 __P((char *, char *, char *, int (*)())); 37static __inline char *med3(char *, char *, char *, int (*)());
43static inline void swapfunc __P((char *, char *, int, int)); 38static __inline void swapfunc(char *, char *, int, int);
44 39
45#define min(a, b) (a) < (b) ? a : b 40#define min(a, b) (a) < (b) ? a : b
46 41
@@ -61,12 +56,12 @@ static inline void swapfunc __P((char *, char *, int, int));
61#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \ 56#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \
62 es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1; 57 es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;
63 58
64static inline void 59static __inline void
65swapfunc(a, b, n, swaptype) 60swapfunc(a, b, n, swaptype)
66 char *a, *b; 61 char *a, *b;
67 int n, swaptype; 62 int n, swaptype;
68{ 63{
69 if(swaptype <= 1) 64 if (swaptype <= 1)
70 swapcode(long, a, b, n) 65 swapcode(long, a, b, n)
71 else 66 else
72 swapcode(char, a, b, n) 67 swapcode(char, a, b, n)
@@ -82,7 +77,7 @@ swapfunc(a, b, n, swaptype)
82 77
83#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype) 78#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype)
84 79
85static inline char * 80static __inline char *
86med3(a, b, c, cmp) 81med3(a, b, c, cmp)
87 char *a, *b, *c; 82 char *a, *b, *c;
88 int (*cmp)(); 83 int (*cmp)();
@@ -93,27 +88,28 @@ med3(a, b, c, cmp)
93} 88}
94 89
95void 90void
96qsort(a, n, es, cmp) 91qsort(aa, n, es, cmp)
97 void *a; 92 void *aa;
98 size_t n, es; 93 size_t n, es;
99 int (*cmp)(); 94 int (*cmp)();
100{ 95{
101 char *pa, *pb, *pc, *pd, *pl, *pm, *pn; 96 char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
102 int d, r, swaptype, swap_cnt; 97 int d, r, swaptype, swap_cnt;
98 register char *a = aa;
103 99
104loop: SWAPINIT(a, es); 100loop: SWAPINIT(a, es);
105 swap_cnt = 0; 101 swap_cnt = 0;
106 if (n < 7) { 102 if (n < 7) {
107 for (pm = a + es; pm < (char *) a + n * es; pm += es) 103 for (pm = (char *)a + es; pm < (char *) a + n * es; pm += es)
108 for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0; 104 for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
109 pl -= es) 105 pl -= es)
110 swap(pl, pl - es); 106 swap(pl, pl - es);
111 return; 107 return;
112 } 108 }
113 pm = a + (n / 2) * es; 109 pm = (char *)a + (n / 2) * es;
114 if (n > 7) { 110 if (n > 7) {
115 pl = a; 111 pl = (char *)a;
116 pn = a + (n - 1) * es; 112 pn = (char *)a + (n - 1) * es;
117 if (n > 40) { 113 if (n > 40) {
118 d = (n / 8) * es; 114 d = (n / 8) * es;
119 pl = med3(pl, pl + d, pl + 2 * d, cmp); 115 pl = med3(pl, pl + d, pl + 2 * d, cmp);
@@ -123,9 +119,9 @@ loop: SWAPINIT(a, es);
123 pm = med3(pl, pm, pn, cmp); 119 pm = med3(pl, pm, pn, cmp);
124 } 120 }
125 swap(a, pm); 121 swap(a, pm);
126 pa = pb = a + es; 122 pa = pb = (char *)a + es;
127 123
128 pc = pd = a + (n - 1) * es; 124 pc = pd = (char *)a + (n - 1) * es;
129 for (;;) { 125 for (;;) {
130 while (pb <= pc && (r = cmp(pb, a)) <= 0) { 126 while (pb <= pc && (r = cmp(pb, a)) <= 0) {
131 if (r == 0) { 127 if (r == 0) {
@@ -151,14 +147,14 @@ loop: SWAPINIT(a, es);
151 pc -= es; 147 pc -= es;
152 } 148 }
153 if (swap_cnt == 0) { /* Switch to insertion sort */ 149 if (swap_cnt == 0) { /* Switch to insertion sort */
154 for (pm = a + es; pm < (char *) a + n * es; pm += es) 150 for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es)
155 for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0; 151 for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
156 pl -= es) 152 pl -= es)
157 swap(pl, pl - es); 153 swap(pl, pl - es);
158 return; 154 return;
159 } 155 }
160 156
161 pn = a + n * es; 157 pn = (char *)a + n * es;
162 r = min(pa - (char *)a, pb - pa); 158 r = min(pa - (char *)a, pb - pa);
163 vecswap(a, pb - r, r); 159 vecswap(a, pb - r, r);
164 r = min(pd - pc, pn - pd - es); 160 r = min(pd - pc, pn - pd - es);
diff --git a/src/lib/libc/stdlib/radixsort.3 b/src/lib/libc/stdlib/radixsort.3
index a2af9f17a4..028837d4d1 100644
--- a/src/lib/libc/stdlib/radixsort.3
+++ b/src/lib/libc/stdlib/radixsort.3
@@ -9,11 +9,7 @@
9.\" 2. Redistributions in binary form must reproduce the above copyright 9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\" notice, this list of conditions and the following disclaimer in the 10.\" notice, this list of conditions and the following disclaimer in the
11.\" documentation and/or other materials provided with the distribution. 11.\" documentation and/or other materials provided with the distribution.
12.\" 3. All advertising materials mentioning features or use of this software 12.\" 3. Neither the name of the University nor the names of its contributors
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 13.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission. 14.\" without specific prior written permission.
19.\" 15.\"
@@ -29,32 +25,33 @@
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE. 26.\" SUCH DAMAGE.
31.\" 27.\"
32.\" from: @(#)radixsort.3 8.2 (Berkeley) 1/27/94 28.\" $OpenBSD: radixsort.3,v 1.9 2003/06/02 20:18:38 millert Exp $
33.\" $Id: radixsort.3,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $
34.\" 29.\"
35.Dd January 27, 1994 30.Dd January 27, 1994
36.Dt RADIXSORT 3 31.Dt RADIXSORT 3
37.Os 32.Os
38.Sh NAME 33.Sh NAME
39.Nm radixsort 34.Nm radixsort ,
35.Nm sradixsort
40.Nd radix sort 36.Nd radix sort
41.Sh SYNOPSIS 37.Sh SYNOPSIS
42.Fd #include <limits.h> 38.Fd #include <limits.h>
43.Fd #include <stdlib.h> 39.Fd #include <stdlib.h>
44.Ft int 40.Ft int
45.Fn radixsort "u_char **base" "int nmemb" "u_char *table" "u_int endbyte" 41.Fn radixsort "const u_char **base" "int nmemb" "const u_char *table" "u_int endbyte"
46.Ft int 42.Ft int
47.Fn sradixsort "u_char **base" "int nmemb" "u_char *table" "u_int endbyte" 43.Fn sradixsort "const u_char **base" "int nmemb" "const u_char *table" "u_int endbyte"
48.Sh DESCRIPTION 44.Sh DESCRIPTION
49The 45The
50.Fn radixsort 46.Fn radixsort
51and 47and
52.Fn sradixsort 48.Fn sradixsort
53functions 49functions are implementations of radix sort.
54are implementations of radix sort.
55.Pp 50.Pp
56These functions sort an array of pointers to byte strings, the initial 51These functions sort an array of
57member of which is referenced by 52.Fa nmemb
53pointers to byte strings.
54The initial member is referenced by
58.Fa base . 55.Fa base .
59The byte strings may contain any values; the end of each string 56The byte strings may contain any values; the end of each string
60is denoted by the user-specified value 57is denoted by the user-specified value
@@ -63,26 +60,24 @@ is denoted by the user-specified value
63Applications may specify a sort order by providing the 60Applications may specify a sort order by providing the
64.Fa table 61.Fa table
65argument. 62argument.
66If 63If non-null,
67.Pf non- Dv NULL ,
68.Fa table 64.Fa table
69must reference an array of 65must reference an array of
70.Dv UCHAR_MAX 66.Dv UCHAR_MAX
71+ 1 bytes which contains the sort 67+ 1 bytes which contains the sort weight of each possible byte value.
72weight of each possible byte value.
73The end-of-string byte must have a sort weight of 0 or 255 68The end-of-string byte must have a sort weight of 0 or 255
74(for sorting in reverse order). 69(for sorting in reverse order).
75More than one byte may have the same sort weight. 70More than one byte may have the same sort weight.
76The 71The
77.Fa table 72.Fa table
78argument 73argument is useful for applications which wish to sort different characters
79is useful for applications which wish to sort different characters
80equally, for example, providing a table with the same weights 74equally, for example, providing a table with the same weights
81for A-Z as for a-z will result in a case-insensitive sort. 75for A-Z as for a-z will result in a case-insensitive sort.
82If 76If
83.Fa table 77.Fa table
84is NULL, the contents of the array are sorted in ascending order 78is
85according to the 79.Dv NULL ,
80the contents of the array are sorted in ascending order according to the
86.Tn ASCII 81.Tn ASCII
87order of the byte strings they reference and 82order of the byte strings they reference and
88.Fa endbyte 83.Fa endbyte
@@ -90,7 +85,7 @@ has a sorting weight of 0.
90.Pp 85.Pp
91The 86The
92.Fn sradixsort 87.Fn sradixsort
93function is stable, that is, if two elements compare as equal, their 88function is stable; that is, if two elements compare as equal, their
94order in the sorted array is unchanged. 89order in the sorted array is unchanged.
95The 90The
96.Fn sradixsort 91.Fn sradixsort
@@ -107,7 +102,7 @@ particular, see D.E. Knuth's Algorithm R and section 5.2.5, exercise 10.
107They take linear time relative to the number of bytes in the strings. 102They take linear time relative to the number of bytes in the strings.
108.Sh RETURN VALUES 103.Sh RETURN VALUES
109Upon successful completion 0 is returned. 104Upon successful completion 0 is returned.
110Otherwise, \-1 is returned and the global variable 105Otherwise, \-1 is returned and the global variable
111.Va errno 106.Va errno
112is set to indicate the error. 107is set to indicate the error.
113.Sh ERRORS 108.Sh ERRORS
@@ -122,15 +117,13 @@ is not 0 or 255.
122.Pp 117.Pp
123Additionally, the 118Additionally, the
124.Fn sradixsort 119.Fn sradixsort
125function 120function may fail and set
126may fail and set
127.Va errno 121.Va errno
128for any of the errors specified for the library routine 122for any of the errors specified for the library routine
129.Xr malloc 3 . 123.Xr malloc 3 .
130.Sh SEE ALSO 124.Sh SEE ALSO
131.Xr sort 1 , 125.Xr sort 1 ,
132.Xr qsort 3 126.Xr qsort 3
133.Pp
134.Rs 127.Rs
135.%A Knuth, D.E. 128.%A Knuth, D.E.
136.%D 1968 129.%D 1968
@@ -158,4 +151,5 @@ for any of the errors specified for the library routine
158.Sh HISTORY 151.Sh HISTORY
159The 152The
160.Fn radixsort 153.Fn radixsort
161function first appeared in 4.4BSD. 154function first appeared in
155.Bx 4.4 .
diff --git a/src/lib/libc/stdlib/radixsort.c b/src/lib/libc/stdlib/radixsort.c
index dd51013c94..1ff30416d9 100644
--- a/src/lib/libc/stdlib/radixsort.c
+++ b/src/lib/libc/stdlib/radixsort.c
@@ -13,11 +13,7 @@
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software 16 * 3. Neither the name of the University nor the names of its contributors
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 17 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission. 18 * without specific prior written permission.
23 * 19 *
@@ -35,8 +31,7 @@
35 */ 31 */
36 32
37#if defined(LIBC_SCCS) && !defined(lint) 33#if defined(LIBC_SCCS) && !defined(lint)
38/*static char sccsid[] = "from: @(#)radixsort.c 8.1 (Berkeley) 6/4/93";*/ 34static char *rcsid = "$OpenBSD: radixsort.c,v 1.6 2003/06/02 20:18:38 millert Exp $";
39static char *rcsid = "$Id: radixsort.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */ 35#endif /* LIBC_SCCS and not lint */
41 36
42/* 37/*
@@ -61,11 +56,11 @@ typedef struct {
61 int sn, si; 56 int sn, si;
62} stack; 57} stack;
63 58
64static inline void simplesort 59static __inline void simplesort
65 __P((const u_char **, int, int, const u_char *, u_int)); 60(const u_char **, int, int, const u_char *, u_int);
66static void r_sort_a __P((const u_char **, int, int, const u_char *, u_int)); 61static void r_sort_a(const u_char **, int, int, const u_char *, u_int);
67static void r_sort_b __P((const u_char **, 62static void r_sort_b(const u_char **,
68 const u_char **, int, int, const u_char *, u_int)); 63 const u_char **, int, int, const u_char *, u_int);
69 64
70#define THRESHOLD 20 /* Divert to simplesort(). */ 65#define THRESHOLD 20 /* Divert to simplesort(). */
71#define SIZE 512 /* Default stack size. */ 66#define SIZE 512 /* Default stack size. */
@@ -295,7 +290,7 @@ r_sort_b(a, ta, n, i, tr, endch)
295 } 290 }
296} 291}
297 292
298static inline void 293static __inline void
299simplesort(a, n, b, tr, endch) /* insertion sort */ 294simplesort(a, n, b, tr, endch) /* insertion sort */
300 register const u_char **a; 295 register const u_char **a;
301 int n, b; 296 int n, b;
diff --git a/src/lib/libc/stdlib/rand.3 b/src/lib/libc/stdlib/rand.3
index a0e7740e66..0d9c52a3b9 100644
--- a/src/lib/libc/stdlib/rand.3
+++ b/src/lib/libc/stdlib/rand.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,8 +29,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)rand.3 6.7 (Berkeley) 6/29/91 32.\" $OpenBSD: rand.3,v 1.9 2003/06/02 20:18:38 millert Exp $
37.\" $Id: rand.3,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd June 29, 1991
40.Dt RAND 3 35.Dt RAND 3
@@ -46,12 +41,15 @@
46.Sh SYNOPSIS 41.Sh SYNOPSIS
47.Fd #include <stdlib.h> 42.Fd #include <stdlib.h>
48.Ft void 43.Ft void
49.Fn srand "unsigned seed" 44.Fn srand "unsigned int seed"
50.Ft int 45.Ft int
51.Fn rand void 46.Fn rand void
47.Ft int
48.Fn rand_r "unsigned int *seed"
52.Sh DESCRIPTION 49.Sh DESCRIPTION
53.Bf -symbolic 50.Bf -symbolic
54These interfaces are obsoleted by random(3). 51These interfaces are obsoleted by
52.Xr random 3 .
55.Ef 53.Ef
56.Pp 54.Pp
57The 55The
@@ -73,13 +71,28 @@ with the same seed value.
73.Pp 71.Pp
74If no seed value is provided, the functions are automatically 72If no seed value is provided, the functions are automatically
75seeded with a value of 1. 73seeded with a value of 1.
74.Pp
75The
76.Fn rand_r
77is a thread-safe version of
78.Fn rand .
79Storage for the seed must be provided through the
80.Fa seed
81argument, and needs to have been initialized by the caller.
76.Sh SEE ALSO 82.Sh SEE ALSO
83.Xr arc4random 3 ,
84.Xr rand48 3 ,
77.Xr random 3 85.Xr random 3
78.Sh STANDARDS 86.Sh STANDARDS
79The 87The
80.Fn rand 88.Fn rand
81and 89and
82.Fn srand 90.Fn srand
83functions 91functions conform to
84conform to
85.St -ansiC . 92.St -ansiC .
93.Pp
94The
95.Fn rand_r
96function conforms to ISO/IEC 9945-1 ANSI/IEEE
97.Pq Dq Tn POSIX
98Std 1003.1c Draft 10.
diff --git a/src/lib/libc/stdlib/rand.c b/src/lib/libc/stdlib/rand.c
index 361d473448..d58d040ad5 100644
--- a/src/lib/libc/stdlib/rand.c
+++ b/src/lib/libc/stdlib/rand.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,24 +28,34 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)rand.c 5.6 (Berkeley) 6/24/91";*/ 31static char *rcsid = "$OpenBSD: rand.c,v 1.7 2003/06/02 20:18:38 millert Exp $";
36static char *rcsid = "$Id: rand.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
39#include <sys/types.h> 34#include <sys/types.h>
40#include <stdlib.h> 35#include <stdlib.h>
41 36
42static u_long next = 1; 37static u_int next = 1;
38
39int
40rand_r(seed)
41u_int *seed;
42{
43
44 *seed = *seed * 1103515245 + 12345;
45 return (*seed % ((u_int)RAND_MAX + 1));
46}
43 47
44int 48int
45rand() 49rand()
46{ 50{
47 return ((next = next * 1103515245 + 12345) % ((u_int)RAND_MAX + 1)); 51
52 return (rand_r(&next));
48} 53}
49 54
50void 55void
51srand(seed) 56srand(seed)
52u_int seed; 57u_int seed;
53{ 58{
59
54 next = seed; 60 next = seed;
55} 61}
diff --git a/src/lib/libc/stdlib/rand48.3 b/src/lib/libc/stdlib/rand48.3
index 5a772c9a8c..78cd0a7cd5 100644
--- a/src/lib/libc/stdlib/rand48.3
+++ b/src/lib/libc/stdlib/rand48.3
@@ -1,4 +1,4 @@
1\" Copyright (c) 1993 Martin Birgmeier 1.\" Copyright (c) 1993 Martin Birgmeier
2.\" All rights reserved. 2.\" All rights reserved.
3.\" 3.\"
4.\" You may redistribute unmodified or modified versions of this source 4.\" You may redistribute unmodified or modified versions of this source
@@ -9,7 +9,7 @@
9.\" of any kind. I shall in no event be liable for anything that happens 9.\" of any kind. I shall in no event be liable for anything that happens
10.\" to anyone/anything when using this software. 10.\" to anyone/anything when using this software.
11.\" 11.\"
12.\" $Id: rand48.3,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $ 12.\" $OpenBSD: rand48.3,v 1.10 2003/06/01 19:27:27 jmc Exp $
13.\" 13.\"
14.Dd October 8, 1993 14.Dd October 8, 1993
15.Dt RAND48 3 15.Dt RAND48 3
@@ -24,10 +24,10 @@
24.Nm srand48 , 24.Nm srand48 ,
25.Nm seed48 , 25.Nm seed48 ,
26.Nm lcong48 26.Nm lcong48
27.Nd pseudo random number generators and initialization routines 27.Nd pseudo-random number generators and initialization routines
28.Sh SYNOPSIS 28.Sh SYNOPSIS
29.Fd #include <stdlib.h> 29.Fd #include <stdlib.h>
30.Ft double 30.Ft double
31.Fn drand48 void 31.Fn drand48 void
32.Ft double 32.Ft double
33.Fn erand48 "unsigned short xseed[3]" 33.Fn erand48 "unsigned short xseed[3]"
@@ -49,12 +49,13 @@
49The 49The
50.Fn rand48 50.Fn rand48
51family of functions generates pseudo-random numbers using a linear 51family of functions generates pseudo-random numbers using a linear
52congruential algorithm working on integers 48 bits in size. The 52congruential algorithm working on integers 48 bits in size.
53particular formula employed is 53The particular formula employed is
54r(n+1) = (a * r(n) + c) mod m 54r(n+1) = (a * r(n) + c) mod m
55where the default values are 55where the default values are
56for the multiplicand a = 0xfdeece66d = 25214903917 and 56for the multiplicand a = 0xfdeece66d = 25214903917 and
57the addend c = 0xb = 11. The modulus is always fixed at m = 2 ** 48. 57the addend c = 0xb = 11.
58The modulus is always fixed at m = 2 ** 48.
58r(n) is called the seed of the random number generator. 59r(n) is called the seed of the random number generator.
59.Pp 60.Pp
60For all the six generator routines described next, the first 61For all the six generator routines described next, the first
@@ -63,15 +64,17 @@ computational step is to perform a single iteration of the algorithm.
63.Fn drand48 64.Fn drand48
64and 65and
65.Fn erand48 66.Fn erand48
66return values of type double. The full 48 bits of r(n+1) are 67return values of type double.
68The full 48 bits of r(n+1) are
67loaded into the mantissa of the returned value, with the exponent set 69loaded into the mantissa of the returned value, with the exponent set
68such that the values produced lie in the interval [0.0, 1.0). 70such that the values produced lie in the interval [0.0, 1.0].
69.Pp 71.Pp
70.Fn lrand48 72.Fn lrand48
71and 73and
72.Fn nrand48 74.Fn nrand48
73return values of type long in the range 75return values of type long in the range
74[0, 2**31-1]. The high-order (31) bits of 76[0, 2**31-1].
77The high-order (31) bits of
75r(n+1) are loaded into the lower bits of the returned value, with 78r(n+1) are loaded into the lower bits of the returned value, with
76the topmost (sign) bit set to zero. 79the topmost (sign) bit set to zero.
77.Pp 80.Pp
@@ -79,14 +82,15 @@ the topmost (sign) bit set to zero.
79and 82and
80.Fn jrand48 83.Fn jrand48
81return values of type long in the range 84return values of type long in the range
82[-2**31, 2**31-1]. The high-order (32) bits of 85[-2**31, 2**31-1].
83r(n+1) are loaded into the returned value. 86The high-order (32) bits of r(n+1) are loaded into the returned value.
84.Pp 87.Pp
85.Fn drand48 , 88.Fn drand48 ,
86.Fn lrand48 , 89.Fn lrand48 ,
87and 90and
88.Fn mrand48 91.Fn mrand48
89use an internal buffer to store r(n). For these functions 92use an internal buffer to store r(n).
93For these functions
90the initial value of r(0) = 0x1234abcd330e = 20017429951246. 94the initial value of r(0) = 0x1234abcd330e = 20017429951246.
91.Pp 95.Pp
92On the other hand, 96On the other hand,
@@ -118,12 +122,12 @@ also initializes the internal buffer r(n) of
118and 122and
119.Fn mrand48 , 123.Fn mrand48 ,
120but here all 48 bits of the seed can be specified in an array of 3 shorts, 124but here all 48 bits of the seed can be specified in an array of 3 shorts,
121where the zeroth member specifies the lowest bits. Again, 125where the zeroth member specifies the lowest bits.
122the constant multiplicand and addend of the algorithm are 126Again, the constant multiplicand and addend of the algorithm are
123reset to the default values given above. 127reset to the default values given above.
124.Fn seed48 128.Fn seed48
125returns a pointer to an array of 3 shorts which contains the old seed. 129returns a pointer to an array of 3 shorts which contains the old seed.
126This array is statically allocated, thus its contents are lost after 130This array is statically allocated, so its contents are lost after
127each new call to 131each new call to
128.Fn seed48 . 132.Fn seed48 .
129.Pp 133.Pp
@@ -152,9 +156,10 @@ always also set the multiplicand and addend for any of the six
152generator calls. 156generator calls.
153.Pp 157.Pp
154For a more powerful random number generator, see 158For a more powerful random number generator, see
155.Xr random 3 159.Xr random 3 .
156.Sh AUTHOR
157Martin Birgmeier
158.Sh SEE ALSO 160.Sh SEE ALSO
161.Xr arc4random 3 ,
159.Xr rand 3 , 162.Xr rand 3 ,
160.Xr random 3 . 163.Xr random 3
164.Sh AUTHORS
165Martin Birgmeier
diff --git a/src/lib/libc/stdlib/rand48.h b/src/lib/libc/stdlib/rand48.h
index 12496d1c8c..afa49f65f3 100644
--- a/src/lib/libc/stdlib/rand48.h
+++ b/src/lib/libc/stdlib/rand48.h
@@ -9,6 +9,8 @@
9 * This software is provided ``as is'', and comes with no warranties 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 10 * of any kind. I shall in no event be liable for anything that happens
11 * to anyone/anything when using this software. 11 * to anyone/anything when using this software.
12 *
13 * $OpenBSD: rand48.h,v 1.3 2002/02/16 21:27:24 millert Exp $
12 */ 14 */
13 15
14#ifndef _RAND48_H_ 16#ifndef _RAND48_H_
@@ -17,7 +19,7 @@
17#include <math.h> 19#include <math.h>
18#include <stdlib.h> 20#include <stdlib.h>
19 21
20void __dorand48 __P((unsigned short[3])); 22void __dorand48(unsigned short[3]);
21 23
22#define RAND48_SEED_0 (0x330e) 24#define RAND48_SEED_0 (0x330e)
23#define RAND48_SEED_1 (0xabcd) 25#define RAND48_SEED_1 (0xabcd)
diff --git a/src/lib/libc/stdlib/random.3 b/src/lib/libc/stdlib/random.3
index 38c15a9803..f43f06420d 100644
--- a/src/lib/libc/stdlib/random.3
+++ b/src/lib/libc/stdlib/random.3
@@ -9,11 +9,7 @@
9.\" 2. Redistributions in binary form must reproduce the above copyright 9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\" notice, this list of conditions and the following disclaimer in the 10.\" notice, this list of conditions and the following disclaimer in the
11.\" documentation and/or other materials provided with the distribution. 11.\" documentation and/or other materials provided with the distribution.
12.\" 3. All advertising materials mentioning features or use of this software 12.\" 3. Neither the name of the University nor the names of its contributors
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 13.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission. 14.\" without specific prior written permission.
19.\" 15.\"
@@ -29,97 +25,106 @@
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE. 26.\" SUCH DAMAGE.
31.\" 27.\"
32.\" from: @(#)random.3 6.5 (Berkeley) 4/19/91 28.\" $OpenBSD: random.3,v 1.17 2003/06/02 20:18:38 millert Exp $
33.\" $Id: random.3,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $
34.\" 29.\"
35.Dd April 19, 1991 30.Dd April 19, 1991
36.Dt RANDOM 3 31.Dt RANDOM 3
37.Os BSD 4.2 32.Os
38.Sh NAME 33.Sh NAME
39.Nm random , 34.Nm random ,
40.Nm srandom , 35.Nm srandom ,
36.Nm srandomdev ,
41.Nm initstate , 37.Nm initstate ,
42.Nm setstate 38.Nm setstate
43.Nd better random number generator; routines for changing generators 39.Nd better random number generator; routines for changing generators
44.Sh SYNOPSIS 40.Sh SYNOPSIS
45.Fd #include <stdlib.h> 41.Fd #include <stdlib.h>
46.Ft long 42.Ft long
47.Fn random void 43.Fn random void
48.Ft void 44.Ft void
49.Fn srandom "unsigned seed" 45.Fn srandom "unsigned int seed"
46.Ft void
47.Fn srandomdev void
50.Ft char * 48.Ft char *
51.Fn initstate "unsigned seed" "char *state" "int n" 49.Fn initstate "unsigned int seed" "char *state" "size_t n"
52.Ft char * 50.Ft char *
53.Fn setstate "char *state" 51.Fn setstate "const char *state"
54.Sh DESCRIPTION 52.Sh DESCRIPTION
55The 53The
56.Fn random 54.Fn random
57function 55function uses a non-linear additive feedback random number generator employing
58uses a non-linear additive feedback random number generator employing a 56a default table of size 31 long integers to return successive pseudo-random
59default table of size 31 long integers to return successive pseudo-random 57numbers in the range from 0 to (2**31)\-1.
60numbers in the range from 0 to
61.if t 2\u\s731\s10\d\(mi1.
62.if n (2**31)\(mi1.
63The period of this random number generator is very large, approximately 58The period of this random number generator is very large, approximately
64.if t 16\(mu(2\u\s731\s10\d\(mi1). 5916*((2**31)\-1).
65.if n 16*((2**31)\(mi1).
66.Pp 60.Pp
67The 61The
68.Fn random Ns / Fn srandom 62.Fn random
69have (almost) the same calling sequence and initialization properties as 63and
70.Xr rand 3 Ns / Xr srand 3 . 64.Fn srandom
65functions have (almost) the same calling sequence and initialization
66properties as
67.Xr rand 3 Ns / Ns Xr srand 3 .
71The difference is that 68The difference is that
72.Xr rand 69.Xr rand
73produces a much less random sequence \(em in fact, the low dozen bits 70produces a much less random sequence \(em in fact, the low dozen bits
74generated by rand go through a cyclic pattern. All the bits generated by 71generated by rand go through a cyclic pattern.
72All the bits generated by
75.Fn random 73.Fn random
76are usable. For example, 74are usable.
75For example,
77.Sq Li random()&01 76.Sq Li random()&01
78will produce a random binary 77will produce a random binary
79value. 78value.
80.Pp 79.Pp
81Unlike 80Like
82.Xr srand ,
83.Fn srandom
84does not return the old seed; the reason for this is that the amount of
85state information used is much more than a single word. (Two other
86routines are provided to deal with restarting/changing random
87number generators). Like
88.Xr rand 3 , 81.Xr rand 3 ,
89however,
90.Fn random 82.Fn random
91will by default produce a sequence of numbers that can be duplicated 83will by default produce a sequence of numbers that can be duplicated
92by calling 84by calling
93.Fn srandom 85.Fn srandom
94with 86with
95.Ql 1 87.Ql 1
96as the seed. 88as the seed.
97.Pp 89.Pp
98The 90The
91.Fn srandomdev
92routine initializes a state array using the
93.Xr arandom 4
94random number device which returns good random numbers,
95suitable for cryptographic use.
96Note that this particular seeding procedure can generate
97states which are impossible to reproduce by calling
98.Fn srandom
99with any value, since the succeeding terms in the
100state buffer are no longer derived from the LC algorithm applied to
101a fixed seed.
102.Pp
103The
99.Fn initstate 104.Fn initstate
100routine allows a state array, passed in as an argument, to be initialized 105routine allows a state array, passed in as an argument, to be initialized
101for future use. The size of the state array (in bytes) is used by 106for future use.
107The size of the state array (in bytes) is used by
102.Fn initstate 108.Fn initstate
103to decide how sophisticated a random number generator it should use \(em the 109to decide how sophisticated a random number generator it should use \(em the
104more state, the better the random numbers will be. 110more state, the better the random numbers will be.
105(Current "optimal" values for the amount of state information are 111(Current "optimal" values for the amount of state information are
1068, 32, 64, 128, and 256 bytes; other amounts will be rounded down to 1128, 32, 64, 128, and 256 bytes; other amounts will be rounded down to
107the nearest known amount. Using less than 8 bytes will cause an error.) 113the nearest known amount.
114Using less than 8 bytes will cause an error.)
108The seed for the initialization (which specifies a starting point for 115The seed for the initialization (which specifies a starting point for
109the random number sequence, and provides for restarting at the same 116the random number sequence, and provides for restarting at the same
110point) is also an argument. 117point) is also an argument.
111The 118The
112.Fn initstate 119.Fn initstate
113function 120function returns a pointer to the previous state information array.
114returns a pointer to the previous state information array.
115.Pp 121.Pp
116Once a state has been initialized, the 122Once a state has been initialized, the
117.Fn setstate 123.Fn setstate
118routine provides for rapid switching between states. 124routine provides for rapid switching between states.
119The 125The
120.Fn setstate 126.Fn setstate
121function 127function returns a pointer to the previous state array; its
122returns a pointer to the previous state array; its
123argument state array is used for further random number generation 128argument state array is used for further random number generation
124until the next call to 129until the next call to
125.Fn initstate 130.Fn initstate
@@ -143,12 +148,8 @@ is that the size of the state array does not have to be remembered after
143it is initialized. 148it is initialized.
144.Pp 149.Pp
145With 256 bytes of state information, the period of the random number 150With 256 bytes of state information, the period of the random number
146generator is greater than 151generator is greater than 2**69
147.if t 2\u\s769\s10\d,
148.if n 2**69
149which should be sufficient for most purposes. 152which should be sufficient for most purposes.
150.Sh AUTHOR
151Earl T. Cohen
152.Sh DIAGNOSTICS 153.Sh DIAGNOSTICS
153If 154If
154.Fn initstate 155.Fn initstate
@@ -157,11 +158,29 @@ is called with less than 8 bytes of state information, or if
157detects that the state information has been garbled, error 158detects that the state information has been garbled, error
158messages are printed on the standard error output. 159messages are printed on the standard error output.
159.Sh SEE ALSO 160.Sh SEE ALSO
160.Xr rand 3 161.Xr arc4random 3 ,
162.Xr drand48 3 ,
163.Xr rand 3 ,
164.Xr random 4
165.Sh STANDARDS
166The
167.Fn random ,
168.Fn srandom ,
169.Fn initstate ,
170and
171.Fn setstate
172functions conform to
173.St -xpg4.2 .
174.Pp
175The
176.Fn srandomdev
177function is an extension.
161.Sh HISTORY 178.Sh HISTORY
162These 179These
163functions appeared in 180functions appeared in
164.Bx 4.2 . 181.Bx 4.2 .
182.Sh AUTHORS
183.An Earl T. Cohen
165.Sh BUGS 184.Sh BUGS
166About 2/3 the speed of 185About 2/3 the speed of
167.Xr rand 3 . 186.Xr rand 3 .
diff --git a/src/lib/libc/stdlib/random.c b/src/lib/libc/stdlib/random.c
index 469b6d976a..4807d2f27d 100644
--- a/src/lib/libc/stdlib/random.c
+++ b/src/lib/libc/stdlib/random.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,12 +28,16 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)random.c 5.9 (Berkeley) 2/23/91";*/ 31static char *rcsid = "$OpenBSD: random.c,v 1.12 2003/06/02 20:18:38 millert Exp $";
36static char *rcsid = "$Id: random.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
34#include <sys/param.h>
35#include <sys/sysctl.h>
36#include <sys/time.h>
37#include <fcntl.h>
39#include <stdio.h> 38#include <stdio.h>
40#include <stdlib.h> 39#include <stdlib.h>
40#include <unistd.h>
41 41
42/* 42/*
43 * random.c: 43 * random.c:
@@ -55,10 +55,10 @@ static char *rcsid = "$Id: random.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $"
55 * congruential generator. If the amount of state information is less than 55 * congruential generator. If the amount of state information is less than
56 * 32 bytes, a simple linear congruential R.N.G. is used. 56 * 32 bytes, a simple linear congruential R.N.G. is used.
57 * 57 *
58 * Internally, the state information is treated as an array of longs; the 58 * Internally, the state information is treated as an array of int32_t; the
59 * zeroeth element of the array is the type of R.N.G. being used (small 59 * zeroeth element of the array is the type of R.N.G. being used (small
60 * integer); the remainder of the array is the state information for the 60 * integer); the remainder of the array is the state information for the
61 * R.N.G. Thus, 32 bytes of state information will give 7 longs worth of 61 * R.N.G. Thus, 32 bytes of state information will give 7 int32_ts worth of
62 * state information, which will allow a degree seven polynomial. (Note: 62 * state information, which will allow a degree seven polynomial. (Note:
63 * the zeroeth word of state information also has some other information 63 * the zeroeth word of state information also has some other information
64 * stored in it -- see setstate() for details). 64 * stored in it -- see setstate() for details).
@@ -134,14 +134,14 @@ static int seps [MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 };
134 * MAX_TYPES * (rptr - state) + TYPE_3 == TYPE_3. 134 * MAX_TYPES * (rptr - state) + TYPE_3 == TYPE_3.
135 */ 135 */
136 136
137static long randtbl[DEG_3 + 1] = { 137static int32_t randtbl[DEG_3 + 1] = {
138 TYPE_3, 138 TYPE_3,
139 0x9a319039, 0x32d9c024, 0x9b663182, 0x5da1f342, 0xde3b81e0, 0xdf0a6fb5, 139 0x991539b1, 0x16a5bce3, 0x6774a4cd, 0x3e01511e, 0x4e508aaa, 0x61048c05,
140 0xf103bc02, 0x48f340fb, 0x7449e56b, 0xbeb1dbb0, 0xab5c5918, 0x946554fd, 140 0xf5500617, 0x846b7115, 0x6a19892c, 0x896a97af, 0xdb48f936, 0x14898454,
141 0x8c2e680f, 0xeb3d799f, 0xb11ee0b7, 0x2d436b86, 0xda672e2a, 0x1588ca88, 141 0x37ffd106, 0xb58bff9c, 0x59e17104, 0xcf918a49, 0x09378c83, 0x52c7a471,
142 0xe369735d, 0x904f35f7, 0xd7158fd6, 0x6fa6f051, 0x616e6b96, 0xac94efdc, 142 0x8d293ea9, 0x1f4fc301, 0xc3db71be, 0x39b44e1c, 0xf8a44ef9, 0x4c8b80b1,
143 0x36413f93, 0xc622c298, 0xf5a42ab8, 0x8a88d77b, 0xf5ad9d0e, 0x8999220b, 143 0x19edc328, 0x87bf4bdd, 0xc9b240e5, 0xe9ee4b1b, 0x4382aee7, 0x535b6b41,
144 0x27fb47b9, 144 0xf3bec5da,
145}; 145};
146 146
147/* 147/*
@@ -158,8 +158,8 @@ static long randtbl[DEG_3 + 1] = {
158 * in the initialization of randtbl) because the state table pointer is set 158 * in the initialization of randtbl) because the state table pointer is set
159 * to point to randtbl[1] (as explained below). 159 * to point to randtbl[1] (as explained below).
160 */ 160 */
161static long *fptr = &randtbl[SEP_3 + 1]; 161static int32_t *fptr = &randtbl[SEP_3 + 1];
162static long *rptr = &randtbl[1]; 162static int32_t *rptr = &randtbl[1];
163 163
164/* 164/*
165 * The following things are the pointer to the state information table, the 165 * The following things are the pointer to the state information table, the
@@ -171,11 +171,11 @@ static long *rptr = &randtbl[1];
171 * this is more efficient than indexing every time to find the address of 171 * this is more efficient than indexing every time to find the address of
172 * the last element to see if the front and rear pointers have wrapped. 172 * the last element to see if the front and rear pointers have wrapped.
173 */ 173 */
174static long *state = &randtbl[1]; 174static int32_t *state = &randtbl[1];
175static int32_t *end_ptr = &randtbl[DEG_3 + 1];
175static int rand_type = TYPE_3; 176static int rand_type = TYPE_3;
176static int rand_deg = DEG_3; 177static int rand_deg = DEG_3;
177static int rand_sep = SEP_3; 178static int rand_sep = SEP_3;
178static long *end_ptr = &randtbl[DEG_3 + 1];
179 179
180/* 180/*
181 * srandom: 181 * srandom:
@@ -191,17 +191,28 @@ static long *end_ptr = &randtbl[DEG_3 + 1];
191 */ 191 */
192void 192void
193srandom(x) 193srandom(x)
194 u_int x; 194 unsigned int x;
195{ 195{
196 register int i, j; 196 int i;
197 int32_t test;
198 div_t val;
197 199
198 if (rand_type == TYPE_0) 200 if (rand_type == TYPE_0)
199 state[0] = x; 201 state[0] = x;
200 else { 202 else {
201 j = 1;
202 state[0] = x; 203 state[0] = x;
203 for (i = 1; i < rand_deg; i++) 204 for (i = 1; i < rand_deg; i++) {
204 state[i] = 1103515245 * state[i - 1] + 12345; 205 /*
206 * Implement the following, without overflowing 31 bits:
207 *
208 * state[i] = (16807 * state[i - 1]) % 2147483647;
209 *
210 * 2^31-1 (prime) = 2147483647 = 127773*16807+2836
211 */
212 val = div(state[i-1], 127773);
213 test = 16807 * val.rem - 2836 * val.quot;
214 state[i] = test + (test < 0 ? 2147483647 : 0);
215 }
205 fptr = &state[rand_sep]; 216 fptr = &state[rand_sep];
206 rptr = &state[0]; 217 rptr = &state[0];
207 for (i = 0; i < 10 * rand_deg; i++) 218 for (i = 0; i < 10 * rand_deg; i++)
@@ -210,6 +221,65 @@ srandom(x)
210} 221}
211 222
212/* 223/*
224 * srandomdev:
225 *
226 * Many programs choose the seed value in a totally predictable manner.
227 * This often causes problems. We seed the generator using the much more
228 * secure arandom(4) interface. Note that this particular seeding
229 * procedure can generate states which are impossible to reproduce by
230 * calling srandom() with any value, since the succeeding terms in the
231 * state buffer are no longer derived from the LC algorithm applied to
232 * a fixed seed.
233 */
234void
235srandomdev()
236{
237 int fd, i, mib[2], n;
238 size_t len;
239
240 if (rand_type == TYPE_0)
241 len = sizeof(state[0]);
242 else
243 len = rand_deg * sizeof(state[0]);
244
245 /*
246 * To get seed data, first try reading from /dev/arandom.
247 * If that fails, try the KERN_ARND sysctl() (one int at a time).
248 * As a last resort, call srandom().
249 */
250 if ((fd = open("/dev/arandom", O_RDONLY, 0)) != -1 &&
251 read(fd, (void *) state, len) == (ssize_t) len) {
252 close(fd);
253 } else {
254 if (fd != -1)
255 close(fd);
256 mib[0] = CTL_KERN;
257 mib[1] = KERN_ARND;
258 n = len / sizeof(int);
259 len = sizeof(int);
260 for (i = 0; i < n; i++) {
261 if (sysctl(mib, 2, (char *)((int *)state + i), &len,
262 NULL, 0) == -1)
263 break;
264 }
265 if (i != n) {
266 struct timeval tv;
267 u_int junk;
268
269 /* XXX - this could be better */
270 gettimeofday(&tv, NULL);
271 srandom(getpid() ^ tv.tv_sec ^ tv.tv_usec ^ junk);
272 return;
273 }
274 }
275
276 if (rand_type != TYPE_0) {
277 fptr = &state[rand_sep];
278 rptr = &state[0];
279 }
280}
281
282/*
213 * initstate: 283 * initstate:
214 * 284 *
215 * Initialize the state information in the given array of n bytes for future 285 * Initialize the state information in the given array of n bytes for future
@@ -232,19 +302,16 @@ char *
232initstate(seed, arg_state, n) 302initstate(seed, arg_state, n)
233 u_int seed; /* seed for R.N.G. */ 303 u_int seed; /* seed for R.N.G. */
234 char *arg_state; /* pointer to state array */ 304 char *arg_state; /* pointer to state array */
235 int n; /* # bytes of state info */ 305 size_t n; /* # bytes of state info */
236{ 306{
237 register char *ostate = (char *)(&state[-1]); 307 char *ostate = (char *)(&state[-1]);
238 308
239 if (rand_type == TYPE_0) 309 if (rand_type == TYPE_0)
240 state[-1] = rand_type; 310 state[-1] = rand_type;
241 else 311 else
242 state[-1] = MAX_TYPES * (rptr - state) + rand_type; 312 state[-1] = MAX_TYPES * (rptr - state) + rand_type;
243 if (n < BREAK_0) { 313 if (n < BREAK_0)
244 (void)fprintf(stderr, 314 return(NULL);
245 "random: not enough state (%d bytes); ignored.\n", n);
246 return(0);
247 }
248 if (n < BREAK_1) { 315 if (n < BREAK_1) {
249 rand_type = TYPE_0; 316 rand_type = TYPE_0;
250 rand_deg = DEG_0; 317 rand_deg = DEG_0;
@@ -266,7 +333,7 @@ initstate(seed, arg_state, n)
266 rand_deg = DEG_4; 333 rand_deg = DEG_4;
267 rand_sep = SEP_4; 334 rand_sep = SEP_4;
268 } 335 }
269 state = &(((long *)arg_state)[1]); /* first location */ 336 state = &(((int32_t *)arg_state)[1]); /* first location */
270 end_ptr = &state[rand_deg]; /* must set end_ptr before srandom */ 337 end_ptr = &state[rand_deg]; /* must set end_ptr before srandom */
271 srandom(seed); 338 srandom(seed);
272 if (rand_type == TYPE_0) 339 if (rand_type == TYPE_0)
@@ -293,11 +360,11 @@ initstate(seed, arg_state, n)
293 */ 360 */
294char * 361char *
295setstate(arg_state) 362setstate(arg_state)
296 char *arg_state; 363 const char *arg_state;
297{ 364{
298 register long *new_state = (long *)arg_state; 365 int32_t *new_state = (int32_t *)arg_state;
299 register int type = new_state[0] % MAX_TYPES; 366 int32_t type = new_state[0] % MAX_TYPES;
300 register int rear = new_state[0] / MAX_TYPES; 367 int32_t rear = new_state[0] / MAX_TYPES;
301 char *ostate = (char *)(&state[-1]); 368 char *ostate = (char *)(&state[-1]);
302 369
303 if (rand_type == TYPE_0) 370 if (rand_type == TYPE_0)
@@ -315,8 +382,7 @@ setstate(arg_state)
315 rand_sep = seps[type]; 382 rand_sep = seps[type];
316 break; 383 break;
317 default: 384 default:
318 (void)fprintf(stderr, 385 return(NULL);
319 "random: state info corrupted; not changed.\n");
320 } 386 }
321 state = &new_state[1]; 387 state = &new_state[1];
322 if (rand_type != TYPE_0) { 388 if (rand_type != TYPE_0) {
@@ -347,7 +413,7 @@ setstate(arg_state)
347long 413long
348random() 414random()
349{ 415{
350 long i; 416 int32_t i;
351 417
352 if (rand_type == TYPE_0) 418 if (rand_type == TYPE_0)
353 i = state[0] = (state[0] * 1103515245 + 12345) & 0x7fffffff; 419 i = state[0] = (state[0] * 1103515245 + 12345) & 0x7fffffff;
@@ -360,5 +426,5 @@ random()
360 } else if (++rptr >= end_ptr) 426 } else if (++rptr >= end_ptr)
361 rptr = state; 427 rptr = state;
362 } 428 }
363 return(i); 429 return((long)i);
364} 430}
diff --git a/src/lib/libc/stdlib/realloc.3 b/src/lib/libc/stdlib/realloc.3
deleted file mode 100644
index 66f09b2081..0000000000
--- a/src/lib/libc/stdlib/realloc.3
+++ /dev/null
@@ -1,100 +0,0 @@
1.\" Copyright (c) 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.\" from: @(#)realloc.3 5.1 (Berkeley) 5/2/91
33.\" $Id: realloc.3,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $
34.\"
35.Dd May 2, 1991
36.Dt REALLOC 3
37.Os
38.Sh NAME
39.Nm realloc
40.Nd reallocation of memory function
41.Sh SYNOPSIS
42.Fd #include <stdlib.h>
43.Ft void *
44.Fn realloc "void *ptr" "size_t size"
45.Sh DESCRIPTION
46The
47.Fn realloc
48function changes the size of the object pointed to by
49.Fa ptr
50to the size specified by
51.Fa size .
52The contents of the object are unchanged up to the lesser
53of the new and old sizes.
54If the new size is larger, the value of the newly allocated portion
55of the object is indeterminate.
56If
57.Fa ptr
58is a null pointer, the
59.Fn realloc
60function behaves like the
61.Xr malloc 3
62function for the specified size.
63Otherwise, if
64.Fa ptr
65does not match a pointer earlier returned by the
66.Xr calloc 3 ,
67.Xr malloc 3 ,
68or
69.Fn realloc
70function, or if the space has been deallocated
71by a call to the
72.Xr free
73or
74.Fn realloc
75function, unpredictable and usually detrimental
76behavior will occur.
77If the space cannot be allocated, the object
78pointed to by
79.Fa ptr
80is unchanged.
81If
82.Fa size
83is zero and
84.Fa ptr
85is not a null pointer, the object it points to is freed.
86.Pp
87The
88.Fn realloc
89function returns either a null pointer or a pointer
90to the possibly moved allocated space.
91.Sh SEE ALSO
92.Xr alloca 3 ,
93.Xr calloc 3 ,
94.Xr free 3 ,
95.Xr malloc 3 ,
96.Sh STANDARDS
97The
98.Fn realloc
99function conforms to
100.St -ansiC .
diff --git a/src/lib/libc/stdlib/realpath.3 b/src/lib/libc/stdlib/realpath.3
index 9d8b1ff2ce..b8093b51e1 100644
--- a/src/lib/libc/stdlib/realpath.3
+++ b/src/lib/libc/stdlib/realpath.3
@@ -12,11 +12,7 @@
12.\" 2. Redistributions in binary form must reproduce the above copyright 12.\" 2. Redistributions in binary form must reproduce the above copyright
13.\" notice, this list of conditions and the following disclaimer in the 13.\" notice, this list of conditions and the following disclaimer in the
14.\" documentation and/or other materials provided with the distribution. 14.\" documentation and/or other materials provided with the distribution.
15.\" 3. All advertising materials mentioning features or use of this software 15.\" 3. Neither the name of the University nor the names of its contributors
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 16.\" may be used to endorse or promote products derived from this software
21.\" without specific prior written permission. 17.\" without specific prior written permission.
22.\" 18.\"
@@ -32,10 +28,9 @@
32.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33.\" SUCH DAMAGE. 29.\" SUCH DAMAGE.
34.\" 30.\"
35.\" from: @(#)realpath.3 8.2 (Berkeley) 2/16/94 31.\" $OpenBSD: realpath.3,v 1.10 2003/06/02 20:18:38 millert Exp $
36.\" $Id: realpath.3,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $
37.\" 32.\"
38.Dd "February 16, 1994" 33.Dd February 16, 1994
39.Dt REALPATH 3 34.Dt REALPATH 3
40.Os 35.Os
41.Sh NAME 36.Sh NAME
@@ -57,8 +52,7 @@ and
57.Pa /../ 52.Pa /../
58in 53in
59.Fa pathname , 54.Fa pathname ,
60and copies the resulting absolute pathname into 55and copies the resulting absolute pathname into the memory referenced by
61the memory referenced by
62.Fa resolvedname . 56.Fa resolvedname .
63The 57The
64.Fa resolvedname 58.Fa resolvedname
@@ -68,7 +62,7 @@ refer to a buffer capable of storing at least
68.Dv MAXPATHLEN 62.Dv MAXPATHLEN
69characters. 63characters.
70.Pp 64.Pp
71The 65The
72.Fn realpath 66.Fn realpath
73function will resolve both absolute and relative paths 67function will resolve both absolute and relative paths
74and return the absolute pathname corresponding to 68and return the absolute pathname corresponding to
@@ -78,18 +72,18 @@ All but the last component of
78must exist when 72must exist when
79.Fn realpath 73.Fn realpath
80is called. 74is called.
81.Sh "RETURN VALUES" 75.Sh RETURN VALUES
82The 76The
83.Fn realpath 77.Fn realpath
84function returns 78function returns
85.Fa resolved_name 79.Fa resolvedname
86on success. 80on success.
87If an error occurs, 81If an error occurs,
88.Fn realpath 82.Fn realpath
89returns 83returns
90.Dv NULL , 84.Dv NULL ,
91and 85and
92.Fa resolved_name 86.Fa resolvedname
93contains the pathname which caused the problem. 87contains the pathname which caused the problem.
94.Sh ERRORS 88.Sh ERRORS
95The function 89The function
@@ -102,9 +96,16 @@ for any of the errors specified for the library functions
102.Xr fchdir 2 , 96.Xr fchdir 2 ,
103.Xr lstat 2 , 97.Xr lstat 2 ,
104.Xr open 2 , 98.Xr open 2 ,
105.Xr readlink 2 99.Xr readlink 2 ,
106and 100and
107.Xr getcwd 3 . 101.Xr getcwd 3 .
102.Sh SEE ALSO
103.Xr getcwd 3
104.Sh HISTORY
105The
106.Fn realpath
107function call first appeared in
108.Bx 4.4 .
108.Sh CAVEATS 109.Sh CAVEATS
109This implementation of 110This implementation of
110.Fn realpath 111.Fn realpath
@@ -114,13 +115,6 @@ The
114version always returns absolute pathnames, 115version always returns absolute pathnames,
115whereas the Solaris implementation will, 116whereas the Solaris implementation will,
116under certain circumstances, return a relative 117under certain circumstances, return a relative
117.Fa resolved_path 118.Fa resolvedname
118when given a relative 119when given a relative
119.Fa pathname . 120.Fa pathname .
120.Sh "SEE ALSO"
121.Xr getcwd 3
122.Sh HISTORY
123The
124.Fn realpath
125function call first appeared in
126.Bx 4.4 .
diff --git a/src/lib/libc/stdlib/realpath.c b/src/lib/libc/stdlib/realpath.c
index e349b7e068..1525d0372f 100644
--- a/src/lib/libc/stdlib/realpath.c
+++ b/src/lib/libc/stdlib/realpath.c
@@ -13,11 +13,7 @@
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software 16 * 3. Neither the name of the University nor the names of its contributors
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 17 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission. 18 * without specific prior written permission.
23 * 19 *
@@ -35,8 +31,7 @@
35 */ 31 */
36 32
37#if defined(LIBC_SCCS) && !defined(lint) 33#if defined(LIBC_SCCS) && !defined(lint)
38/*static char sccsid[] = "from: @(#)realpath.c 8.1 (Berkeley) 2/16/94";*/ 34static char *rcsid = "$OpenBSD: realpath.c,v 1.10 2003/08/01 21:04:59 millert Exp $";
39static char *rcsid = "$Id: realpath.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */ 35#endif /* LIBC_SCCS and not lint */
41 36
42#include <sys/param.h> 37#include <sys/param.h>
@@ -61,15 +56,20 @@ realpath(path, resolved)
61 char *resolved; 56 char *resolved;
62{ 57{
63 struct stat sb; 58 struct stat sb;
64 int fd, n, rootd, serrno; 59 int fd, n, needslash, serrno;
65 char *p, *q, wbuf[MAXPATHLEN]; 60 char *p, *q, wbuf[MAXPATHLEN];
61 int symlinks = 0;
66 62
67 /* Save the starting point. */ 63 /* Save the starting point. */
68 if ((fd = open(".", O_RDONLY)) < 0) { 64 if ((fd = open(".", O_RDONLY)) < 0) {
69 (void)strcpy(resolved, "."); 65 (void)strlcpy(resolved, ".", MAXPATHLEN);
70 return (NULL); 66 return (NULL);
71 } 67 }
72 68
69 /* Convert "." -> "" to optimize away a needless lstat() and chdir() */
70 if (path[0] == '.' && path[1] == '\0')
71 path = "";
72
73 /* 73 /*
74 * Find the dirname and basename from the path to be resolved. 74 * Find the dirname and basename from the path to be resolved.
75 * Change directory to the dirname component. 75 * Change directory to the dirname component.
@@ -78,8 +78,7 @@ realpath(path, resolved)
78 * if it is a directory, then change to that directory. 78 * if it is a directory, then change to that directory.
79 * get the current directory name and append the basename. 79 * get the current directory name and append the basename.
80 */ 80 */
81 (void)strncpy(resolved, path, MAXPATHLEN - 1); 81 strlcpy(resolved, path, MAXPATHLEN);
82 resolved[MAXPATHLEN - 1] = '\0';
83loop: 82loop:
84 q = strrchr(resolved, '/'); 83 q = strrchr(resolved, '/');
85 if (q != NULL) { 84 if (q != NULL) {
@@ -99,9 +98,13 @@ loop:
99 p = resolved; 98 p = resolved;
100 99
101 /* Deal with the last component. */ 100 /* Deal with the last component. */
102 if (lstat(p, &sb) == 0) { 101 if (*p != '\0' && lstat(p, &sb) == 0) {
103 if (S_ISLNK(sb.st_mode)) { 102 if (S_ISLNK(sb.st_mode)) {
104 n = readlink(p, resolved, MAXPATHLEN); 103 if (++symlinks > MAXSYMLINKS) {
104 errno = ELOOP;
105 goto err1;
106 }
107 n = readlink(p, resolved, MAXPATHLEN-1);
105 if (n < 0) 108 if (n < 0)
106 goto err1; 109 goto err1;
107 resolved[n] = '\0'; 110 resolved[n] = '\0';
@@ -118,7 +121,7 @@ loop:
118 * Save the last component name and get the full pathname of 121 * Save the last component name and get the full pathname of
119 * the current directory. 122 * the current directory.
120 */ 123 */
121 (void)strcpy(wbuf, p); 124 (void)strlcpy(wbuf, p, sizeof wbuf);
122 if (getcwd(resolved, MAXPATHLEN) == 0) 125 if (getcwd(resolved, MAXPATHLEN) == 0)
123 goto err1; 126 goto err1;
124 127
@@ -127,18 +130,18 @@ loop:
127 * happens if the last component is empty, or the dirname is root. 130 * happens if the last component is empty, or the dirname is root.
128 */ 131 */
129 if (resolved[0] == '/' && resolved[1] == '\0') 132 if (resolved[0] == '/' && resolved[1] == '\0')
130 rootd = 1; 133 needslash = 0;
131 else 134 else
132 rootd = 0; 135 needslash = 1;
133 136
134 if (*wbuf) { 137 if (*wbuf) {
135 if (strlen(resolved) + strlen(wbuf) + rootd + 1 > MAXPATHLEN) { 138 if (strlen(resolved) + strlen(wbuf) + needslash >= MAXPATHLEN) {
136 errno = ENAMETOOLONG; 139 errno = ENAMETOOLONG;
137 goto err1; 140 goto err1;
138 } 141 }
139 if (rootd == 0) 142 if (needslash)
140 (void)strcat(resolved, "/"); 143 strlcat(resolved, "/", MAXPATHLEN);
141 (void)strcat(resolved, wbuf); 144 strlcat(resolved, wbuf, MAXPATHLEN);
142 } 145 }
143 146
144 /* Go back to where we came from. */ 147 /* Go back to where we came from. */
diff --git a/src/lib/libc/stdlib/remque.c b/src/lib/libc/stdlib/remque.c
new file mode 100644
index 0000000000..f4c5769a8c
--- /dev/null
+++ b/src/lib/libc/stdlib/remque.c
@@ -0,0 +1,48 @@
1/* $OpenBSD: remque.c,v 1.1 2003/05/08 23:26:30 millert Exp $ */
2
3/*
4 * Copyright (c) 1993 John Brezak
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 be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
22 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#if defined(LIBC_SCCS) && !defined(lint)
32static char *rcsid = "$OpenBSD: remque.c,v 1.1 2003/05/08 23:26:30 millert Exp $";
33#endif /* LIBC_SCCS and not lint */
34
35#include <search.h>
36
37struct qelem {
38 struct qelem *q_forw;
39 struct qelem *q_back;
40};
41
42void
43remque(void *element)
44{
45 struct qelem *e = (struct qelem *) element;
46 e->q_forw->q_back = e->q_back;
47 e->q_back->q_forw = e->q_forw;
48}
diff --git a/src/lib/libc/stdlib/seed48.c b/src/lib/libc/stdlib/seed48.c
index e3d31901dd..c4dcd0ead8 100644
--- a/src/lib/libc/stdlib/seed48.c
+++ b/src/lib/libc/stdlib/seed48.c
@@ -11,6 +11,10 @@
11 * to anyone/anything when using this software. 11 * to anyone/anything when using this software.
12 */ 12 */
13 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
14#include "rand48.h" 18#include "rand48.h"
15 19
16extern unsigned short __rand48_seed[3]; 20extern unsigned short __rand48_seed[3];
diff --git a/src/lib/libc/stdlib/setenv.c b/src/lib/libc/stdlib/setenv.c
index a36669888d..2ba072b65c 100644
--- a/src/lib/libc/stdlib/setenv.c
+++ b/src/lib/libc/stdlib/setenv.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,13 +28,14 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)setenv.c 5.6 (Berkeley) 6/4/91";*/ 31static char *rcsid = "$OpenBSD: setenv.c,v 1.6 2003/06/02 20:18:38 millert Exp $";
36static char *rcsid = "$Id: setenv.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
39#include <stdlib.h> 34#include <stdlib.h>
40#include <string.h> 35#include <string.h>
41 36
37char *__findenv(const char *name, int *offset);
38
42/* 39/*
43 * setenv -- 40 * setenv --
44 * Set the value of the environmental variable "name" to be 41 * Set the value of the environmental variable "name" to be
@@ -54,7 +51,6 @@ setenv(name, value, rewrite)
54 static int alloced; /* if allocated space before */ 51 static int alloced; /* if allocated space before */
55 register char *C; 52 register char *C;
56 int l_value, offset; 53 int l_value, offset;
57 char *__findenv();
58 54
59 if (*value == '=') /* no `=' in value */ 55 if (*value == '=') /* no `=' in value */
60 ++value; 56 ++value;
@@ -63,7 +59,8 @@ setenv(name, value, rewrite)
63 if (!rewrite) 59 if (!rewrite)
64 return (0); 60 return (0);
65 if (strlen(C) >= l_value) { /* old larger; copy over */ 61 if (strlen(C) >= l_value) { /* old larger; copy over */
66 while (*C++ = *value++); 62 while ((*C++ = *value++))
63 ;
67 return (0); 64 return (0);
68 } 65 }
69 } else { /* create new slot */ 66 } else { /* create new slot */
@@ -72,10 +69,11 @@ setenv(name, value, rewrite)
72 69
73 for (P = environ, cnt = 0; *P; ++P, ++cnt); 70 for (P = environ, cnt = 0; *P; ++P, ++cnt);
74 if (alloced) { /* just increase size */ 71 if (alloced) { /* just increase size */
75 environ = (char **)realloc((char *)environ, 72 P = (char **)realloc((void *)environ,
76 (size_t)(sizeof(char *) * (cnt + 2))); 73 (size_t)(sizeof(char *) * (cnt + 2)));
77 if (!environ) 74 if (!P)
78 return (-1); 75 return (-1);
76 environ = P;
79 } 77 }
80 else { /* get new space */ 78 else { /* get new space */
81 alloced = 1; /* copy old entries into it */ 79 alloced = 1; /* copy old entries into it */
@@ -95,7 +93,7 @@ setenv(name, value, rewrite)
95 return (-1); 93 return (-1);
96 for (C = environ[offset]; (*C = *name++) && *C != '='; ++C) 94 for (C = environ[offset]; (*C = *name++) && *C != '='; ++C)
97 ; 95 ;
98 for (*C++ = '='; *C++ = *value++; ) 96 for (*C++ = '='; (*C++ = *value++); )
99 ; 97 ;
100 return (0); 98 return (0);
101} 99}
diff --git a/src/lib/libc/stdlib/srand48.c b/src/lib/libc/stdlib/srand48.c
index daf733f93e..fcff8a172e 100644
--- a/src/lib/libc/stdlib/srand48.c
+++ b/src/lib/libc/stdlib/srand48.c
@@ -11,6 +11,10 @@
11 * to anyone/anything when using this software. 11 * to anyone/anything when using this software.
12 */ 12 */
13 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
14#include "rand48.h" 18#include "rand48.h"
15 19
16extern unsigned short __rand48_seed[3]; 20extern unsigned short __rand48_seed[3];
diff --git a/src/lib/libc/stdlib/strtod.3 b/src/lib/libc/stdlib/strtod.3
index 0b7f973857..e25b0a5511 100644
--- a/src/lib/libc/stdlib/strtod.3
+++ b/src/lib/libc/stdlib/strtod.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,8 +29,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)strtod.3 5.3 (Berkeley) 6/29/91 32.\" $OpenBSD: strtod.3,v 1.8 2003/06/02 20:18:38 millert Exp $
37.\" $Id: strtod.3,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd June 29, 1991
40.Dt STRTOD 3 35.Dt STRTOD 3
@@ -51,20 +46,25 @@ string to double
51.Sh DESCRIPTION 46.Sh DESCRIPTION
52The 47The
53.Fn strtod 48.Fn strtod
54function converts the initial portion of the string 49function converts the initial portion of the string pointed to by
55pointed to by
56.Fa nptr 50.Fa nptr
57to 51to
58.Em double 52.Li double
59representation. 53representation.
60.Pp 54.Pp
61The expected form of the string is an optional plus (``+'') or minus 55The expected form of the string is an optional plus
62sign (``-'') followed by a sequence of digits optionally containing 56.Pq Ql +
57or minus sign
58.Pq Ql -
59followed by a sequence of digits optionally containing
63a decimal-point character, optionally followed by an exponent. 60a decimal-point character, optionally followed by an exponent.
64An exponent consists of an ``E'' or ``e'', followed by an optional plus 61An exponent consists of an
65or minus sign, followed by a sequence of digits. 62.Sq E
63or
64.Sq e ,
65followed by an optional plus or minus sign, followed by a sequence of digits.
66.Pp 66.Pp
67Leading white-space characters in the string (as defined by the 67Leading whitespace characters in the string (as defined by the
68.Xr isspace 3 68.Xr isspace 3
69function) are skipped. 69function) are skipped.
70.Sh RETURN VALUES 70.Sh RETURN VALUES
@@ -88,18 +88,18 @@ is stored in the location referenced by
88If the correct value would cause overflow, plus or minus 88If the correct value would cause overflow, plus or minus
89.Dv HUGE_VAL 89.Dv HUGE_VAL
90is returned (according to the sign of the value), and 90is returned (according to the sign of the value), and
91.Dv ERANGE 91.Er ERANGE
92is stored in 92is stored in
93.Va errno . 93.Va errno .
94If the correct value would cause underflow, zero is 94If the correct value would cause underflow, zero is returned and
95returned and 95.Er ERANGE
96.Dv ERANGE 96is stored in
97is stored in
98.Va errno . 97.Va errno .
99.Sh ERRORS 98.Sh ERRORS
100.Bl -tag -width Er 99.Bl -tag -width Er
101.It Bq Er ERANGE 100.It Bq Er ERANGE
102Overflow or underflow occurred. 101Overflow or underflow occurred.
102.El
103.Sh SEE ALSO 103.Sh SEE ALSO
104.Xr atof 3 , 104.Xr atof 3 ,
105.Xr atoi 3 , 105.Xr atoi 3 ,
@@ -109,6 +109,5 @@ Overflow or underflow occurred.
109.Sh STANDARDS 109.Sh STANDARDS
110The 110The
111.Fn strtod 111.Fn strtod
112function 112function conforms to
113conforms to
114.St -ansiC . 113.St -ansiC .
diff --git a/src/lib/libc/stdlib/strtod.c b/src/lib/libc/stdlib/strtod.c
index b13fa128f5..8e839d6155 100644
--- a/src/lib/libc/stdlib/strtod.c
+++ b/src/lib/libc/stdlib/strtod.c
@@ -90,12 +90,14 @@
90 */ 90 */
91 91
92#if defined(LIBC_SCCS) && !defined(lint) 92#if defined(LIBC_SCCS) && !defined(lint)
93static char *rcsid = "$Id: strtod.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $"; 93static char *rcsid = "$OpenBSD: strtod.c,v 1.19 2004/02/03 16:52:11 drahn Exp $";
94#endif /* LIBC_SCCS and not lint */ 94#endif /* LIBC_SCCS and not lint */
95 95
96#if defined(__m68k__) || defined(__sparc__) || defined(__i386__) || \ 96#if defined(__m68k__) || defined(__sparc__) || defined(__i386__) || \
97 defined(__mips__) || defined(__ns32k__) || defined(__alpha__) 97 defined(__mips__) || defined(__ns32k__) || defined(__alpha__) || \
98#include <machine/endian.h> 98 defined(__powerpc__) || defined(__m88k__) || defined(__hppa__) || \
99 defined(__x86_64__) || (defined(__arm__) && defined(__VFP_FP__))
100#include <sys/types.h>
99#if BYTE_ORDER == BIG_ENDIAN 101#if BYTE_ORDER == BIG_ENDIAN
100#define IEEE_BIG_ENDIAN 102#define IEEE_BIG_ENDIAN
101#else 103#else
@@ -103,7 +105,16 @@ static char *rcsid = "$Id: strtod.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $"
103#endif 105#endif
104#endif 106#endif
105 107
106#ifdef vax 108#if defined(__arm__) && !defined(__VFP_FP__)
109/*
110 * Although the CPU is little endian the FP has different
111 * byte and word endianness. The byte order is still little endian
112 * but the word order is big endian.
113 */
114#define IEEE_BIG_ENDIAN
115#endif
116
117#ifdef __vax__
107#define VAX 118#define VAX
108#endif 119#endif
109 120
@@ -143,7 +154,6 @@ extern void *MALLOC(size_t);
143#include "errno.h" 154#include "errno.h"
144 155
145#ifdef Bad_float_h 156#ifdef Bad_float_h
146#undef __STDC__
147#ifdef IEEE_BIG_ENDIAN 157#ifdef IEEE_BIG_ENDIAN
148#define IEEE_ARITHMETIC 158#define IEEE_ARITHMETIC
149#endif 159#endif
@@ -212,19 +222,24 @@ Exactly one of IEEE_LITTLE_ENDIAN IEEE_BIG_ENDIAN, VAX, or
212IBM should be defined. 222IBM should be defined.
213#endif 223#endif
214 224
225typedef union {
226 double d;
227 ULong ul[2];
228} _double;
229#define value(x) ((x).d)
215#ifdef IEEE_LITTLE_ENDIAN 230#ifdef IEEE_LITTLE_ENDIAN
216#define word0(x) ((ULong *)&x)[1] 231#define word0(x) ((x).ul[1])
217#define word1(x) ((ULong *)&x)[0] 232#define word1(x) ((x).ul[0])
218#else 233#else
219#define word0(x) ((ULong *)&x)[0] 234#define word0(x) ((x).ul[0])
220#define word1(x) ((ULong *)&x)[1] 235#define word1(x) ((x).ul[1])
221#endif 236#endif
222 237
223/* The following definition of Storeinc is appropriate for MIPS processors. 238/* The following definition of Storeinc is appropriate for MIPS processors.
224 * An alternative that might be better on some machines is 239 * An alternative that might be better on some machines is
225 * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff) 240 * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff)
226 */ 241 */
227#if defined(IEEE_LITTLE_ENDIAN) + defined(VAX) 242#if defined(IEEE_LITTLE_ENDIAN) + defined(VAX) + defined(__arm__)
228#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \ 243#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \
229((unsigned short *)a)[0] = (unsigned short)c, a++) 244((unsigned short *)a)[0] = (unsigned short)c, a++)
230#else 245#else
@@ -380,7 +395,7 @@ Balloc
380 int x; 395 int x;
381 Bigint *rv; 396 Bigint *rv;
382 397
383 if (rv = freelist[k]) { 398 if ((rv = freelist[k])) {
384 freelist[k] = rv->next; 399 freelist[k] = rv->next;
385 } 400 }
386 else { 401 else {
@@ -628,7 +643,7 @@ mult
628 xc0 = c->x; 643 xc0 = c->x;
629#ifdef Pack_32 644#ifdef Pack_32
630 for(; xb < xbe; xb++, xc0++) { 645 for(; xb < xbe; xb++, xc0++) {
631 if (y = *xb & 0xffff) { 646 if ((y = *xb & 0xffff)) {
632 x = xa; 647 x = xa;
633 xc = xc0; 648 xc = xc0;
634 carry = 0; 649 carry = 0;
@@ -642,7 +657,7 @@ mult
642 while(x < xae); 657 while(x < xae);
643 *xc = carry; 658 *xc = carry;
644 } 659 }
645 if (y = *xb >> 16) { 660 if ((y = *xb >> 16)) {
646 x = xa; 661 x = xa;
647 xc = xc0; 662 xc = xc0;
648 carry = 0; 663 carry = 0;
@@ -693,7 +708,7 @@ pow5mult
693 int i; 708 int i;
694 static int p05[3] = { 5, 25, 125 }; 709 static int p05[3] = { 5, 25, 125 };
695 710
696 if (i = k & 3) 711 if ((i = k & 3))
697 b = multadd(b, p05[i-1], 0); 712 b = multadd(b, p05[i-1], 0);
698 713
699 if (!(k >>= 2)) 714 if (!(k >>= 2))
@@ -756,7 +771,7 @@ lshift
756 z = *x++ >> k1; 771 z = *x++ >> k1;
757 } 772 }
758 while(x < xe); 773 while(x < xe);
759 if (*x1 = z) 774 if ((*x1 = z))
760 ++n1; 775 ++n1;
761 } 776 }
762#else 777#else
@@ -899,14 +914,16 @@ diff
899 static double 914 static double
900ulp 915ulp
901#ifdef KR_headers 916#ifdef KR_headers
902 (x) double x; 917 (_x) double _x;
903#else 918#else
904 (double x) 919 (double _x)
905#endif 920#endif
906{ 921{
922 _double x;
907 register Long L; 923 register Long L;
908 double a; 924 _double a;
909 925
926 value(x) = _x;
910 L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1; 927 L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1;
911#ifndef Sudden_Underflow 928#ifndef Sudden_Underflow
912 if (L > 0) { 929 if (L > 0) {
@@ -931,7 +948,7 @@ ulp
931 } 948 }
932 } 949 }
933#endif 950#endif
934 return a; 951 return value(a);
935 } 952 }
936 953
937 static double 954 static double
@@ -944,7 +961,7 @@ b2d
944{ 961{
945 ULong *xa, *xa0, w, y, z; 962 ULong *xa, *xa0, w, y, z;
946 int k; 963 int k;
947 double d; 964 _double d;
948#ifdef VAX 965#ifdef VAX
949 ULong d0, d1; 966 ULong d0, d1;
950#else 967#else
@@ -1001,22 +1018,27 @@ b2d
1001#undef d0 1018#undef d0
1002#undef d1 1019#undef d1
1003#endif 1020#endif
1004 return d; 1021 return value(d);
1005 } 1022 }
1006 1023
1007 static Bigint * 1024 static Bigint *
1008d2b 1025d2b
1009#ifdef KR_headers 1026#ifdef KR_headers
1010 (d, e, bits) double d; int *e, *bits; 1027 (_d, e, bits) double d; int *e, *bits;
1011#else 1028#else
1012 (double d, int *e, int *bits) 1029 (double _d, int *e, int *bits)
1013#endif 1030#endif
1014{ 1031{
1015 Bigint *b; 1032 Bigint *b;
1016 int de, i, k; 1033 int de, i, k;
1017 ULong *x, y, z; 1034 ULong *x, y, z;
1035 _double d;
1018#ifdef VAX 1036#ifdef VAX
1019 ULong d0, d1; 1037 ULong d0, d1;
1038#endif
1039
1040 value(d) = _d;
1041#ifdef VAX
1020 d0 = word0(d) >> 16 | word0(d) << 16; 1042 d0 = word0(d) >> 16 | word0(d) << 16;
1021 d1 = word1(d) >> 16 | word1(d) << 16; 1043 d1 = word1(d) >> 16 | word1(d) << 16;
1022#else 1044#else
@@ -1141,11 +1163,11 @@ ratio
1141 (Bigint *a, Bigint *b) 1163 (Bigint *a, Bigint *b)
1142#endif 1164#endif
1143{ 1165{
1144 double da, db; 1166 _double da, db;
1145 int k, ka, kb; 1167 int k, ka, kb;
1146 1168
1147 da = b2d(a, &ka); 1169 value(da) = b2d(a, &ka);
1148 db = b2d(b, &kb); 1170 value(db) = b2d(b, &kb);
1149#ifdef Pack_32 1171#ifdef Pack_32
1150 k = ka - kb + 32*(a->wds - b->wds); 1172 k = ka - kb + 32*(a->wds - b->wds);
1151#else 1173#else
@@ -1171,7 +1193,7 @@ ratio
1171 word0(db) += k*Exp_msk1; 1193 word0(db) += k*Exp_msk1;
1172 } 1194 }
1173#endif 1195#endif
1174 return da / db; 1196 return value(da) / value(db);
1175 } 1197 }
1176 1198
1177static CONST double 1199static CONST double
@@ -1211,7 +1233,8 @@ strtod
1211 int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign, 1233 int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign,
1212 e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign; 1234 e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
1213 CONST char *s, *s0, *s1; 1235 CONST char *s, *s0, *s1;
1214 double aadj, aadj1, adj, rv, rv0; 1236 double aadj, aadj1, adj;
1237 _double rv, rv0;
1215 Long L; 1238 Long L;
1216 ULong y, z; 1239 ULong y, z;
1217 Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; 1240 Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
@@ -1223,10 +1246,10 @@ strtod
1223#endif 1246#endif
1224 1247
1225 sign = nz0 = nz = 0; 1248 sign = nz0 = nz = 0;
1226 rv = 0.; 1249 value(rv) = 0.;
1227 1250
1228 1251
1229 for(s = s00; isspace(*s); s++) 1252 for(s = s00; isspace((unsigned char) *s); s++)
1230 ; 1253 ;
1231 1254
1232 if (*s == '-') { 1255 if (*s == '-') {
@@ -1340,9 +1363,9 @@ strtod
1340 if (!nd0) 1363 if (!nd0)
1341 nd0 = nd; 1364 nd0 = nd;
1342 k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; 1365 k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
1343 rv = y; 1366 value(rv) = y;
1344 if (k > 9) 1367 if (k > 9)
1345 rv = tens[k - 9] * rv + z; 1368 value(rv) = tens[k - 9] * value(rv) + z;
1346 bd0 = 0; 1369 bd0 = 0;
1347 if (nd <= DBL_DIG 1370 if (nd <= DBL_DIG
1348#ifndef RND_PRODQUOT 1371#ifndef RND_PRODQUOT
@@ -1356,7 +1379,8 @@ strtod
1356#ifdef VAX 1379#ifdef VAX
1357 goto vax_ovfl_check; 1380 goto vax_ovfl_check;
1358#else 1381#else
1359 /* rv = */ rounded_product(rv, tens[e]); 1382 /* value(rv) = */ rounded_product(value(rv),
1383 tens[e]);
1360 goto ret; 1384 goto ret;
1361#endif 1385#endif
1362 } 1386 }
@@ -1366,27 +1390,30 @@ strtod
1366 * this for larger i values. 1390 * this for larger i values.
1367 */ 1391 */
1368 e -= i; 1392 e -= i;
1369 rv *= tens[i]; 1393 value(rv) *= tens[i];
1370#ifdef VAX 1394#ifdef VAX
1371 /* VAX exponent range is so narrow we must 1395 /* VAX exponent range is so narrow we must
1372 * worry about overflow here... 1396 * worry about overflow here...
1373 */ 1397 */
1374 vax_ovfl_check: 1398 vax_ovfl_check:
1375 word0(rv) -= P*Exp_msk1; 1399 word0(rv) -= P*Exp_msk1;
1376 /* rv = */ rounded_product(rv, tens[e]); 1400 /* value(rv) = */ rounded_product(value(rv),
1401 tens[e]);
1377 if ((word0(rv) & Exp_mask) 1402 if ((word0(rv) & Exp_mask)
1378 > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) 1403 > Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
1379 goto ovfl; 1404 goto ovfl;
1380 word0(rv) += P*Exp_msk1; 1405 word0(rv) += P*Exp_msk1;
1381#else 1406#else
1382 /* rv = */ rounded_product(rv, tens[e]); 1407 /* value(rv) = */ rounded_product(value(rv),
1408 tens[e]);
1383#endif 1409#endif
1384 goto ret; 1410 goto ret;
1385 } 1411 }
1386 } 1412 }
1387#ifndef Inaccurate_Divide 1413#ifndef Inaccurate_Divide
1388 else if (e >= -Ten_pmax) { 1414 else if (e >= -Ten_pmax) {
1389 /* rv = */ rounded_quotient(rv, tens[-e]); 1415 /* value(rv) = */ rounded_quotient(value(rv),
1416 tens[-e]);
1390 goto ret; 1417 goto ret;
1391 } 1418 }
1392#endif 1419#endif
@@ -1397,13 +1424,13 @@ strtod
1397 1424
1398 if (e1 > 0) { 1425 if (e1 > 0) {
1399 if (i = e1 & 15) 1426 if (i = e1 & 15)
1400 rv *= tens[i]; 1427 value(rv) *= tens[i];
1401 if (e1 &= ~15) { 1428 if (e1 &= ~15) {
1402 if (e1 > DBL_MAX_10_EXP) { 1429 if (e1 > DBL_MAX_10_EXP) {
1403 ovfl: 1430 ovfl:
1404 errno = ERANGE; 1431 errno = ERANGE;
1405#ifdef __STDC__ 1432#ifndef Bad_float_h
1406 rv = HUGE_VAL; 1433 value(rv) = HUGE_VAL;
1407#else 1434#else
1408 /* Can't trust HUGE_VAL */ 1435 /* Can't trust HUGE_VAL */
1409#ifdef IEEE_Arith 1436#ifdef IEEE_Arith
@@ -1421,10 +1448,10 @@ strtod
1421 if (e1 >>= 4) { 1448 if (e1 >>= 4) {
1422 for(j = 0; e1 > 1; j++, e1 >>= 1) 1449 for(j = 0; e1 > 1; j++, e1 >>= 1)
1423 if (e1 & 1) 1450 if (e1 & 1)
1424 rv *= bigtens[j]; 1451 value(rv) *= bigtens[j];
1425 /* The last multiplication could overflow. */ 1452 /* The last multiplication could overflow. */
1426 word0(rv) -= P*Exp_msk1; 1453 word0(rv) -= P*Exp_msk1;
1427 rv *= bigtens[j]; 1454 value(rv) *= bigtens[j];
1428 if ((z = word0(rv) & Exp_mask) 1455 if ((z = word0(rv) & Exp_mask)
1429 > Exp_msk1*(DBL_MAX_EXP+Bias-P)) 1456 > Exp_msk1*(DBL_MAX_EXP+Bias-P))
1430 goto ovfl; 1457 goto ovfl;
@@ -1443,23 +1470,23 @@ strtod
1443 else if (e1 < 0) { 1470 else if (e1 < 0) {
1444 e1 = -e1; 1471 e1 = -e1;
1445 if (i = e1 & 15) 1472 if (i = e1 & 15)
1446 rv /= tens[i]; 1473 value(rv) /= tens[i];
1447 if (e1 &= ~15) { 1474 if (e1 &= ~15) {
1448 e1 >>= 4; 1475 e1 >>= 4;
1449 if (e1 >= 1 << n_bigtens) 1476 if (e1 >= 1 << n_bigtens)
1450 goto undfl; 1477 goto undfl;
1451 for(j = 0; e1 > 1; j++, e1 >>= 1) 1478 for(j = 0; e1 > 1; j++, e1 >>= 1)
1452 if (e1 & 1) 1479 if (e1 & 1)
1453 rv *= tinytens[j]; 1480 value(rv) *= tinytens[j];
1454 /* The last multiplication could underflow. */ 1481 /* The last multiplication could underflow. */
1455 rv0 = rv; 1482 value(rv0) = value(rv);
1456 rv *= tinytens[j]; 1483 value(rv) *= tinytens[j];
1457 if (!rv) { 1484 if (!value(rv)) {
1458 rv = 2.*rv0; 1485 value(rv) = 2.*value(rv0);
1459 rv *= tinytens[j]; 1486 value(rv) *= tinytens[j];
1460 if (!rv) { 1487 if (!value(rv)) {
1461 undfl: 1488 undfl:
1462 rv = 0.; 1489 value(rv) = 0.;
1463 errno = ERANGE; 1490 errno = ERANGE;
1464 if (bd0) 1491 if (bd0)
1465 goto retfree; 1492 goto retfree;
@@ -1483,7 +1510,7 @@ strtod
1483 for(;;) { 1510 for(;;) {
1484 bd = Balloc(bd0->k); 1511 bd = Balloc(bd0->k);
1485 Bcopy(bd, bd0); 1512 Bcopy(bd, bd0);
1486 bb = d2b(rv, &bbe, &bbbits); /* rv = bb * 2^bbe */ 1513 bb = d2b(value(rv), &bbe, &bbbits); /* rv = bb * 2^bbe */
1487 bs = i2b(1); 1514 bs = i2b(1);
1488 1515
1489 if (e >= 0) { 1516 if (e >= 0) {
@@ -1595,12 +1622,12 @@ strtod
1595 break; 1622 break;
1596#endif 1623#endif
1597 if (dsign) 1624 if (dsign)
1598 rv += ulp(rv); 1625 value(rv) += ulp(value(rv));
1599#ifndef ROUND_BIASED 1626#ifndef ROUND_BIASED
1600 else { 1627 else {
1601 rv -= ulp(rv); 1628 value(rv) -= ulp(value(rv));
1602#ifndef Sudden_Underflow 1629#ifndef Sudden_Underflow
1603 if (!rv) 1630 if (!value(rv))
1604 goto undfl; 1631 goto undfl;
1605#endif 1632#endif
1606 } 1633 }
@@ -1651,10 +1678,10 @@ strtod
1651 /* Check for overflow */ 1678 /* Check for overflow */
1652 1679
1653 if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { 1680 if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
1654 rv0 = rv; 1681 value(rv0) = value(rv);
1655 word0(rv) -= P*Exp_msk1; 1682 word0(rv) -= P*Exp_msk1;
1656 adj = aadj1 * ulp(rv); 1683 adj = aadj1 * ulp(value(rv));
1657 rv += adj; 1684 value(rv) += adj;
1658 if ((word0(rv) & Exp_mask) >= 1685 if ((word0(rv) & Exp_mask) >=
1659 Exp_msk1*(DBL_MAX_EXP+Bias-P)) { 1686 Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
1660 if (word0(rv0) == Big0 && word1(rv0) == Big1) 1687 if (word0(rv0) == Big0 && word1(rv0) == Big1)
@@ -1669,10 +1696,10 @@ strtod
1669 else { 1696 else {
1670#ifdef Sudden_Underflow 1697#ifdef Sudden_Underflow
1671 if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { 1698 if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
1672 rv0 = rv; 1699 value(rv0) = value(rv);
1673 word0(rv) += P*Exp_msk1; 1700 word0(rv) += P*Exp_msk1;
1674 adj = aadj1 * ulp(rv); 1701 adj = aadj1 * ulp(value(rv));
1675 rv += adj; 1702 value(rv) += adj;
1676#ifdef IBM 1703#ifdef IBM
1677 if ((word0(rv) & Exp_mask) < P*Exp_msk1) 1704 if ((word0(rv) & Exp_mask) < P*Exp_msk1)
1678#else 1705#else
@@ -1690,8 +1717,8 @@ strtod
1690 word0(rv) -= P*Exp_msk1; 1717 word0(rv) -= P*Exp_msk1;
1691 } 1718 }
1692 else { 1719 else {
1693 adj = aadj1 * ulp(rv); 1720 adj = aadj1 * ulp(value(rv));
1694 rv += adj; 1721 value(rv) += adj;
1695 } 1722 }
1696#else 1723#else
1697 /* Compute adj so that the IEEE rounding rules will 1724 /* Compute adj so that the IEEE rounding rules will
@@ -1706,8 +1733,8 @@ strtod
1706 if (!dsign) 1733 if (!dsign)
1707 aadj1 = -aadj1; 1734 aadj1 = -aadj1;
1708 } 1735 }
1709 adj = aadj1 * ulp(rv); 1736 adj = aadj1 * ulp(value(rv));
1710 rv += adj; 1737 value(rv) += adj;
1711#endif 1738#endif
1712 } 1739 }
1713 z = word0(rv) & Exp_mask; 1740 z = word0(rv) & Exp_mask;
@@ -1738,7 +1765,7 @@ strtod
1738 ret: 1765 ret:
1739 if (se) 1766 if (se)
1740 *se = (char *)s; 1767 *se = (char *)s;
1741 return sign ? -rv : rv; 1768 return sign ? -value(rv) : value(rv);
1742 } 1769 }
1743 1770
1744 static int 1771 static int
@@ -1884,10 +1911,10 @@ quorem
1884 char * 1911 char *
1885__dtoa 1912__dtoa
1886#ifdef KR_headers 1913#ifdef KR_headers
1887 (d, mode, ndigits, decpt, sign, rve) 1914 (_d, mode, ndigits, decpt, sign, rve)
1888 double d; int mode, ndigits, *decpt, *sign; char **rve; 1915 double _d; int mode, ndigits, *decpt, *sign; char **rve;
1889#else 1916#else
1890 (double d, int mode, int ndigits, int *decpt, int *sign, char **rve) 1917 (double _d, int mode, int ndigits, int *decpt, int *sign, char **rve)
1891#endif 1918#endif
1892{ 1919{
1893 /* Arguments ndigits, decpt, sign are similar to those 1920 /* Arguments ndigits, decpt, sign are similar to those
@@ -1933,11 +1960,13 @@ __dtoa
1933 ULong x; 1960 ULong x;
1934#endif 1961#endif
1935 Bigint *b, *b1, *delta, *mlo, *mhi, *S; 1962 Bigint *b, *b1, *delta, *mlo, *mhi, *S;
1936 double d2, ds, eps; 1963 double ds;
1937 char *s, *s0; 1964 char *s, *s0;
1938 static Bigint *result; 1965 static Bigint *result;
1939 static int result_k; 1966 static int result_k;
1967 _double d, d2, eps;
1940 1968
1969 value(d) = _d;
1941 if (result) { 1970 if (result) {
1942 result->k = result_k; 1971 result->k = result_k;
1943 result->maxwds = 1 << result_k; 1972 result->maxwds = 1 << result_k;
@@ -1964,7 +1993,7 @@ __dtoa
1964 *decpt = 9999; 1993 *decpt = 9999;
1965 s = 1994 s =
1966#ifdef IEEE_Arith 1995#ifdef IEEE_Arith
1967 !word1(d) && !(word0(d) & 0xfffff) ? "Infinity" : 1996 !word1(d) && !(word0(d) & 0xfffff) ? ndigits < 8 ? "Inf" : "Infinity" :
1968#endif 1997#endif
1969 "NaN"; 1998 "NaN";
1970 if (rve) 1999 if (rve)
@@ -1977,9 +2006,9 @@ __dtoa
1977 } 2006 }
1978#endif 2007#endif
1979#ifdef IBM 2008#ifdef IBM
1980 d += 0; /* normalize */ 2009 value(d) += 0; /* normalize */
1981#endif 2010#endif
1982 if (!d) { 2011 if (!value(d)) {
1983 *decpt = 1; 2012 *decpt = 1;
1984 s = "0"; 2013 s = "0";
1985 if (rve) 2014 if (rve)
@@ -1987,18 +2016,18 @@ __dtoa
1987 return s; 2016 return s;
1988 } 2017 }
1989 2018
1990 b = d2b(d, &be, &bbits); 2019 b = d2b(value(d), &be, &bbits);
1991#ifdef Sudden_Underflow 2020#ifdef Sudden_Underflow
1992 i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); 2021 i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
1993#else 2022#else
1994 if (i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) { 2023 if (i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) {
1995#endif 2024#endif
1996 d2 = d; 2025 value(d2) = value(d);
1997 word0(d2) &= Frac_mask1; 2026 word0(d2) &= Frac_mask1;
1998 word0(d2) |= Exp_11; 2027 word0(d2) |= Exp_11;
1999#ifdef IBM 2028#ifdef IBM
2000 if (j = 11 - hi0bits(word0(d2) & Frac_mask)) 2029 if (j = 11 - hi0bits(word0(d2) & Frac_mask))
2001 d2 /= 1 << j; 2030 value(d2) /= 1 << j;
2002#endif 2031#endif
2003 2032
2004 /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 2033 /* log(x) ~=~ log(1.5) + (x-1.5)/1.5
@@ -2037,19 +2066,20 @@ __dtoa
2037 i = bbits + be + (Bias + (P-1) - 1); 2066 i = bbits + be + (Bias + (P-1) - 1);
2038 x = i > 32 ? word0(d) << 64 - i | word1(d) >> i - 32 2067 x = i > 32 ? word0(d) << 64 - i | word1(d) >> i - 32
2039 : word1(d) << 32 - i; 2068 : word1(d) << 32 - i;
2040 d2 = x; 2069 value(d2) = x;
2041 word0(d2) -= 31*Exp_msk1; /* adjust exponent */ 2070 word0(d2) -= 31*Exp_msk1; /* adjust exponent */
2042 i -= (Bias + (P-1) - 1) + 1; 2071 i -= (Bias + (P-1) - 1) + 1;
2043 denorm = 1; 2072 denorm = 1;
2044 } 2073 }
2045#endif 2074#endif
2046 ds = (d2-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; 2075 ds = (value(d2)-1.5)*0.289529654602168 + 0.1760912590558 +
2076 i*0.301029995663981;
2047 k = (int)ds; 2077 k = (int)ds;
2048 if (ds < 0. && ds != k) 2078 if (ds < 0. && ds != k)
2049 k--; /* want k = floor(ds) */ 2079 k--; /* want k = floor(ds) */
2050 k_check = 1; 2080 k_check = 1;
2051 if (k >= 0 && k <= Ten_pmax) { 2081 if (k >= 0 && k <= Ten_pmax) {
2052 if (d < tens[k]) 2082 if (value(d) < tens[k])
2053 k--; 2083 k--;
2054 k_check = 0; 2084 k_check = 0;
2055 } 2085 }
@@ -2116,7 +2146,7 @@ __dtoa
2116 /* Try to get by with floating-point arithmetic. */ 2146 /* Try to get by with floating-point arithmetic. */
2117 2147
2118 i = 0; 2148 i = 0;
2119 d2 = d; 2149 value(d2) = value(d);
2120 k0 = k; 2150 k0 = k;
2121 ilim0 = ilim; 2151 ilim0 = ilim;
2122 ieps = 2; /* conservative */ 2152 ieps = 2; /* conservative */
@@ -2126,7 +2156,7 @@ __dtoa
2126 if (j & Bletch) { 2156 if (j & Bletch) {
2127 /* prevent overflows */ 2157 /* prevent overflows */
2128 j &= Bletch - 1; 2158 j &= Bletch - 1;
2129 d /= bigtens[n_bigtens-1]; 2159 value(d) /= bigtens[n_bigtens-1];
2130 ieps++; 2160 ieps++;
2131 } 2161 }
2132 for(; j; j >>= 1, i++) 2162 for(; j; j >>= 1, i++)
@@ -2134,32 +2164,32 @@ __dtoa
2134 ieps++; 2164 ieps++;
2135 ds *= bigtens[i]; 2165 ds *= bigtens[i];
2136 } 2166 }
2137 d /= ds; 2167 value(d) /= ds;
2138 } 2168 }
2139 else if (j1 = -k) { 2169 else if (j1 = -k) {
2140 d *= tens[j1 & 0xf]; 2170 value(d) *= tens[j1 & 0xf];
2141 for(j = j1 >> 4; j; j >>= 1, i++) 2171 for(j = j1 >> 4; j; j >>= 1, i++)
2142 if (j & 1) { 2172 if (j & 1) {
2143 ieps++; 2173 ieps++;
2144 d *= bigtens[i]; 2174 value(d) *= bigtens[i];
2145 } 2175 }
2146 } 2176 }
2147 if (k_check && d < 1. && ilim > 0) { 2177 if (k_check && value(d) < 1. && ilim > 0) {
2148 if (ilim1 <= 0) 2178 if (ilim1 <= 0)
2149 goto fast_failed; 2179 goto fast_failed;
2150 ilim = ilim1; 2180 ilim = ilim1;
2151 k--; 2181 k--;
2152 d *= 10.; 2182 value(d) *= 10.;
2153 ieps++; 2183 ieps++;
2154 } 2184 }
2155 eps = ieps*d + 7.; 2185 value(eps) = ieps*value(d) + 7.;
2156 word0(eps) -= (P-1)*Exp_msk1; 2186 word0(eps) -= (P-1)*Exp_msk1;
2157 if (ilim == 0) { 2187 if (ilim == 0) {
2158 S = mhi = 0; 2188 S = mhi = 0;
2159 d -= 5.; 2189 value(d) -= 5.;
2160 if (d > eps) 2190 if (value(d) > value(eps))
2161 goto one_digit; 2191 goto one_digit;
2162 if (d < -eps) 2192 if (value(d) < -value(eps))
2163 goto no_digits; 2193 goto no_digits;
2164 goto fast_failed; 2194 goto fast_failed;
2165 } 2195 }
@@ -2168,33 +2198,33 @@ __dtoa
2168 /* Use Steele & White method of only 2198 /* Use Steele & White method of only
2169 * generating digits needed. 2199 * generating digits needed.
2170 */ 2200 */
2171 eps = 0.5/tens[ilim-1] - eps; 2201 value(eps) = 0.5/tens[ilim-1] - value(eps);
2172 for(i = 0;;) { 2202 for(i = 0;;) {
2173 L = d; 2203 L = value(d);
2174 d -= L; 2204 value(d) -= L;
2175 *s++ = '0' + (int)L; 2205 *s++ = '0' + (int)L;
2176 if (d < eps) 2206 if (value(d) < value(eps))
2177 goto ret1; 2207 goto ret1;
2178 if (1. - d < eps) 2208 if (1. - value(d) < value(eps))
2179 goto bump_up; 2209 goto bump_up;
2180 if (++i >= ilim) 2210 if (++i >= ilim)
2181 break; 2211 break;
2182 eps *= 10.; 2212 value(eps) *= 10.;
2183 d *= 10.; 2213 value(d) *= 10.;
2184 } 2214 }
2185 } 2215 }
2186 else { 2216 else {
2187#endif 2217#endif
2188 /* Generate ilim digits, then fix them up. */ 2218 /* Generate ilim digits, then fix them up. */
2189 eps *= tens[ilim-1]; 2219 value(eps) *= tens[ilim-1];
2190 for(i = 1;; i++, d *= 10.) { 2220 for(i = 1;; i++, value(d) *= 10.) {
2191 L = d; 2221 L = value(d);
2192 d -= L; 2222 value(d) -= L;
2193 *s++ = '0' + (int)L; 2223 *s++ = '0' + (int)L;
2194 if (i == ilim) { 2224 if (i == ilim) {
2195 if (d > 0.5 + eps) 2225 if (value(d) > 0.5 + value(eps))
2196 goto bump_up; 2226 goto bump_up;
2197 else if (d < 0.5 - eps) { 2227 else if (value(d) < 0.5 - value(eps)) {
2198 while(*--s == '0'); 2228 while(*--s == '0');
2199 s++; 2229 s++;
2200 goto ret1; 2230 goto ret1;
@@ -2207,7 +2237,7 @@ __dtoa
2207#endif 2237#endif
2208 fast_failed: 2238 fast_failed:
2209 s = s0; 2239 s = s0;
2210 d = d2; 2240 value(d) = value(d2);
2211 k = k0; 2241 k = k0;
2212 ilim = ilim0; 2242 ilim = ilim0;
2213 } 2243 }
@@ -2219,24 +2249,24 @@ __dtoa
2219 ds = tens[k]; 2249 ds = tens[k];
2220 if (ndigits < 0 && ilim <= 0) { 2250 if (ndigits < 0 && ilim <= 0) {
2221 S = mhi = 0; 2251 S = mhi = 0;
2222 if (ilim < 0 || d <= 5*ds) 2252 if (ilim < 0 || value(d) <= 5*ds)
2223 goto no_digits; 2253 goto no_digits;
2224 goto one_digit; 2254 goto one_digit;
2225 } 2255 }
2226 for(i = 1;; i++) { 2256 for(i = 1;; i++) {
2227 L = d / ds; 2257 L = value(d) / ds;
2228 d -= L*ds; 2258 value(d) -= L*ds;
2229#ifdef Check_FLT_ROUNDS 2259#ifdef Check_FLT_ROUNDS
2230 /* If FLT_ROUNDS == 2, L will usually be high by 1 */ 2260 /* If FLT_ROUNDS == 2, L will usually be high by 1 */
2231 if (d < 0) { 2261 if (value(d) < 0) {
2232 L--; 2262 L--;
2233 d += ds; 2263 value(d) += ds;
2234 } 2264 }
2235#endif 2265#endif
2236 *s++ = '0' + (int)L; 2266 *s++ = '0' + (int)L;
2237 if (i == ilim) { 2267 if (i == ilim) {
2238 d += d; 2268 value(d) += value(d);
2239 if (d > ds || d == ds && L & 1) { 2269 if (value(d) > ds || value(d) == ds && L & 1) {
2240 bump_up: 2270 bump_up:
2241 while(*--s == '9') 2271 while(*--s == '9')
2242 if (s == s0) { 2272 if (s == s0) {
@@ -2248,7 +2278,7 @@ __dtoa
2248 } 2278 }
2249 break; 2279 break;
2250 } 2280 }
2251 if (!(d *= 10.)) 2281 if (!(value(d) *= 10.))
2252 break; 2282 break;
2253 } 2283 }
2254 goto ret1; 2284 goto ret1;
diff --git a/src/lib/libc/stdlib/strtol.3 b/src/lib/libc/stdlib/strtol.3
index 808ba90165..3f5375c5e3 100644
--- a/src/lib/libc/stdlib/strtol.3
+++ b/src/lib/libc/stdlib/strtol.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,49 +29,57 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)strtol.3 5.4 (Berkeley) 6/25/92 32.\" $OpenBSD: strtol.3,v 1.13 2003/06/02 20:18:38 millert Exp $
37.\" $Id: strtol.3,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $
38.\" 33.\"
39.Dd June 25, 1992 34.Dd June 25, 1992
40.Dt STRTOL 3 35.Dt STRTOL 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
43.Nm strtol, strtoq 38.Nm strtol ,
44.Nd convert string value to a long or quad_t integer 39.Nm strtoll ,
40.Nm strtoq
41.Nd "convert string value to a long or long long integer"
45.Sh SYNOPSIS 42.Sh SYNOPSIS
46.Fd #include <stdlib.h> 43.Fd #include <stdlib.h>
47.Fd #include <limits.h> 44.Fd #include <limits.h>
48.Ft long 45.Ft long
49.Fn strtol "char *nptr" "char **endptr" "int base" 46.Fn strtol "const char *nptr" "char **endptr" "int base"
50 47.Pp
48.Fd #include <stdlib.h>
49.Fd #include <limits.h>
50.Ft long long
51.Fn strtoll "const char *nptr" "char **endptr" "int base"
52.Pp
51.Fd #include <sys/types.h> 53.Fd #include <sys/types.h>
52.Fd #include <stdlib.h> 54.Fd #include <stdlib.h>
53.Fd #include <limits.h> 55.Fd #include <limits.h>
54.Ft quad_t 56.Ft quad_t
55.Fn strtoq "char *nptr" "char **endptr" "int base" 57.Fn strtoq "const char *nptr" "char **endptr" "int base"
56.Sh DESCRIPTION 58.Sh DESCRIPTION
57The 59The
58.Fn strtol 60.Fn strtol
59function 61function converts the string in
60converts the string in
61.Fa nptr 62.Fa nptr
62to a 63to a
63.Em long 64.Li long
64value. 65value.
65The 66The
66.Fn strtoq 67.Fn strtoll
67function 68function converts the string in
68converts the string in
69.Fa nptr 69.Fa nptr
70to a 70to a
71.Em quad_t 71.Li long long
72value. 72value.
73The
74.Fn strtoq
75function is a deprecated equivalent of
76.Fn strtoll
77and is provided for backwards compatibility with legacy programs.
73The conversion is done according to the given 78The conversion is done according to the given
74.Fa base , 79.Fa base ,
75which must be between 2 and 36 inclusive, 80which must be a number between 2 and 36 inclusive or the special value 0.
76or be the special value 0.
77.Pp 81.Pp
78The string may begin with an arbitrary amount of white space 82The string may begin with an arbitrary amount of whitespace
79(as determined by 83(as determined by
80.Xr isspace 3 ) 84.Xr isspace 3 )
81followed by a single optional 85followed by a single optional
@@ -85,25 +89,22 @@ or
85sign. 89sign.
86If 90If
87.Fa base 91.Fa base
88is zero or 16, 92is zero or 16, the string may then include a
89the string may then include a
90.Ql 0x 93.Ql 0x
91prefix, 94prefix, and the number will be read in base 16; otherwise, a zero
92and the number will be read in base 16; otherwise, a zero
93.Fa base 95.Fa base
94is taken as 10 (decimal) unless the next character is 96is taken as 10 (decimal) unless the next character is
95.Ql 0 , 97.Ql 0 ,
96in which case it is taken as 8 (octal). 98in which case it is taken as 8 (octal).
97.Pp 99.Pp
98The remainder of the string is converted to a 100The remainder of the string is converted to a
99.Em long 101.Li long
100value in the obvious manner, 102value in the obvious manner,
101stopping at the first character which is not a valid digit 103stopping at the first character which is not a valid digit
102in the given base. 104in the given base.
103(In bases above 10, the letter 105(In bases above 10, the letter
104.Ql A 106.Ql A
105in either upper or lower case 107in either upper or lower case represents 10,
106represents 10,
107.Ql B 108.Ql B
108represents 11, and so forth, with 109represents 11, and so forth, with
109.Ql Z 110.Ql Z
@@ -111,7 +112,7 @@ representing 35.)
111.Pp 112.Pp
112If 113If
113.Fa endptr 114.Fa endptr
114is non nil, 115is non-null,
115.Fn strtol 116.Fn strtol
116stores the address of the first invalid character in 117stores the address of the first invalid character in
117.Fa *endptr . 118.Fa *endptr .
@@ -133,8 +134,7 @@ on return, the entire string was valid.)
133.Sh RETURN VALUES 134.Sh RETURN VALUES
134The 135The
135.Fn strtol 136.Fn strtol
136function 137function returns the result of the conversion,
137returns the result of the conversion,
138unless the value would underflow or overflow. 138unless the value would underflow or overflow.
139If an underflow occurs, 139If an underflow occurs,
140.Fn strtol 140.Fn strtol
@@ -148,6 +148,76 @@ In both cases,
148.Va errno 148.Va errno
149is set to 149is set to
150.Er ERANGE . 150.Er ERANGE .
151.Pp
152The
153.Fn strtoll
154function has identical return values except that
155.Dv LLONG_MIN
156and
157.Dv LLONG_MAX
158are used to indicate underflow and overflow respectively.
159.Sh EXAMPLES
160Ensuring that a string is a valid number (i.e., in range and containing no
161trailing characters) requires clearing
162.Va errno
163beforehand explicitly since
164.Va errno
165is not changed on a successful call to
166.Fn strtol ,
167and the return value of
168.Fn strtol
169cannot be used unambiguously to signal an error:
170.Bd -literal -offset indent
171char *ep;
172long lval;
173
174\&...
175
176errno = 0;
177lval = strtol(buf, &ep, 10);
178if (buf[0] == '\e0' || *ep != '\e0')
179 goto not_a_number;
180if (errno == ERANGE && (lval == LONG_MAX || lval == LONG_MIN))
181 goto out_of_range;
182.Ed
183.Pp
184This example will accept
185.Dq 12
186but not
187.Dq 12foo
188or
189.Dq 12\en .
190If trailing whitespace is acceptable, further checks must be done on
191.Va *ep ;
192alternately, use
193.Xr sscanf 3 .
194.Pp
195If
196.Fn strtol
197is being used instead of
198.Xr atoi 3 ,
199error checking is further complicated because the desired return value is an
200.Li int
201rather than a
202.Li long ;
203however, on some architectures integers and long integers are the same size.
204Thus the following is necessary:
205.Bd -literal -offset indent
206char *ep;
207int ival;
208long lval;
209
210\&...
211
212errno = 0;
213lval = strtol(buf, &ep, 10);
214if (buf[0] == '\e0' || *ep != '\e0')
215 goto not_a_number;
216if ((errno == ERANGE && (lval == LONG_MAX || lval == LONG_MIN)) ||
217 (lval > INT_MAX || lval < INT_MIN))
218 goto out_of_range;
219ival = lval;
220.Ed
151.Sh ERRORS 221.Sh ERRORS
152.Bl -tag -width Er 222.Bl -tag -width Er
153.It Bq Er ERANGE 223.It Bq Er ERANGE
@@ -157,13 +227,21 @@ The given string was out of range; the value converted has been clamped.
157.Xr atof 3 , 227.Xr atof 3 ,
158.Xr atoi 3 , 228.Xr atoi 3 ,
159.Xr atol 3 , 229.Xr atol 3 ,
230.Xr atoll 3 ,
231.Xr sscanf 3 ,
160.Xr strtod 3 , 232.Xr strtod 3 ,
161.Xr strtoul 3 233.Xr strtoul 3
162.Sh STANDARDS 234.Sh STANDARDS
163The 235The
164.Fn strtol 236.Fn strtol
165function 237and
166conforms to 238.Fn strtoll
167.St -ansiC . 239functions conform to
240.St -ansiC-99 .
241The
242.Fn strtoq
243function is a
244.Bx
245extension and is provided for backwards compatibility with legacy programs.
168.Sh BUGS 246.Sh BUGS
169Ignores the current locale. 247Ignores the current locale.
diff --git a/src/lib/libc/stdlib/strtol.c b/src/lib/libc/stdlib/strtol.c
index 6f374abd5f..1c39720794 100644
--- a/src/lib/libc/stdlib/strtol.c
+++ b/src/lib/libc/stdlib/strtol.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,13 +28,12 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)strtol.c 5.4 (Berkeley) 2/23/91";*/ 31static char *rcsid = "$OpenBSD: strtol.c,v 1.5 2003/06/02 20:18:38 millert Exp $";
36static char *rcsid = "$Id: strtol.c,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
39#include <limits.h>
40#include <ctype.h> 34#include <ctype.h>
41#include <errno.h> 35#include <errno.h>
36#include <limits.h>
42#include <stdlib.h> 37#include <stdlib.h>
43 38
44 39
@@ -54,25 +49,28 @@ strtol(nptr, endptr, base)
54 char **endptr; 49 char **endptr;
55 register int base; 50 register int base;
56{ 51{
57 register const char *s = nptr; 52 register const char *s;
58 register unsigned long acc; 53 register long acc, cutoff;
59 register int c; 54 register int c;
60 register unsigned long cutoff; 55 register int neg, any, cutlim;
61 register int neg = 0, any, cutlim;
62 56
63 /* 57 /*
64 * Skip white space and pick up leading +/- sign if any. 58 * Skip white space and pick up leading +/- sign if any.
65 * If base is 0, allow 0x for hex and 0 for octal, else 59 * If base is 0, allow 0x for hex and 0 for octal, else
66 * assume decimal; if base is already 16, allow 0x. 60 * assume decimal; if base is already 16, allow 0x.
67 */ 61 */
62 s = nptr;
68 do { 63 do {
69 c = *s++; 64 c = (unsigned char) *s++;
70 } while (isspace(c)); 65 } while (isspace(c));
71 if (c == '-') { 66 if (c == '-') {
72 neg = 1; 67 neg = 1;
73 c = *s++; 68 c = *s++;
74 } else if (c == '+') 69 } else {
75 c = *s++; 70 neg = 0;
71 if (c == '+')
72 c = *s++;
73 }
76 if ((base == 0 || base == 16) && 74 if ((base == 0 || base == 16) &&
77 c == '0' && (*s == 'x' || *s == 'X')) { 75 c == '0' && (*s == 'x' || *s == 'X')) {
78 c = s[1]; 76 c = s[1];
@@ -99,10 +97,17 @@ strtol(nptr, endptr, base)
99 * Set any if any `digits' consumed; make it negative to indicate 97 * Set any if any `digits' consumed; make it negative to indicate
100 * overflow. 98 * overflow.
101 */ 99 */
102 cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX; 100 cutoff = neg ? LONG_MIN : LONG_MAX;
103 cutlim = cutoff % (unsigned long)base; 101 cutlim = cutoff % base;
104 cutoff /= (unsigned long)base; 102 cutoff /= base;
105 for (acc = 0, any = 0;; c = *s++) { 103 if (neg) {
104 if (cutlim > 0) {
105 cutlim -= base;
106 cutoff += 1;
107 }
108 cutlim = -cutlim;
109 }
110 for (acc = 0, any = 0;; c = (unsigned char) *s++) {
106 if (isdigit(c)) 111 if (isdigit(c))
107 c -= '0'; 112 c -= '0';
108 else if (isalpha(c)) 113 else if (isalpha(c))
@@ -111,19 +116,30 @@ strtol(nptr, endptr, base)
111 break; 116 break;
112 if (c >= base) 117 if (c >= base)
113 break; 118 break;
114 if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) 119 if (any < 0)
115 any = -1; 120 continue;
116 else { 121 if (neg) {
117 any = 1; 122 if (acc < cutoff || acc == cutoff && c > cutlim) {
118 acc *= base; 123 any = -1;
119 acc += c; 124 acc = LONG_MIN;
125 errno = ERANGE;
126 } else {
127 any = 1;
128 acc *= base;
129 acc -= c;
130 }
131 } else {
132 if (acc > cutoff || acc == cutoff && c > cutlim) {
133 any = -1;
134 acc = LONG_MAX;
135 errno = ERANGE;
136 } else {
137 any = 1;
138 acc *= base;
139 acc += c;
140 }
120 } 141 }
121 } 142 }
122 if (any < 0) {
123 acc = neg ? LONG_MIN : LONG_MAX;
124 errno = ERANGE;
125 } else if (neg)
126 acc = -acc;
127 if (endptr != 0) 143 if (endptr != 0)
128 *endptr = (char *) (any ? s - 1 : nptr); 144 *endptr = (char *) (any ? s - 1 : nptr);
129 return (acc); 145 return (acc);
diff --git a/src/lib/libc/stdlib/strtoq.c b/src/lib/libc/stdlib/strtoll.c
index fc559e9d7f..ac9353890f 100644
--- a/src/lib/libc/stdlib/strtoq.c
+++ b/src/lib/libc/stdlib/strtoll.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,33 +28,32 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35static char sccsid[] = "@(#)strtoq.c 5.1 (Berkeley) 6/26/92"; 31static const char rcsid[] = "$OpenBSD: strtoll.c,v 1.2 2003/06/02 20:18:38 millert Exp $";
36#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
37 33
38#include <sys/types.h> 34#include <sys/types.h>
39 35
40#include <limits.h>
41#include <errno.h>
42#include <ctype.h> 36#include <ctype.h>
37#include <errno.h>
38#include <limits.h>
43#include <stdlib.h> 39#include <stdlib.h>
44 40
45/* 41/*
46 * Convert a string to a quad integer. 42 * Convert a string to a long long.
47 * 43 *
48 * Ignores `locale' stuff. Assumes that the upper and lower case 44 * Ignores `locale' stuff. Assumes that the upper and lower case
49 * alphabets and digits are each contiguous. 45 * alphabets and digits are each contiguous.
50 */ 46 */
51quad_t 47long long
52strtoq(nptr, endptr, base) 48strtoll(nptr, endptr, base)
53 const char *nptr; 49 const char *nptr;
54 char **endptr; 50 char **endptr;
55 register int base; 51 int base;
56{ 52{
57 register const char *s; 53 const char *s;
58 register u_quad_t acc; 54 long long acc, cutoff;
59 register int c; 55 int c;
60 register u_quad_t qbase, cutoff; 56 int neg, any, cutlim;
61 register int neg, any, cutlim;
62 57
63 /* 58 /*
64 * Skip white space and pick up leading +/- sign if any. 59 * Skip white space and pick up leading +/- sign if any.
@@ -67,7 +62,7 @@ strtoq(nptr, endptr, base)
67 */ 62 */
68 s = nptr; 63 s = nptr;
69 do { 64 do {
70 c = *s++; 65 c = (unsigned char) *s++;
71 } while (isspace(c)); 66 } while (isspace(c));
72 if (c == '-') { 67 if (c == '-') {
73 neg = 1; 68 neg = 1;
@@ -93,7 +88,7 @@ strtoq(nptr, endptr, base)
93 * followed by a legal input character, is too big. One that 88 * followed by a legal input character, is too big. One that
94 * is equal to this value may be valid or not; the limit 89 * is equal to this value may be valid or not; the limit
95 * between valid and invalid numbers is then based on the last 90 * between valid and invalid numbers is then based on the last
96 * digit. For instance, if the range for quads is 91 * digit. For instance, if the range for long longs is
97 * [-9223372036854775808..9223372036854775807] and the input base 92 * [-9223372036854775808..9223372036854775807] and the input base
98 * is 10, cutoff will be set to 922337203685477580 and cutlim to 93 * is 10, cutoff will be set to 922337203685477580 and cutlim to
99 * either 7 (neg==0) or 8 (neg==1), meaning that if we have 94 * either 7 (neg==0) or 8 (neg==1), meaning that if we have
@@ -104,11 +99,17 @@ strtoq(nptr, endptr, base)
104 * Set any if any `digits' consumed; make it negative to indicate 99 * Set any if any `digits' consumed; make it negative to indicate
105 * overflow. 100 * overflow.
106 */ 101 */
107 qbase = (unsigned)base; 102 cutoff = neg ? LLONG_MIN : LLONG_MAX;
108 cutoff = neg ? -(u_quad_t)QUAD_MIN : QUAD_MAX; 103 cutlim = cutoff % base;
109 cutlim = cutoff % qbase; 104 cutoff /= base;
110 cutoff /= qbase; 105 if (neg) {
111 for (acc = 0, any = 0;; c = *s++) { 106 if (cutlim > 0) {
107 cutlim -= base;
108 cutoff += 1;
109 }
110 cutlim = -cutlim;
111 }
112 for (acc = 0, any = 0;; c = (unsigned char) *s++) {
112 if (isdigit(c)) 113 if (isdigit(c))
113 c -= '0'; 114 c -= '0';
114 else if (isalpha(c)) 115 else if (isalpha(c))
@@ -117,20 +118,45 @@ strtoq(nptr, endptr, base)
117 break; 118 break;
118 if (c >= base) 119 if (c >= base)
119 break; 120 break;
120 if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) 121 if (any < 0)
121 any = -1; 122 continue;
122 else { 123 if (neg) {
123 any = 1; 124 if (acc < cutoff || (acc == cutoff && c > cutlim)) {
124 acc *= qbase; 125 any = -1;
125 acc += c; 126 acc = LLONG_MIN;
127 errno = ERANGE;
128 } else {
129 any = 1;
130 acc *= base;
131 acc -= c;
132 }
133 } else {
134 if (acc > cutoff || (acc == cutoff && c > cutlim)) {
135 any = -1;
136 acc = LLONG_MAX;
137 errno = ERANGE;
138 } else {
139 any = 1;
140 acc *= base;
141 acc += c;
142 }
126 } 143 }
127 } 144 }
128 if (any < 0) {
129 acc = neg ? QUAD_MIN : QUAD_MAX;
130 errno = ERANGE;
131 } else if (neg)
132 acc = -acc;
133 if (endptr != 0) 145 if (endptr != 0)
134 *endptr = (char *) (any ? s - 1 : nptr); 146 *endptr = (char *) (any ? s - 1 : nptr);
135 return (acc); 147 return (acc);
136} 148}
149
150#ifdef __weak_alias
151__weak_alias(strtoq, strtoll);
152#else
153quad_t
154strtoq(nptr, endptr, base)
155 const char *nptr;
156 char **endptr;
157 int base;
158{
159
160 return ((quad_t)strtoll(nptr, endptr, base);
161}
162#endif
diff --git a/src/lib/libc/stdlib/strtoul.3 b/src/lib/libc/stdlib/strtoul.3
index db551b0141..4f6d6a51f9 100644
--- a/src/lib/libc/stdlib/strtoul.3
+++ b/src/lib/libc/stdlib/strtoul.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,21 +29,27 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)strtoul.3 5.4 (Berkeley) 6/25/92 32.\" $OpenBSD: strtoul.3,v 1.15 2003/06/02 20:18:38 millert Exp $
37.\" $Id: strtoul.3,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $
38.\" 33.\"
39.Dd June 25, 1992 34.Dd June 25, 1992
40.Dt STRTOUL 3 35.Dt STRTOUL 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
43.Nm strtoul, strtouq 38.Nm strtoul ,
44.Nd convert a string to an unsigned long or uquad_t integer 39.Nm strtoull ,
40.Nm strtouq
41.Nd "convert a string to an unsigned long or unsigned long long integer"
45.Sh SYNOPSIS 42.Sh SYNOPSIS
46.Fd #include <stdlib.h> 43.Fd #include <stdlib.h>
47.Fd #include <limits.h> 44.Fd #include <limits.h>
48.Ft unsigned long 45.Ft unsigned long
49.Fn strtoul "const char *nptr" "char **endptr" "int base" 46.Fn strtoul "const char *nptr" "char **endptr" "int base"
50 47.Pp
48.Fd #include <stdlib.h>
49.Fd #include <limits.h>
50.Ft unsigned long long
51.Fn strtoull "const char *nptr" "char **endptr" "int base"
52.Pp
51.Fd #include <sys/types.h> 53.Fd #include <sys/types.h>
52.Fd #include <stdlib.h> 54.Fd #include <stdlib.h>
53.Fd #include <limits.h> 55.Fd #include <limits.h>
@@ -56,26 +58,34 @@
56.Sh DESCRIPTION 58.Sh DESCRIPTION
57The 59The
58.Fn strtoul 60.Fn strtoul
59function 61function converts the string in
60converts the string in
61.Fa nptr 62.Fa nptr
62to an 63to an
63.Em unsigned long 64.Li unsigned long
64value. 65value.
65The 66The
66.Fn strtouq 67.Fn strtoull
67function 68function converts the string in
68converts the string in
69.Fa nptr 69.Fa nptr
70to a 70to an
71.Em u_quad_t 71.Li unsigned long long
72value. 72value.
73The
74.Fn strtouq
75function is a deprecated equivalent of
76.Fn strtoull
77and is provided for backwards compatibility with legacy programs.
73The conversion is done according to the given 78The conversion is done according to the given
74.Fa base , 79.Fa base ,
75which must be between 2 and 36 inclusive, 80which must be a number between 2 and 36 inclusive
76or be the special value 0. 81or the special value 0.
82If the string in
83.Fa nptr
84represents a negative number, it will be converted to its unsigned equivalent.
85This behavior is consistent with what happens when a signed integer type is
86cast to its unsigned counterpart.
77.Pp 87.Pp
78The string may begin with an arbitrary amount of white space 88The string may begin with an arbitrary amount of whitespace
79(as determined by 89(as determined by
80.Xr isspace 3 ) 90.Xr isspace 3 )
81followed by a single optional 91followed by a single optional
@@ -85,26 +95,22 @@ or
85sign. 95sign.
86If 96If
87.Fa base 97.Fa base
88is zero or 16, 98is zero or 16, the string may then include a
89the string may then include a
90.Ql 0x 99.Ql 0x
91prefix, 100prefix, and the number will be read in base 16; otherwise, a zero
92and the number will be read in base 16; otherwise, a zero
93.Fa base 101.Fa base
94is taken as 10 (decimal) unless the next character is 102is taken as 10 (decimal) unless the next character is
95.Ql 0 , 103.Ql 0 ,
96in which case it is taken as 8 (octal). 104in which case it is taken as 8 (octal).
97.Pp 105.Pp
98The remainder of the string is converted to an 106The remainder of the string is converted to an
99.Em unsigned long 107.Li unsigned long
100value in the obvious manner, 108value in the obvious manner, stopping at the end of the string
101stopping at the end of the string
102or at the first character that does not produce a valid digit 109or at the first character that does not produce a valid digit
103in the given base. 110in the given base.
104(In bases above 10, the letter 111(In bases above 10, the letter
105.Ql A 112.Ql A
106in either upper or lower case 113in either upper or lower case represents 10,
107represents 10,
108.Ql B 114.Ql B
109represents 11, and so forth, with 115represents 11, and so forth, with
110.Ql Z 116.Ql Z
@@ -112,7 +118,7 @@ representing 35.)
112.Pp 118.Pp
113If 119If
114.Fa endptr 120.Fa endptr
115is non nil, 121is non-null,
116.Fn strtoul 122.Fn strtoul
117stores the address of the first invalid character in 123stores the address of the first invalid character in
118.Fa *endptr . 124.Fa *endptr .
@@ -134,12 +140,18 @@ on return, the entire string was valid.)
134.Sh RETURN VALUES 140.Sh RETURN VALUES
135The 141The
136.Fn strtoul 142.Fn strtoul
137function 143function returns the result of the conversion,
138returns either the result of the conversion 144unless the value would overflow, in which case
139or, if there was a leading minus sign, 145.Dv ULONG_MAX
140the negation of the result of the conversion, 146is returned and
141unless the original (non-negated) value would overflow; 147.Va errno
142in the latter case, 148is set to
149.Er ERANGE .
150If there was a leading minus sign,
151.Fn strtoul
152returns the (unsigned) negation of the absolute value of the number, unless
153the absolute value would overflow.
154In this case,
143.Fn strtoul 155.Fn strtoul
144returns 156returns
145.Dv ULONG_MAX 157.Dv ULONG_MAX
@@ -147,18 +159,73 @@ and sets the global variable
147.Va errno 159.Va errno
148to 160to
149.Er ERANGE . 161.Er ERANGE .
162.Pp
163The
164.Fn strtoull
165function has identical return values except that
166.Dv ULLONG_MAX
167is used to indicate overflow.
168.Pp
169There is no way to determine if
170.Fn strtoul
171has processed a negative number (and returned an unsigned value) short of
172examining the string in
173.Fa nptr
174directly.
175.Sh EXAMPLES
176Ensuring that a string is a valid number (i.e., in range and containing no
177trailing characters) requires clearing
178.Va errno
179beforehand explicitly since
180.Va errno
181is not changed on a successful call to
182.Fn strtoul ,
183and the return value of
184.Fn strtoul
185cannot be used unambiguously to signal an error:
186.Bd -literal -offset indent
187char *ep;
188unsigned long ulval;
189
190\&...
191
192errno = 0;
193ulval = strtoul(buf, &ep, 10);
194if (buf[0] == '\e0' || *ep != '\e0')
195 goto not_a_number;
196if (errno == ERANGE && ulval == ULONG_MAX)
197 goto out_of_range;
198.Ed
199.Pp
200This example will accept
201.Dq 12
202but not
203.Dq 12foo
204or
205.Dq 12\en .
206If trailing whitespace is acceptable, further checks must be done on
207.Va *ep ;
208alternately, use
209.Xr sscanf 3 .
150.Sh ERRORS 210.Sh ERRORS
151.Bl -tag -width Er 211.Bl -tag -width Er
152.It Bq Er ERANGE 212.It Bq Er ERANGE
153The given string was out of range; the value converted has been clamped. 213The given string was out of range; the value converted has been clamped.
154.El 214.El
155.Sh SEE ALSO 215.Sh SEE ALSO
216.Xr sscanf 3 ,
156.Xr strtol 3 217.Xr strtol 3
157.Sh STANDARDS 218.Sh STANDARDS
158The 219The
159.Fn strtoul 220.Fn strtoul
160function 221and
161conforms to 222.Fn strtoull
162.St -ansiC . 223functions conform to
224.St -ansiC-99 .
225The
226.Fn strtouq
227function is a
228.Bx
229extension and is provided for backwards compatibility with legacy programs.
163.Sh BUGS 230.Sh BUGS
164Ignores the current locale. 231Ignores the current locale.
diff --git a/src/lib/libc/stdlib/strtoul.c b/src/lib/libc/stdlib/strtoul.c
index 00f7210fa1..7d31ce79fb 100644
--- a/src/lib/libc/stdlib/strtoul.c
+++ b/src/lib/libc/stdlib/strtoul.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,13 +28,12 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)strtoul.c 5.3 (Berkeley) 2/23/91";*/ 31static char *rcsid = "$OpenBSD: strtoul.c,v 1.5 2003/06/02 20:18:38 millert Exp $";
36static char *rcsid = "$Id: strtoul.c,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
39#include <limits.h>
40#include <ctype.h> 34#include <ctype.h>
41#include <errno.h> 35#include <errno.h>
36#include <limits.h>
42#include <stdlib.h> 37#include <stdlib.h>
43 38
44/* 39/*
@@ -53,23 +48,26 @@ strtoul(nptr, endptr, base)
53 char **endptr; 48 char **endptr;
54 register int base; 49 register int base;
55{ 50{
56 register const char *s = nptr; 51 register const char *s;
57 register unsigned long acc; 52 register unsigned long acc, cutoff;
58 register int c; 53 register int c;
59 register unsigned long cutoff; 54 register int neg, any, cutlim;
60 register int neg = 0, any, cutlim;
61 55
62 /* 56 /*
63 * See strtol for comments as to the logic used. 57 * See strtol for comments as to the logic used.
64 */ 58 */
59 s = nptr;
65 do { 60 do {
66 c = *s++; 61 c = (unsigned char) *s++;
67 } while (isspace(c)); 62 } while (isspace(c));
68 if (c == '-') { 63 if (c == '-') {
69 neg = 1; 64 neg = 1;
70 c = *s++; 65 c = *s++;
71 } else if (c == '+') 66 } else {
72 c = *s++; 67 neg = 0;
68 if (c == '+')
69 c = *s++;
70 }
73 if ((base == 0 || base == 16) && 71 if ((base == 0 || base == 16) &&
74 c == '0' && (*s == 'x' || *s == 'X')) { 72 c == '0' && (*s == 'x' || *s == 'X')) {
75 c = s[1]; 73 c = s[1];
@@ -78,9 +76,10 @@ strtoul(nptr, endptr, base)
78 } 76 }
79 if (base == 0) 77 if (base == 0)
80 base = c == '0' ? 8 : 10; 78 base = c == '0' ? 8 : 10;
81 cutoff = (unsigned long)ULONG_MAX / (unsigned long)base; 79
82 cutlim = (unsigned long)ULONG_MAX % (unsigned long)base; 80 cutoff = ULONG_MAX / (unsigned long)base;
83 for (acc = 0, any = 0;; c = *s++) { 81 cutlim = ULONG_MAX % (unsigned long)base;
82 for (acc = 0, any = 0;; c = (unsigned char) *s++) {
84 if (isdigit(c)) 83 if (isdigit(c))
85 c -= '0'; 84 c -= '0';
86 else if (isalpha(c)) 85 else if (isalpha(c))
@@ -89,18 +88,19 @@ strtoul(nptr, endptr, base)
89 break; 88 break;
90 if (c >= base) 89 if (c >= base)
91 break; 90 break;
92 if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) 91 if (any < 0)
92 continue;
93 if (acc > cutoff || acc == cutoff && c > cutlim) {
93 any = -1; 94 any = -1;
94 else { 95 acc = ULONG_MAX;
96 errno = ERANGE;
97 } else {
95 any = 1; 98 any = 1;
96 acc *= base; 99 acc *= (unsigned long)base;
97 acc += c; 100 acc += c;
98 } 101 }
99 } 102 }
100 if (any < 0) { 103 if (neg && any > 0)
101 acc = ULONG_MAX;
102 errno = ERANGE;
103 } else if (neg)
104 acc = -acc; 104 acc = -acc;
105 if (endptr != 0) 105 if (endptr != 0)
106 *endptr = (char *) (any ? s - 1 : nptr); 106 *endptr = (char *) (any ? s - 1 : nptr);
diff --git a/src/lib/libc/stdlib/strtouq.c b/src/lib/libc/stdlib/strtoull.c
index cc647d8d28..a0ac9b381f 100644
--- a/src/lib/libc/stdlib/strtouq.c
+++ b/src/lib/libc/stdlib/strtoull.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,40 +28,39 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35static char sccsid[] = "@(#)strtouq.c 5.1 (Berkeley) 6/26/92"; 31static const char rcsid[] = "$OpenBSD: strtoull.c,v 1.2 2003/06/02 20:18:38 millert Exp $";
36#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
37 33
38#include <sys/types.h> 34#include <sys/types.h>
39 35
40#include <limits.h>
41#include <errno.h>
42#include <ctype.h> 36#include <ctype.h>
37#include <errno.h>
38#include <limits.h>
43#include <stdlib.h> 39#include <stdlib.h>
44 40
45/* 41/*
46 * Convert a string to an unsigned quad integer. 42 * Convert a string to an unsigned long long.
47 * 43 *
48 * Ignores `locale' stuff. Assumes that the upper and lower case 44 * Ignores `locale' stuff. Assumes that the upper and lower case
49 * alphabets and digits are each contiguous. 45 * alphabets and digits are each contiguous.
50 */ 46 */
51u_quad_t 47unsigned long long
52strtouq(nptr, endptr, base) 48strtoull(nptr, endptr, base)
53 const char *nptr; 49 const char *nptr;
54 char **endptr; 50 char **endptr;
55 register int base; 51 int base;
56{ 52{
57 register const char *s = nptr; 53 const char *s;
58 register u_quad_t acc; 54 unsigned long long acc, cutoff;
59 register int c; 55 int c;
60 register u_quad_t qbase, cutoff; 56 int neg, any, cutlim;
61 register int neg, any, cutlim;
62 57
63 /* 58 /*
64 * See strtoq for comments as to the logic used. 59 * See strtoq for comments as to the logic used.
65 */ 60 */
66 s = nptr; 61 s = nptr;
67 do { 62 do {
68 c = *s++; 63 c = (unsigned char) *s++;
69 } while (isspace(c)); 64 } while (isspace(c));
70 if (c == '-') { 65 if (c == '-') {
71 neg = 1; 66 neg = 1;
@@ -83,10 +78,10 @@ strtouq(nptr, endptr, base)
83 } 78 }
84 if (base == 0) 79 if (base == 0)
85 base = c == '0' ? 8 : 10; 80 base = c == '0' ? 8 : 10;
86 qbase = (unsigned)base; 81
87 cutoff = (u_quad_t)UQUAD_MAX / qbase; 82 cutoff = ULLONG_MAX / (unsigned long long)base;
88 cutlim = (u_quad_t)UQUAD_MAX % qbase; 83 cutlim = ULLONG_MAX % (unsigned long long)base;
89 for (acc = 0, any = 0;; c = *s++) { 84 for (acc = 0, any = 0;; c = (unsigned char) *s++) {
90 if (isdigit(c)) 85 if (isdigit(c))
91 c -= '0'; 86 c -= '0';
92 else if (isalpha(c)) 87 else if (isalpha(c))
@@ -95,20 +90,35 @@ strtouq(nptr, endptr, base)
95 break; 90 break;
96 if (c >= base) 91 if (c >= base)
97 break; 92 break;
98 if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) 93 if (any < 0)
94 continue;
95 if (acc > cutoff || (acc == cutoff && c > cutlim)) {
99 any = -1; 96 any = -1;
100 else { 97 acc = ULLONG_MAX;
98 errno = ERANGE;
99 } else {
101 any = 1; 100 any = 1;
102 acc *= qbase; 101 acc *= (unsigned long long)base;
103 acc += c; 102 acc += c;
104 } 103 }
105 } 104 }
106 if (any < 0) { 105 if (neg && any > 0)
107 acc = UQUAD_MAX;
108 errno = ERANGE;
109 } else if (neg)
110 acc = -acc; 106 acc = -acc;
111 if (endptr != 0) 107 if (endptr != 0)
112 *endptr = (char *) (any ? s - 1 : nptr); 108 *endptr = (char *) (any ? s - 1 : nptr);
113 return (acc); 109 return (acc);
114} 110}
111
112#ifdef __weak_alias
113__weak_alias(strtouq, strtoull);
114#else
115u_quad_t
116strtouq(nptr, endptr, base)
117 const char *nptr;
118 char **endptr;
119 int base;
120{
121
122 return ((u_quad_t)strtoull(nptr, endptr, base);
123}
124#endif
diff --git a/src/lib/libc/stdlib/system.3 b/src/lib/libc/stdlib/system.3
index 520f51db0a..1034b01066 100644
--- a/src/lib/libc/stdlib/system.3
+++ b/src/lib/libc/stdlib/system.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,8 +29,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)system.3 6.5 (Berkeley) 6/29/91 32.\" $OpenBSD: system.3,v 1.9 2003/06/02 20:18:38 millert Exp $
37.\" $Id: system.3,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd June 29, 1991
40.Dt SYSTEM 3 35.Dt SYSTEM 3
@@ -49,8 +44,7 @@
49.Sh DESCRIPTION 44.Sh DESCRIPTION
50The 45The
51.Fn system 46.Fn system
52function 47function hands the argument
53hands the argument
54.Fa string 48.Fa string
55to the command interpreter 49to the command interpreter
56.Xr sh 1 . 50.Xr sh 1 .
@@ -64,36 +58,42 @@ and blocking
64.Pp 58.Pp
65If 59If
66.Fa string 60.Fa string
67is a 61is
68.Dv NULL 62.Dv NULL ,
69pointer,
70.Fn system 63.Fn system
71will return non-zero. 64will return non-zero.
72Otherwise, 65Otherwise,
73.Fn system 66.Fn system
74returns the termination status of the shell in the format specified by 67returns the termination status of the shell in the format specified by
75.Xr waitpid 3 . 68.Xr waitpid 2 .
76.Sh RETURN VALUES 69.Sh RETURN VALUES
77If a child process cannot be created, or the termination status of 70If a child process cannot be created, or the termination status of
78the shell cannot be obtained, 71the shell cannot be obtained,
79.Fn system 72.Fn system
80returns -1 and sets 73returns \-1 and sets
81.Va errno 74.Va errno
82to indicate the error. 75to indicate the error.
83If execution of the shell fails, 76If execution of the shell fails,
84.Fn system 77.Fn system
85returns the termination status for a program that terminates with a call of 78returns the termination status for a program that terminates with a call of
86.Fn exit 127 . 79.Fn exit 127 .
87.Sh SEE ALSO 80.Sh SEE ALSO
88.Xr sh 1 , 81.Xr sh 1 ,
89.Xr execve 2 , 82.Xr execve 2 ,
90.Xr popen 3 , 83.Xr waitpid 2 ,
91.Xr waitpid 3 , 84.Xr popen 3
92.Sh STANDARDS 85.Sh STANDARDS
93The 86The
94.Fn system 87.Fn system
95function 88function conforms to
96conforms to 89.St -ansiC
97.St -ansiC
98and 90and
99.St -1003.2-92 . 91.St -p1003.2-92 .
92.Sh CAVEATS
93Never supply the
94.Fn system
95function with a command containing any part of an unsanitized user-supplied
96string.
97Shell meta-characters present will be honored by the
98.Xr sh 1
99command interpreter.
diff --git a/src/lib/libc/stdlib/system.c b/src/lib/libc/stdlib/system.c
index c2f39325f6..06b439230b 100644
--- a/src/lib/libc/stdlib/system.c
+++ b/src/lib/libc/stdlib/system.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,8 +28,7 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)system.c 5.10 (Berkeley) 2/23/91";*/ 31static char *rcsid = "$OpenBSD: system.c,v 1.6 2003/06/02 20:18:38 millert Exp $";
36static char *rcsid = "$Id: system.c,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
39#include <sys/types.h> 34#include <sys/types.h>
@@ -51,20 +46,24 @@ system(command)
51{ 46{
52 pid_t pid; 47 pid_t pid;
53 sig_t intsave, quitsave; 48 sig_t intsave, quitsave;
54 int omask; 49 sigset_t mask, omask;
55 int pstat; 50 int pstat;
56 char *argp[] = {"sh", "-c", (char *) command, NULL}; 51 char *argp[] = {"sh", "-c", NULL, NULL};
57 52
58 if (!command) /* just checking... */ 53 if (!command) /* just checking... */
59 return(1); 54 return(1);
60 55
61 omask = sigblock(sigmask(SIGCHLD)); 56 argp[2] = (char *)command;
62 switch(pid = vfork()) { 57
58 sigemptyset(&mask);
59 sigaddset(&mask, SIGCHLD);
60 sigprocmask(SIG_BLOCK, &mask, &omask);
61 switch (pid = vfork()) {
63 case -1: /* error */ 62 case -1: /* error */
64 (void)sigsetmask(omask); 63 sigprocmask(SIG_SETMASK, &omask, NULL);
65 return(-1); 64 return(-1);
66 case 0: /* child */ 65 case 0: /* child */
67 (void)sigsetmask(omask); 66 sigprocmask(SIG_SETMASK, &omask, NULL);
68 execve(_PATH_BSHELL, argp, environ); 67 execve(_PATH_BSHELL, argp, environ);
69 _exit(127); 68 _exit(127);
70 } 69 }
@@ -72,8 +71,8 @@ system(command)
72 intsave = signal(SIGINT, SIG_IGN); 71 intsave = signal(SIGINT, SIG_IGN);
73 quitsave = signal(SIGQUIT, SIG_IGN); 72 quitsave = signal(SIGQUIT, SIG_IGN);
74 pid = waitpid(pid, (int *)&pstat, 0); 73 pid = waitpid(pid, (int *)&pstat, 0);
75 (void)sigsetmask(omask); 74 sigprocmask(SIG_SETMASK, &omask, NULL);
76 (void)signal(SIGINT, intsave); 75 (void)signal(SIGINT, intsave);
77 (void)signal(SIGQUIT, quitsave); 76 (void)signal(SIGQUIT, quitsave);
78 return(pid == -1 ? -1 : pstat); 77 return (pid == -1 ? -1 : pstat);
79} 78}
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..15d7b84a3a
--- /dev/null
+++ b/src/lib/libc/stdlib/tsearch.3
@@ -0,0 +1,116 @@
1.\" $OpenBSD: tsearch.3,v 1.12 2003/06/17 21:56:24 millert Exp $
2.\"
3.\" Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
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 THE AUTHOR DISCLAIMS ALL WARRANTIES
10.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16.\"
17.Dd June 15, 1997
18.Dt TSEARCH 3
19.Os
20.Sh NAME
21.Nm tsearch ,
22.Nm tfind ,
23.Nm tdelete ,
24.Nm twalk
25.Nd manipulate binary search trees
26.Sh SYNOPSIS
27.Fd #include <search.h>
28.Ft void *
29.Fn tdelete "const void *key" "void **rootp" "int (*compar) (const void *, const void *)"
30.Ft void *
31.Fn tfind "const void *key" "void * const *rootp" "int (*compar) (const void *, const void *)"
32.Ft void *
33.Fn tsearch "const void *key" "void **rootp" "int (*compar) (const void *, const void *)"
34.Ft void
35.Fn twalk "const void *root" "void (*action) (const void *, VISIT, int)"
36.Sh DESCRIPTION
37The
38.Fn tdelete ,
39.Fn tfind ,
40.Fn tsearch ,
41and
42.Fn twalk
43functions manage binary search trees based on algorithms T and D
44from Knuth (6.2.2).
45The comparison function passed in by
46the user has the same style of return values as
47.Xr strcmp 3 .
48.Pp
49.Fn tfind
50searches for the datum matched by the argument
51.Fa key
52in the binary tree rooted at
53.Fa rootp ,
54returning a pointer to the datum if it is found and
55.Dv NULL
56if it is not.
57.Pp
58.Fn tsearch
59is identical to
60.Fn tfind
61except that if no match is found,
62.Fa key
63is inserted into the tree and a pointer to it is returned.
64If
65.Fa rootp
66points to a null value a new binary search tree is created.
67.Pp
68.Fn tdelete
69deletes a node from the specified binary search tree and returns
70a pointer to the parent of the node to be deleted.
71It takes the same arguments as
72.Fn tfind
73and
74.Fn tsearch .
75If the node to be deleted is the root of the binary search tree,
76.Fa rootp
77will be adjusted.
78.Pp
79.Fn twalk
80walks the binary search tree rooted in
81.Fa root
82and calls the function
83.Fa action
84on each node.
85.Fa action
86is called with three arguments: a pointer to the current node,
87a value from the enum
88.Sy "typedef enum { preorder, postorder, endorder, leaf } VISIT;"
89specifying the traversal type, and a node level (where level
90zero is the root of the tree).
91.Sh RETURN VALUES
92The
93.Fn tsearch
94function returns
95.Dv NULL
96if allocation of a new node fails (usually
97due to a lack of free memory).
98.Pp
99.Fn tfind ,
100.Fn tsearch ,
101and
102.Fn tdelete
103return
104.Dv NULL
105if
106.Fa rootp
107is
108.Dv NULL
109or the datum cannot be found.
110.Pp
111The
112.Fn twalk
113function returns no value.
114.Sh SEE ALSO
115.Xr bsearch 3 ,
116.Xr lsearch 3
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
index 2b7ce63a63..26e2bc10f2 100644
--- a/src/lib/libc/string/Makefile.inc
+++ b/src/lib/libc/string/Makefile.inc
@@ -1,23 +1,22 @@
1# from: @(#)Makefile.inc 5.6 (Berkeley) 3/5/91 1# $OpenBSD: Makefile.inc,v 1.12 2003/02/20 03:20:09 deraadt Exp $
2# $Id: Makefile.inc,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $
3 2
4# string sources 3# string sources
5.PATH: ${.CURDIR}/arch/${MACHINE_ARCH}/string ${.CURDIR}/string 4.PATH: ${LIBCSRCDIR}/arch/${MACHINE_ARCH}/string ${LIBCSRCDIR}/string
6 5
7SRCS+= bm.c memccpy.c strcasecmp.c strcoll.c strdup.c strerror.c \ 6SRCS+= bm.c memccpy.c strcasecmp.c strcoll.c strdup.c strerror.c \
8 strftime.c strmode.c strsignal.c strtok.c strxfrm.c \ 7 strerror_r.c strlcat.c strmode.c strsignal.c strtok.c strxfrm.c \
9 __strerror.c __strsignal.c 8 __strerror.c __strsignal.c
10 9
11# machine-dependent net sources 10# machine-dependent net sources
12# m-d Makefile.inc must include sources for: 11# m-d Makefile.inc must include sources for:
13# bcmp() bcopy() bzero() ffs() index() memchr() memcmp() memset() 12# bcmp() bcopy() bzero() ffs() index() memchr() memcmp() memset()
14# rindex() strcat() strcmp() strcpy() strcspn() strlen() 13# rindex() strcat() strcmp() strcpy() strcspn() strlen() strlcpy()
15# strncat() strncmp() strncpy() strpbrk() strsep() 14# strncat() strncmp() strncpy() strpbrk() strsep()
16# strspn() strstr() swav() 15# strspn() strstr() swav()
17# m-d Makefile.inc may include sources for: 16# m-d Makefile.inc may include sources for:
18# memcpy() memmove() strchr() strrchr() 17# memcpy() memmove() strchr() strrchr()
19 18
20.include "${.CURDIR}/arch/${MACHINE_ARCH}/string/Makefile.inc" 19.include "${LIBCSRCDIR}/arch/${MACHINE_ARCH}/string/Makefile.inc"
21 20
22# if no machine specific memmove(3), build one out of bcopy(3). 21# if no machine specific memmove(3), build one out of bcopy(3).
23.if empty(SRCS:Mmemmove.S) 22.if empty(SRCS:Mmemmove.S)
@@ -27,6 +26,11 @@ memmove.o: bcopy.c
27 @${LD} -x -r ${.TARGET} 26 @${LD} -x -r ${.TARGET}
28 @mv a.out ${.TARGET} 27 @mv a.out ${.TARGET}
29 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
30memmove.po: bcopy.c 34memmove.po: bcopy.c
31 ${CC} -DMEMMOVE ${CFLAGS} ${CPPFLAGS} -c -p ${.ALLSRC} -o ${.TARGET} 35 ${CC} -DMEMMOVE ${CFLAGS} ${CPPFLAGS} -c -p ${.ALLSRC} -o ${.TARGET}
32 @${LD} -X -r ${.TARGET} 36 @${LD} -X -r ${.TARGET}
@@ -48,6 +52,11 @@ memcpy.o: bcopy.c
48 @${LD} -x -r ${.TARGET} 52 @${LD} -x -r ${.TARGET}
49 @mv a.out ${.TARGET} 53 @mv a.out ${.TARGET}
50 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
51memcpy.po: bcopy.c 60memcpy.po: bcopy.c
52 ${CC} -DMEMCOPY ${CFLAGS} ${CPPFLAGS} -c -p ${.ALLSRC} -o ${.TARGET} 61 ${CC} -DMEMCOPY ${CFLAGS} ${CPPFLAGS} -c -p ${.ALLSRC} -o ${.TARGET}
53 @${LD} -X -r ${.TARGET} 62 @${LD} -X -r ${.TARGET}
@@ -67,6 +76,11 @@ strchr.o: index.c
67 @${LD} -x -r ${.TARGET} 76 @${LD} -x -r ${.TARGET}
68 @mv a.out ${.TARGET} 77 @mv a.out ${.TARGET}
69 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
70strchr.po: index.c 84strchr.po: index.c
71 ${CC} -DSTRCHR ${CFLAGS} ${CPPFLAGS} -c -p ${.ALLSRC} -o ${.TARGET} 85 ${CC} -DSTRCHR ${CFLAGS} ${CPPFLAGS} -c -p ${.ALLSRC} -o ${.TARGET}
72 @${LD} -X -r ${.TARGET} 86 @${LD} -X -r ${.TARGET}
@@ -85,6 +99,11 @@ strrchr.o: rindex.c
85 @${LD} -x -r ${.TARGET} 99 @${LD} -x -r ${.TARGET}
86 @mv a.out ${.TARGET} 100 @mv a.out ${.TARGET}
87 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
88strrchr.po: rindex.c 107strrchr.po: rindex.c
89 ${CC} -DSTRRCHR ${CFLAGS} ${CPPFLAGS} -c -p ${.ALLSRC} -o ${.TARGET} 108 ${CC} -DSTRRCHR ${CFLAGS} ${CPPFLAGS} -c -p ${.ALLSRC} -o ${.TARGET}
90 @${LD} -X -r ${.TARGET} 109 @${LD} -X -r ${.TARGET}
@@ -95,14 +114,39 @@ strrchr.so: rindex.c
95 -o ${.TARGET} 114 -o ${.TARGET}
96.endif 115.endif
97 116
98MAN+= bm.3 bcmp.3 bcopy.3 bstring.3 bzero.3 ffs.3 index.3 memccpy.3 memchr.3 \ 117# build .ln files for memmove, memcpy, strchr and strrchr always from
99 memcmp.3 memcpy.3 memmove.3 memset.3 rindex.3 strcasecmp.3 strcat.3 \ 118# bcopy, index, and rindex
100 strchr.3 strcmp.3 strcoll.3 strcpy.3 strcspn.3 strerror.3 strftime.3 \ 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 \
101 string.3 strlen.3 strmode.3 strdup.3 strpbrk.3 strrchr.3 strsep.3 \ 140 string.3 strlen.3 strmode.3 strdup.3 strpbrk.3 strrchr.3 strsep.3 \
102 strsignal.3 strspn.3 strstr.3 strtok.3 strxfrm.3 swab.3 141 strsignal.3 strspn.3 strstr.3 strtok.3 strxfrm.3 swab.3 strlcpy.3
103 142
104MLINKS+=bm.3 bm_comp.3 bm.3 bm_exec.3 bm.3 bm_free.3 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
105MLINKS+=strcasecmp.3 strncasecmp.3 146MLINKS+=strcasecmp.3 strncasecmp.3
106MLINKS+=strcat.3 strncat.3 147MLINKS+=strcat.3 strncat.3
107MLINKS+=strcmp.3 strncmp.3 148MLINKS+=strcmp.3 strncmp.3
108MLINKS+=strcpy.3 strncpy.3 149MLINKS+=strcpy.3 strncpy.3
150MLINKS+=strlcpy.3 strlcat.3
151MLINKS+=strtok.3 strtok_r.3
152MLINKS+=strerror.3 strerror_r.3
diff --git a/src/lib/libc/string/__strerror.c b/src/lib/libc/string/__strerror.c
index cd604906db..15436eaab2 100644
--- a/src/lib/libc/string/__strerror.c
+++ b/src/lib/libc/string/__strerror.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,8 +28,7 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)strerror.c 5.6 (Berkeley) 5/4/91";*/ 31static char *rcsid = "$OpenBSD: __strerror.c,v 1.10 2003/06/02 20:18:38 millert Exp $";
36static char *rcsid = "$Id: __strerror.c,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
39#ifdef NLS 34#ifdef NLS
@@ -46,9 +41,27 @@ static char *rcsid = "$Id: __strerror.c,v 1.1.1.1 1995/10/18 08:42:20 deraadt Ex
46#define sys_errlist _sys_errlist 41#define sys_errlist _sys_errlist
47#define sys_nerr _sys_nerr 42#define sys_nerr _sys_nerr
48 43
44#include <errno.h>
45#include <limits.h>
49#include <stdio.h> 46#include <stdio.h>
50#include <string.h> 47#include <string.h>
51 48
49static char *
50itoa(num)
51 int num;
52{
53 static char buffer[11];
54 char *p;
55
56 p = buffer + 4;
57 while (num >= 10) {
58 *--p = (num % 10) + '0';
59 num /= 10;
60 }
61 *p = (num % 10) + '0';
62 return p;
63}
64
52/* 65/*
53 * Since perror() is not allowed to change the contents of strerror()'s 66 * Since perror() is not allowed to change the contents of strerror()'s
54 * static buffer, both functions supply their own buffers to the 67 * static buffer, both functions supply their own buffers to the
@@ -60,32 +73,37 @@ __strerror(num, buf)
60 int num; 73 int num;
61 char *buf; 74 char *buf;
62{ 75{
63#define UPREFIX "Unknown error: %u" 76#define UPREFIX "Unknown error: "
64 register unsigned int errnum; 77 register unsigned int errnum;
65
66#ifdef NLS 78#ifdef NLS
67 nl_catd catd ; 79 int save_errno;
80 nl_catd catd;
81
68 catd = catopen("libc", 0); 82 catd = catopen("libc", 0);
69#endif 83#endif
70 84
71 errnum = num; /* convert to unsigned */ 85 errnum = num; /* convert to unsigned */
72 if (errnum < sys_nerr) { 86 if (errnum < sys_nerr) {
73#ifdef NLS 87#ifdef NLS
74 strcpy(buf, catgets(catd, 1, errnum, 88 strlcpy(buf, catgets(catd, 1, errnum,
75 (char *)sys_errlist[errnum])); 89 (char *)sys_errlist[errnum]), NL_TEXTMAX);
76#else 90#else
77 return(sys_errlist[errnum]); 91 return(sys_errlist[errnum]);
78#endif 92#endif
79 } else { 93 } else {
80#ifdef NLS 94#ifdef NLS
81 sprintf(buf, catgets(catd, 1, 0xffff, UPREFIX), errnum); 95 strlcpy(buf, catgets(catd, 1, 0xffff, UPREFIX), NL_TEXTMAX);
82#else 96#else
83 sprintf(buf, UPREFIX, errnum); 97 strlcpy(buf, UPREFIX, NL_TEXTMAX);
84#endif 98#endif
99 strlcat(buf, itoa(errnum), NL_TEXTMAX);
100 errno = EINVAL;
85 } 101 }
86 102
87#ifdef NLS 103#ifdef NLS
104 save_errno = errno;
88 catclose(catd); 105 catclose(catd);
106 errno = save_errno;
89#endif 107#endif
90 108
91 return buf; 109 return buf;
diff --git a/src/lib/libc/string/__strsignal.c b/src/lib/libc/string/__strsignal.c
index 1937e2d608..5bab3cd0af 100644
--- a/src/lib/libc/string/__strsignal.c
+++ b/src/lib/libc/string/__strsignal.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,8 +28,7 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)strerror.c 5.6 (Berkeley) 5/4/91";*/ 31static char *rcsid = "$OpenBSD: __strsignal.c,v 1.8 2003/06/02 20:18:38 millert Exp $";
36static char *rcsid = "$Id: __strsignal.c,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
39#ifdef NLS 34#ifdef NLS
@@ -46,15 +41,31 @@ static char *rcsid = "$Id: __strsignal.c,v 1.1.1.1 1995/10/18 08:42:20 deraadt E
46#define sys_siglist _sys_siglist 41#define sys_siglist _sys_siglist
47 42
48#include <stdio.h> 43#include <stdio.h>
44#include <limits.h>
49#include <signal.h> 45#include <signal.h>
50#include <string.h> 46#include <string.h>
51 47
48static char *itoa(num)
49 int num;
50{
51 static char buffer[11];
52 char *p;
53
54 p = buffer + 4;
55 while (num >= 10) {
56 *--p = (num % 10) + '0';
57 num /= 10;
58 }
59 *p = (num % 10) + '0';
60 return p;
61}
62
52char * 63char *
53__strsignal(num, buf) 64__strsignal(num, buf)
54 int num; 65 int num;
55 char *buf; 66 char *buf;
56{ 67{
57#define UPREFIX "Unknown signal: %u" 68#define UPREFIX "Unknown signal: "
58 register unsigned int signum; 69 register unsigned int signum;
59 70
60#ifdef NLS 71#ifdef NLS
@@ -65,17 +76,18 @@ __strsignal(num, buf)
65 signum = num; /* convert to unsigned */ 76 signum = num; /* convert to unsigned */
66 if (signum < NSIG) { 77 if (signum < NSIG) {
67#ifdef NLS 78#ifdef NLS
68 strcpy(buf, catgets(catd, 2, signum, 79 strlcpy(buf, catgets(catd, 2, signum,
69 (char *)sys_siglist[signum])); 80 (char *)sys_siglist[signum]), NL_TEXTMAX);
70#else 81#else
71 return((char *)sys_siglist[signum]); 82 return((char *)sys_siglist[signum]);
72#endif 83#endif
73 } else { 84 } else {
74#ifdef NLS 85#ifdef NLS
75 sprintf(buf, catgets(catd, 1, 0xffff, UPREFIX), signum); 86 strlcpy(buf, catgets(catd, 1, 0xffff, UPREFIX), NL_TEXTMAX);
76#else 87#else
77 sprintf(buf, UPREFIX, signum); 88 strlcpy(buf, UPREFIX, NL_TEXTMAX);
78#endif 89#endif
90 strlcat(buf, itoa(signum), NL_TEXTMAX);
79 } 91 }
80 92
81#ifdef NLS 93#ifdef NLS
diff --git a/src/lib/libc/string/bcmp.3 b/src/lib/libc/string/bcmp.3
index 118c55c579..953476caa7 100644
--- a/src/lib/libc/string/bcmp.3
+++ b/src/lib/libc/string/bcmp.3
@@ -11,11 +11,7 @@
11.\" 2. Redistributions in binary form must reproduce the above copyright 11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the 12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution. 13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software 14.\" 3. Neither the name of the University nor the names of its contributors
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 15.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission. 16.\" without specific prior written permission.
21.\" 17.\"
@@ -31,12 +27,11 @@
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE. 28.\" SUCH DAMAGE.
33.\" 29.\"
34.\" from: @(#)bcmp.3 5.4 (Berkeley) 4/19/91 30.\" $OpenBSD: bcmp.3,v 1.6 2003/06/02 20:18:38 millert Exp $
35.\" $Id: bcmp.3,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $
36.\" 31.\"
37.Dd April 19, 1991 32.Dd April 19, 1991
38.Dt BCMP 3 33.Dt BCMP 3
39.Os BSD 4.2 34.Os
40.Sh NAME 35.Sh NAME
41.Nm bcmp 36.Nm bcmp
42.Nd compare byte string 37.Nd compare byte string
@@ -47,8 +42,7 @@
47.Sh DESCRIPTION 42.Sh DESCRIPTION
48The 43The
49.Fn bcmp 44.Fn bcmp
50function 45function compares byte string
51compares byte string
52.Fa b1 46.Fa b1
53against byte string 47against byte string
54.Fa b2 , 48.Fa b2 ,
@@ -68,5 +62,5 @@ The strings may overlap.
68.Sh HISTORY 62.Sh HISTORY
69A 63A
70.Fn bcmp 64.Fn bcmp
71function first appeared in 65function first appeared in
72.Bx 4.2 . 66.Bx 4.2 .
diff --git a/src/lib/libc/string/bcmp.c b/src/lib/libc/string/bcmp.c
index 2cc38baee3..2beeef8298 100644
--- a/src/lib/libc/string/bcmp.c
+++ b/src/lib/libc/string/bcmp.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,15 +28,19 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)bcmp.c 5.6 (Berkeley) 2/24/91";*/ 31static char *rcsid = "$OpenBSD: bcmp.c,v 1.5 2003/06/02 20:18:38 millert Exp $";
36static char *rcsid = "$Id: bcmp.c,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
34#ifndef _KERNEL
39#include <string.h> 35#include <string.h>
36#else
37#include <lib/libkern/libkern.h>
38#endif
40 39
41/* 40/*
42 * bcmp -- vax cmpc3 instruction 41 * bcmp -- vax cmpc3 instruction
43 */ 42 */
43int
44bcmp(b1, b2, length) 44bcmp(b1, b2, length)
45 const void *b1, *b2; 45 const void *b1, *b2;
46 register size_t length; 46 register size_t length;
diff --git a/src/lib/libc/string/bcopy.3 b/src/lib/libc/string/bcopy.3
index 6db3812caf..7b55bcbf43 100644
--- a/src/lib/libc/string/bcopy.3
+++ b/src/lib/libc/string/bcopy.3
@@ -12,11 +12,7 @@
12.\" 2. Redistributions in binary form must reproduce the above copyright 12.\" 2. Redistributions in binary form must reproduce the above copyright
13.\" notice, this list of conditions and the following disclaimer in the 13.\" notice, this list of conditions and the following disclaimer in the
14.\" documentation and/or other materials provided with the distribution. 14.\" documentation and/or other materials provided with the distribution.
15.\" 3. All advertising materials mentioning features or use of this software 15.\" 3. Neither the name of the University nor the names of its contributors
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 16.\" may be used to endorse or promote products derived from this software
21.\" without specific prior written permission. 17.\" without specific prior written permission.
22.\" 18.\"
@@ -32,15 +28,14 @@
32.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33.\" SUCH DAMAGE. 29.\" SUCH DAMAGE.
34.\" 30.\"
35.\" from: @(#)bcopy.3 5.3 (Berkeley) 4/19/91 31.\" $OpenBSD: bcopy.3,v 1.8 2003/06/21 12:04:01 avsm Exp $
36.\" $Id: bcopy.3,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $
37.\" 32.\"
38.Dd April 19, 1991 33.Dd April 19, 1991
39.Dt BCOPY 3 34.Dt BCOPY 3
40.Os BSD 4.2 35.Os
41.Sh NAME 36.Sh NAME
42.Nm bcopy 37.Nm bcopy
43.Nd copy byte string 38.Nd copy bytes
44.Sh SYNOPSIS 39.Sh SYNOPSIS
45.Fd #include <string.h> 40.Fd #include <string.h>
46.Ft void 41.Ft void
@@ -48,14 +43,13 @@
48.Sh DESCRIPTION 43.Sh DESCRIPTION
49The 44The
50.Fn bcopy 45.Fn bcopy
51function 46function copies
52copies
53.Fa len 47.Fa len
54bytes from string 48bytes from buffer
55.Fa src 49.Fa src
56to string 50to buffer
57.Fa dst . 51.Fa dst .
58The two strings may overlap. 52The two buffers may overlap.
59If 53If
60.Fa len 54.Fa len
61is zero, no bytes are copied. 55is zero, no bytes are copied.
@@ -64,9 +58,10 @@ is zero, no bytes are copied.
64.Xr memcpy 3 , 58.Xr memcpy 3 ,
65.Xr memmove 3 , 59.Xr memmove 3 ,
66.Xr strcpy 3 , 60.Xr strcpy 3 ,
61.Xr strlcpy 3 ,
67.Xr strncpy 3 62.Xr strncpy 3
68.Sh HISTORY 63.Sh HISTORY
69A 64A
70.Fn bcopy 65.Fn bcopy
71function appeared in 66function appeared in
72.Bx 4.2 . 67.Bx 4.2 .
diff --git a/src/lib/libc/string/bcopy.c b/src/lib/libc/string/bcopy.c
index 92feed66ea..c48faa145e 100644
--- a/src/lib/libc/string/bcopy.c
+++ b/src/lib/libc/string/bcopy.c
@@ -13,11 +13,7 @@
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software 16 * 3. Neither the name of the University nor the names of its contributors
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 17 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission. 18 * without specific prior written permission.
23 * 19 *
@@ -35,8 +31,7 @@
35 */ 31 */
36 32
37#if defined(LIBC_SCCS) && !defined(lint) 33#if defined(LIBC_SCCS) && !defined(lint)
38/*static char *sccsid = "from: @(#)bcopy.c 5.11 (Berkeley) 6/21/91";*/ 34static char *rcsid = "$OpenBSD: bcopy.c,v 1.3 2003/06/02 20:18:38 millert Exp $";
39static char *rcsid = "$Id: bcopy.c,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */ 35#endif /* LIBC_SCCS and not lint */
41 36
42#include <string.h> 37#include <string.h>
diff --git a/src/lib/libc/string/bm.3 b/src/lib/libc/string/bm.3
index 2264a6a1c4..772b0d372e 100644
--- a/src/lib/libc/string/bm.3
+++ b/src/lib/libc/string/bm.3
@@ -12,11 +12,7 @@
12.\" 2. Redistributions in binary form must reproduce the above copyright 12.\" 2. Redistributions in binary form must reproduce the above copyright
13.\" notice, this list of conditions and the following disclaimer in the 13.\" notice, this list of conditions and the following disclaimer in the
14.\" documentation and/or other materials provided with the distribution. 14.\" documentation and/or other materials provided with the distribution.
15.\" 3. All advertising materials mentioning features or use of this software 15.\" 3. Neither the name of the University nor the names of its contributors
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 16.\" may be used to endorse or promote products derived from this software
21.\" without specific prior written permission. 17.\" without specific prior written permission.
22.\" 18.\"
@@ -32,83 +28,84 @@
32.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33.\" SUCH DAMAGE. 29.\" SUCH DAMAGE.
34.\" 30.\"
35.\" from: @(#)bm.3 8.4 (Berkeley) 6/21/94 31.\" $OpenBSD: bm.3,v 1.7 2003/06/02 20:18:38 millert Exp $
36.\" $Id: bm.3,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $
37.\" 32.\"
38.TH BM 3 33.Dd June 29, 1999
39.SH NAME 34.Dt BM 3
40bm_comp, bm_exec, bm_free \- Boyer-Moore string search 35.Os
41.SH SYNOPSIS 36.Sh NAME
42.ft B 37.Nm bm_comp ,
43#include <sys/types.h> 38.Nm bm_exec ,
44.br 39.Nm bm_free
45#include <bm.h> 40.Nd Boyer-Moore string search
46.sp 41.Sh SYNOPSIS
47bm_pat * 42.Fd #include <sys/types.h>
48.br 43.Fd #include <bm.h>
49bm_comp(u_char *pattern, size_t patlen, u_char freq[256]); 44.Ft bm_pat *
50.sp 45.Fn bm_comp "u_char *pattern" "size_t patlen" "u_char freq[256]"
51u_char * 46.Ft u_char *
52.br 47.Fn bm_exec "bm_pat *pdesc" "u_char *text" "size_t len"
53bm_exec(bm_pat *pdesc, u_char *text, size_t len); 48.Ft void
54.sp 49.Fn bm_free "bm_pat *pdesc"
55void 50.Sh DESCRIPTION
56.br
57bm_free(bm_pat *pdesc);
58.SH DESCRIPTION
59These routines implement an efficient mechanism to find an 51These routines implement an efficient mechanism to find an
60occurrence of a byte string within another byte string. 52occurrence of a byte string within another byte string.
61.PP 53.Pp
62.I Bm_comp 54.Fn bm_comp
63evaluates the 55evaluates
64.I patlen 56.Fa patlen
65bytes starting at 57bytes starting at
66.IR pattern , 58.Fa pattern
67and returns a pointer to a structure describing them. 59and returns a pointer to a structure describing them.
68The bytes referenced by 60The bytes referenced by
69.I pattern 61.Fa pattern
70may be of any value. 62may be of any value.
71.PP 63.Pp
72The search takes advantage of the frequency distribution of the 64The search takes advantage of the frequency distribution of the
73bytes in the text to be searched. 65bytes in the text to be searched.
74If specified, 66If specified,
75.I freq 67.Ar freq
76should be an array of 256 values, 68should be an array of 256 values,
77with higher values indicating that the corresponding character occurs 69with higher values indicating that the corresponding character occurs
78more frequently. 70more frequently.
79(A less than optimal frequency distribution can only result in less 71(A less than optimal frequency distribution can only result in less
80than optimal performance, not incorrect results.) 72than optimal performance, not incorrect results.)
81If 73If
82.I freq 74.Ar freq
83is NULL, 75is
76.Dv NULL ,
84a system default table is used. 77a system default table is used.
85.PP 78.Pp
86.I Bm_exec 79.Fn bm_exec
87returns a pointer to the leftmost occurrence of the string given to 80returns a pointer to the leftmost occurrence of the string given to
88.I bm_comp 81.Fn bm_comp
89within 82within
90.IR text , 83.Ar text ,
91or NULL if none occurs. 84or
85.Dv NULL
86if none occurs.
92The number of bytes in 87The number of bytes in
93.I text 88.Ar text
94must be specified by 89must be specified by
95.IR len . 90.Ar len .
96.PP 91.Pp
97Space allocated for the returned description is discarded 92Space allocated for the returned description is discarded
98by calling 93by calling
99.I bm_free 94.Fn bm_free
100with the returned description as an argument. 95with the returned description as an argument.
101.PP 96.Pp
102The asymptotic speed of 97The asymptotic speed of
103.I bm_exec 98.Fn bm_exec
104is 99is
105.RI O( len / patlen ). 100.Pf O Ns Pq len / patlen .
106.PP 101.Sh SEE ALSO
107.SH "SEE ALSO" 102.Xr regexp 3 ,
108.IR regexp (3), 103.Xr strstr 3
109.IR strstr (3) 104.Rs
110.sp 105.%R "Fast String Searching"
111.IR "Fast String Searching" , 106.%A Andrew Hume
112Hume and Sunday, 107.%A Daniel Sunday
113Software Practice and Experience, 108.%J "Software Practice and Experience"
114Vol. 21, 11 (November 1991) pp. 1221-48. 109.%V Volume 21, 11 (November 1991)
110.%P 1221-48
111.Re
diff --git a/src/lib/libc/string/bm.c b/src/lib/libc/string/bm.c
index 68eac22ecc..2c7f8fac32 100644
--- a/src/lib/libc/string/bm.c
+++ b/src/lib/libc/string/bm.c
@@ -13,11 +13,7 @@
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software 16 * 3. Neither the name of the University nor the names of its contributors
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 17 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission. 18 * without specific prior written permission.
23 * 19 *
@@ -34,10 +30,9 @@
34 * SUCH DAMAGE. 30 * SUCH DAMAGE.
35 */ 31 */
36 32
37#ifndef lint 33#if defined(LIBC_SCCS) && !defined(lint)
38/* from: static char sccsid[] = "@(#)bm.c 8.7 (Berkeley) 6/21/94"; */ 34static char *rcsid = "$OpenBSD: bm.c,v 1.4 2003/06/02 20:18:38 millert Exp $";
39static char *rcsid = "$Id: bm.c,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $"; 35#endif /* LIBC_SCCS and not lint */
40#endif /* not lint */
41 36
42#include <sys/types.h> 37#include <sys/types.h>
43 38
diff --git a/src/lib/libc/string/bstring.3 b/src/lib/libc/string/bstring.3
index 12fcfb0cc1..d33a3c1e79 100644
--- a/src/lib/libc/string/bstring.3
+++ b/src/lib/libc/string/bstring.3
@@ -11,11 +11,7 @@
11.\" 2. Redistributions in binary form must reproduce the above copyright 11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the 12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution. 13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software 14.\" 3. Neither the name of the University nor the names of its contributors
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 15.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission. 16.\" without specific prior written permission.
21.\" 17.\"
@@ -31,22 +27,13 @@
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE. 28.\" SUCH DAMAGE.
33.\" 29.\"
34.\" from: @(#)bstring.3 6.8 (Berkeley) 4/19/91 30.\" $OpenBSD: bstring.3,v 1.6 2004/02/10 14:35:35 jmc Exp $
35.\" $Id: bstring.3,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $
36.\" 31.\"
37.Dd April 19, 1991 32.Dd April 19, 1991
38.Dt BSTRING 3 33.Dt BSTRING 3
39.Os 34.Os
40.Sh NAME 35.Sh NAME
41.Nm bcmp , 36.Nm bstring
42.Nm bcopy ,
43.Nm bzero ,
44.Nm memccpy ,
45.Nm memchr ,
46.Nm memcmp ,
47.Nm memcpy ,
48.Nm memmove,
49.Nm memset
50.Nd byte string operations 37.Nd byte string operations
51.Sh SYNOPSIS 38.Sh SYNOPSIS
52.Fd #include <string.h> 39.Fd #include <string.h>
@@ -97,14 +84,15 @@ and
97conform to 84conform to
98.St -ansiC . 85.St -ansiC .
99.Sh HISTORY 86.Sh HISTORY
100The functions 87The
101.Fn bzero 88.Fn bzero
102and 89and
103.Fn memccpy 90.Fn memccpy
104appeared in 91functions appeared in
105.Bx 4.3 ; 92.Bx 4.3 .
106the functions 93The
107.Fn bcmp , 94.Fn bcmp
108.Fn bcopy , 95and
109appeared in 96.Fn bcopy
97functions appeared in
110.Bx 4.2 . 98.Bx 4.2 .
diff --git a/src/lib/libc/string/bzero.3 b/src/lib/libc/string/bzero.3
index 4f0141e051..592d9f2f08 100644
--- a/src/lib/libc/string/bzero.3
+++ b/src/lib/libc/string/bzero.3
@@ -11,11 +11,7 @@
11.\" 2. Redistributions in binary form must reproduce the above copyright 11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the 12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution. 13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software 14.\" 3. Neither the name of the University nor the names of its contributors
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 15.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission. 16.\" without specific prior written permission.
21.\" 17.\"
@@ -31,12 +27,11 @@
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE. 28.\" SUCH DAMAGE.
33.\" 29.\"
34.\" from: @(#)bzero.3 5.3 (Berkeley) 4/19/91 30.\" $OpenBSD: bzero.3,v 1.6 2003/06/02 20:18:38 millert Exp $
35.\" $Id: bzero.3,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $
36.\" 31.\"
37.Dd April 19, 1991 32.Dd April 19, 1991
38.Dt BZERO 3 33.Dt BZERO 3
39.Os BSD 4.3 34.Os
40.Sh NAME 35.Sh NAME
41.Nm bzero 36.Nm bzero
42.Nd write zeroes to a byte string 37.Nd write zeroes to a byte string
@@ -47,8 +42,7 @@
47.Sh DESCRIPTION 42.Sh DESCRIPTION
48The 43The
49.Fn bzero 44.Fn bzero
50function 45function writes
51writes
52.Fa len 46.Fa len
53zero bytes to the string 47zero bytes to the string
54.Fa b . 48.Fa b .
@@ -63,6 +57,5 @@ does nothing.
63.Sh HISTORY 57.Sh HISTORY
64A 58A
65.Fn bzero 59.Fn bzero
66function 60function appeared in
67appeared in
68.Bx 4.3 . 61.Bx 4.3 .
diff --git a/src/lib/libc/string/bzero.c b/src/lib/libc/string/bzero.c
index 4865e396ef..7e557ecd4a 100644
--- a/src/lib/libc/string/bzero.c
+++ b/src/lib/libc/string/bzero.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,21 +28,22 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)bzero.c 5.7 (Berkeley) 2/24/91";*/ 31static char *rcsid = "$OpenBSD: bzero.c,v 1.5 2003/06/11 21:08:16 deraadt Exp $";
36static char *rcsid = "$Id: bzero.c,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
34#ifndef _KERNEL
39#include <string.h> 35#include <string.h>
36#else
37#include <lib/libkern/libkern.h>
38#endif
40 39
41/* 40/*
42 * bzero -- vax movc5 instruction 41 * bzero -- vax movc5 instruction
43 */ 42 */
44void 43void
45bzero(b, length) 44bzero(void *b, size_t length)
46 void *b;
47 register size_t length;
48{ 45{
49 register char *p; 46 char *p;
50 47
51 for (p = b; length--;) 48 for (p = b; length--;)
52 *p++ = '\0'; 49 *p++ = '\0';
diff --git a/src/lib/libc/string/ffs.3 b/src/lib/libc/string/ffs.3
index 6464bea2b1..a2f0cd336d 100644
--- a/src/lib/libc/string/ffs.3
+++ b/src/lib/libc/string/ffs.3
@@ -11,11 +11,7 @@
11.\" 2. Redistributions in binary form must reproduce the above copyright 11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the 12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution. 13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software 14.\" 3. Neither the name of the University nor the names of its contributors
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 15.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission. 16.\" without specific prior written permission.
21.\" 17.\"
@@ -31,8 +27,7 @@
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE. 28.\" SUCH DAMAGE.
33.\" 29.\"
34.\" from: @(#)ffs.3 5.3 (Berkeley) 4/19/91 30.\" $OpenBSD: ffs.3,v 1.4 2003/06/02 20:18:38 millert Exp $
35.\" $Id: ffs.3,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $
36.\" 31.\"
37.Dd April 19, 1991 32.Dd April 19, 1991
38.Dt FFS 3 33.Dt FFS 3
@@ -47,12 +42,10 @@
47.Sh DESCRIPTION 42.Sh DESCRIPTION
48The 43The
49.Fn ffs 44.Fn ffs
50function 45function finds the first bit set in
51finds the first bit set in
52.Fa value 46.Fa value
53and returns the index of that bit. 47and returns the index of that bit.
54Bits are numbered starting from 1, starting at the right-most 48Bits are numbered starting from 1, starting at the rightmost bit.
55bit.
56A return value of 0 means that the argument was zero. 49A return value of 0 means that the argument was zero.
57.Sh SEE ALSO 50.Sh SEE ALSO
58.Xr bitstring 3 51.Xr bitstring 3
diff --git a/src/lib/libc/string/ffs.c b/src/lib/libc/string/ffs.c
index 42bc87ddea..f1d14096a2 100644
--- a/src/lib/libc/string/ffs.c
+++ b/src/lib/libc/string/ffs.c
@@ -1,55 +1,48 @@
1/*- 1/* $OpenBSD: ffs.c,v 1.6 2003/06/11 21:08:16 deraadt Exp $ */
2 * Copyright (c) 1990 The Regents of the University of California. 2
3 * All rights reserved. 3/*
4 * 4 * Public domain.
5 * Redistribution and use in source and binary forms, with or without 5 * Written by Dale Rahn.
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 */ 6 */
33 7
34#if defined(LIBC_SCCS) && !defined(lint) 8#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)ffs.c 5.4 (Berkeley) 5/17/90";*/ 9static char *rcsid = "$OpenBSD: ffs.c,v 1.6 2003/06/11 21:08:16 deraadt Exp $";
36static char *rcsid = "$Id: ffs.c,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 10#endif /* LIBC_SCCS and not lint */
38 11
12#if !defined(_KERNEL) && !defined(_STANDALONE)
39#include <string.h> 13#include <string.h>
14#else
15#include <lib/libkern/libkern.h>
16#endif
40 17
41/* 18/*
42 * ffs -- vax ffs instruction 19 * ffs -- vax ffs instruction
43 */ 20 */
44int 21int
45ffs(mask) 22ffs(int mask)
46 register int mask;
47{ 23{
48 register int bit; 24 int bit;
25 unsigned int r = mask;
26 static const signed char t[16] = {
27 -28, 1, 2, 1,
28 3, 1, 2, 1,
29 4, 1, 2, 1,
30 3, 1, 2, 1
31 };
32
33 bit = 0;
34 if (!(r & 0xffff)) {
35 bit += 16;
36 r >>= 16;
37 }
38 if (!(r & 0xff)) {
39 bit += 8;
40 r >>= 8;
41 }
42 if (!(r & 0xf)) {
43 bit += 4;
44 r >>= 4;
45 }
49 46
50 if (mask == 0) 47 return (bit + t[ r & 0xf ]);
51 return(0);
52 for (bit = 1; !(mask & 1); bit++)
53 mask >>= 1;
54 return(bit);
55} 48}
diff --git a/src/lib/libc/string/index.3 b/src/lib/libc/string/index.3
deleted file mode 100644
index 847b03628b..0000000000
--- a/src/lib/libc/string/index.3
+++ /dev/null
@@ -1,83 +0,0 @@
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.\" from: @(#)index.3 5.3 (Berkeley) 4/19/91
35.\" $Id: index.3,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $
36.\"
37.Dd April 19, 1991
38.Dt INDEX 3
39.Os
40.Sh NAME
41.Nm index
42.Nd locate character in string
43.Sh SYNOPSIS
44.Fd #include <string.h>
45.Ft char *
46.Fn index "const char *s" "int c"
47.Sh DESCRIPTION
48The
49.Fn index
50function
51locates the first character matching
52.Fa c
53(converted to a
54.Em char )
55in the null-terminated string
56.Fa s .
57.Sh RETURN VALUES
58The character
59.Fa c
60is returned if it is found; otherwise
61.Dv NULL
62is returned.
63If
64.Fa c
65is '\e0',
66.Fn index
67locates the terminating '\e0'.
68.Sh SEE ALSO
69.Xr memchr 3 ,
70.Xr rindex 3 ,
71.Xr strchr 3 ,
72.Xr strcspn 3 ,
73.Xr strpbrk 3 ,
74.Xr strrchr 3 ,
75.Xr strsep 3 ,
76.Xr strspn 3 ,
77.Xr strstr 3 ,
78.Xr strtok 3
79.Sh HISTORY
80A
81.Fn index
82function appeared in
83.At v6 .
diff --git a/src/lib/libc/string/index.c b/src/lib/libc/string/index.c
index 3d9c05f961..52d0fd46fa 100644
--- a/src/lib/libc/string/index.c
+++ b/src/lib/libc/string/index.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,19 +28,17 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)index.c 5.7 (Berkeley) 2/24/91";*/ 31static char *rcsid = "$OpenBSD: index.c,v 1.4 2003/06/02 20:18:38 millert Exp $";
36static char *rcsid = "$Id: index.c,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
39#include <string.h> 34#include <string.h>
40 35
41char * 36char *
42#ifdef STRCHR 37#ifdef STRCHR
43strchr(p, ch) 38strchr(const char *p, int ch)
44#else 39#else
45index(p, ch) 40index(const char *p, int ch)
46#endif 41#endif
47 register const char *p, ch;
48{ 42{
49 for (;; ++p) { 43 for (;; ++p) {
50 if (*p == ch) 44 if (*p == ch)
diff --git a/src/lib/libc/string/memccpy.3 b/src/lib/libc/string/memccpy.3
index 61df704028..8c159cb8de 100644
--- a/src/lib/libc/string/memccpy.3
+++ b/src/lib/libc/string/memccpy.3
@@ -1,5 +1,7 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California. 1.\" $OpenBSD: memccpy.3,v 1.8 2003/06/02 20:18:38 millert Exp $
2.\" All rights reserved. 2.\"
3.\" Copyright (c) 1990, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
3.\" 5.\"
4.\" Redistribution and use in source and binary forms, with or without 6.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions 7.\" modification, are permitted provided that the following conditions
@@ -9,11 +11,7 @@
9.\" 2. Redistributions in binary form must reproduce the above copyright 11.\" 2. Redistributions in binary form must reproduce the above copyright
10.\" notice, this list of conditions and the following disclaimer in the 12.\" notice, this list of conditions and the following disclaimer in the
11.\" documentation and/or other materials provided with the distribution. 13.\" documentation and/or other materials provided with the distribution.
12.\" 3. All advertising materials mentioning features or use of this software 14.\" 3. Neither the name of the University nor the names of its contributors
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 15.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission. 16.\" without specific prior written permission.
19.\" 17.\"
@@ -29,14 +27,14 @@
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE. 28.\" SUCH DAMAGE.
31.\" 29.\"
32.\" from: @(#)memccpy.3 5.4 (Berkeley) 4/19/91 30.\" @(#)memccpy.3 8.1 (Berkeley) 6/9/93
33.\" $Id: memccpy.3,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $
34.\" 31.\"
35.Dd April 19, 1991 32.Dd June 9, 1993
36.Dt MEMCCPY 3 33.Dt MEMCCPY 3
37.Os 34.Os
38.Sh NAME 35.Sh NAME
39.Nm memccpy 36.Nm memccpy
37.Nd copy string until character found
40.Sh SYNOPSIS 38.Sh SYNOPSIS
41.Fd #include <string.h> 39.Fd #include <string.h>
42.Ft void * 40.Ft void *
@@ -44,14 +42,15 @@
44.Sh DESCRIPTION 42.Sh DESCRIPTION
45The 43The
46.Fn memccpy 44.Fn memccpy
47function 45function copies bytes from string
48copies bytes from string
49.Fa src 46.Fa src
50to string 47to string
51.Fa dst . 48.Fa dst .
52If the character 49If the character
53.Fa c 50.Fa c
54(as converted to an unsigned char) occurs in the string 51(as converted to an
52.Li unsigned char )
53occurs in the string
55.Fa src , 54.Fa src ,
56the copy stops and a pointer to the byte after the copy of 55the copy stops and a pointer to the byte after the copy of
57.Fa c 56.Fa c
@@ -60,14 +59,15 @@ in the string
60is returned. 59is returned.
61Otherwise, 60Otherwise,
62.Fa len 61.Fa len
63bytes are copied, and a NULL pointer is returned. 62bytes are copied, and a null pointer is returned.
64.Sh SEE ALSO 63.Sh SEE ALSO
65.Xr bcopy 3 , 64.Xr bcopy 3 ,
66.Xr memcpy 3 , 65.Xr memcpy 3 ,
67.Xr memmove 3 , 66.Xr memmove 3 ,
68.Xr strcpy 3 67.Xr strcpy 3 ,
68.Xr strlcpy 3
69.Sh HISTORY 69.Sh HISTORY
70The 70The
71.Fn memccpy 71.Fn memccpy
72function is 72function first appeared in
73.Ud . 73.Bx 4.4 .
diff --git a/src/lib/libc/string/memccpy.c b/src/lib/libc/string/memccpy.c
index 3a1d7bcca1..37496d1c26 100644
--- a/src/lib/libc/string/memccpy.c
+++ b/src/lib/libc/string/memccpy.c
@@ -1,6 +1,8 @@
1/* $OpenBSD: memccpy.c,v 1.4 2003/06/02 20:18:38 millert Exp $ */
2
1/*- 3/*-
2 * Copyright (c) 1990 The Regents of the University of California. 4 * Copyright (c) 1990, 1993
3 * All rights reserved. 5 * The Regents of the University of California. All rights reserved.
4 * 6 *
5 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
@@ -10,11 +12,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 15 * 3. Neither the name of the University nor the names of its contributors
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 16 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 17 * without specific prior written permission.
20 * 18 *
@@ -32,8 +30,11 @@
32 */ 30 */
33 31
34#if defined(LIBC_SCCS) && !defined(lint) 32#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)memccpy.c 5.8 (Berkeley) 5/30/91";*/ 33#if 0
36static char *rcsid = "$Id: memccpy.c,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $"; 34static char sccsid[] = "@(#)memccpy.c 8.1 (Berkeley) 6/4/93";
35#else
36static char *rcsid = "$OpenBSD: memccpy.c,v 1.4 2003/06/02 20:18:38 millert Exp $";
37#endif
37#endif /* LIBC_SCCS and not lint */ 38#endif /* LIBC_SCCS and not lint */
38 39
39#include <string.h> 40#include <string.h>
diff --git a/src/lib/libc/string/memchr.3 b/src/lib/libc/string/memchr.3
index 265711e3b5..ddca58bc5e 100644
--- a/src/lib/libc/string/memchr.3
+++ b/src/lib/libc/string/memchr.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,8 +29,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)memchr.3 5.4 (Berkeley) 6/29/91 32.\" $OpenBSD: memchr.3,v 1.6 2003/06/02 20:18:38 millert Exp $
37.\" $Id: memchr.3,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd June 29, 1991
40.Dt MEMCHR 3 35.Dt MEMCHR 3
@@ -49,23 +44,21 @@
49.Sh DESCRIPTION 44.Sh DESCRIPTION
50The 45The
51.Fn memchr 46.Fn memchr
52function 47function locates the first occurrence of
53locates the first occurrence of
54.Fa c 48.Fa c
55(converted to an unsigned char) 49(converted to an
50.Li unsigned char )
56in string 51in string
57.Fa b . 52.Fa b .
58.Sh RETURN VALUES 53.Sh RETURN VALUES
59The 54The
60.Fn memchr 55.Fn memchr
61function 56function returns a pointer to the byte located, or
62returns a pointer to the byte located, 57.Dv NULL
63or NULL if no such byte exists within 58if no such byte exists within
64.Fa len 59.Fa len
65bytes. 60bytes.
66.Sh SEE ALSO 61.Sh SEE ALSO
67.Xr index 3 ,
68.Xr rindex 3 ,
69.Xr strchr 3 , 62.Xr strchr 3 ,
70.Xr strcspn 3 , 63.Xr strcspn 3 ,
71.Xr strpbrk 3 , 64.Xr strpbrk 3 ,
@@ -77,6 +70,5 @@ bytes.
77.Sh STANDARDS 70.Sh STANDARDS
78The 71The
79.Fn memchr 72.Fn memchr
80function 73function conforms to
81conforms to
82.St -ansiC . 74.St -ansiC .
diff --git a/src/lib/libc/string/memchr.c b/src/lib/libc/string/memchr.c
index 61652c6bb1..454abcbc17 100644
--- a/src/lib/libc/string/memchr.c
+++ b/src/lib/libc/string/memchr.c
@@ -13,11 +13,7 @@
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software 16 * 3. Neither the name of the University nor the names of its contributors
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 17 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission. 18 * without specific prior written permission.
23 * 19 *
@@ -35,23 +31,19 @@
35 */ 31 */
36 32
37#if defined(LIBC_SCCS) && !defined(lint) 33#if defined(LIBC_SCCS) && !defined(lint)
38/*static char *sccsid = "from: @(#)memchr.c 5.6 (Berkeley) 1/26/91";*/ 34static char *rcsid = "$OpenBSD: memchr.c,v 1.6 2003/06/11 21:08:16 deraadt Exp $";
39static char *rcsid = "$Id: memchr.c,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */ 35#endif /* LIBC_SCCS and not lint */
41 36
42#include <string.h> 37#include <string.h>
43 38
44void * 39void *
45memchr(s, c, n) 40memchr(const void *s, int c, size_t n)
46 const void *s;
47 register unsigned char c;
48 register size_t n;
49{ 41{
50 if (n != 0) { 42 if (n != 0) {
51 register const unsigned char *p = s; 43 const unsigned char *p = s;
52 44
53 do { 45 do {
54 if (*p++ == c) 46 if (*p++ == (unsigned char)c)
55 return ((void *)(p - 1)); 47 return ((void *)(p - 1));
56 } while (--n != 0); 48 } while (--n != 0);
57 } 49 }
diff --git a/src/lib/libc/string/memcmp.3 b/src/lib/libc/string/memcmp.3
index 13901c1009..bd46e6898e 100644
--- a/src/lib/libc/string/memcmp.3
+++ b/src/lib/libc/string/memcmp.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,8 +29,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)memcmp.3 5.5 (Berkeley) 6/29/91 32.\" $OpenBSD: memcmp.3,v 1.5 2003/06/02 20:18:38 millert Exp $
37.\" $Id: memcmp.3,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd June 29, 1991
40.Dt MEMCMP 3 35.Dt MEMCMP 3
@@ -49,8 +44,7 @@
49.Sh DESCRIPTION 44.Sh DESCRIPTION
50The 45The
51.Fn memcmp 46.Fn memcmp
52function 47function compares byte string
53compares byte string
54.Fa b1 48.Fa b1
55against byte string 49against byte string
56.Fa b2 . 50.Fa b2 .
@@ -60,10 +54,11 @@ bytes long.
60.Sh RETURN VALUES 54.Sh RETURN VALUES
61The 55The
62.Fn memcmp 56.Fn memcmp
63function 57function returns zero if the two strings are identical,
64returns zero if the the two strings are identical,
65otherwise returns the difference between the first two differing bytes 58otherwise returns the difference between the first two differing bytes
66(treated as unsigned char values, so that 59(treated as
60.Li unsigned char
61values, so that
67.Sq Li \e200 62.Sq Li \e200
68is greater than 63is greater than
69.Sq Li \&\e0 , 64.Sq Li \&\e0 ,
@@ -78,6 +73,5 @@ Zero-length strings are always identical.
78.Sh STANDARDS 73.Sh STANDARDS
79The 74The
80.Fn memcmp 75.Fn memcmp
81function 76function conforms to
82conforms to
83.St -ansiC . 77.St -ansiC .
diff --git a/src/lib/libc/string/memcmp.c b/src/lib/libc/string/memcmp.c
index 23d2ab2393..6c83208a7b 100644
--- a/src/lib/libc/string/memcmp.c
+++ b/src/lib/libc/string/memcmp.c
@@ -13,11 +13,7 @@
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software 16 * 3. Neither the name of the University nor the names of its contributors
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 17 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission. 18 * without specific prior written permission.
23 * 19 *
@@ -35,8 +31,7 @@
35 */ 31 */
36 32
37#if defined(LIBC_SCCS) && !defined(lint) 33#if defined(LIBC_SCCS) && !defined(lint)
38/*static char *sccsid = "from: @(#)memcmp.c 5.6 (Berkeley) 1/26/91";*/ 34static char *rcsid = "$OpenBSD: memcmp.c,v 1.4 2003/06/11 21:08:16 deraadt Exp $";
39static char *rcsid = "$Id: memcmp.c,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */ 35#endif /* LIBC_SCCS and not lint */
41 36
42#include <string.h> 37#include <string.h>
@@ -45,12 +40,10 @@ static char *rcsid = "$Id: memcmp.c,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $"
45 * Compare memory regions. 40 * Compare memory regions.
46 */ 41 */
47int 42int
48memcmp(s1, s2, n) 43memcmp(const void *s1, const void *s2, size_t n)
49 const void *s1, *s2;
50 size_t n;
51{ 44{
52 if (n != 0) { 45 if (n != 0) {
53 register const unsigned char *p1 = s1, *p2 = s2; 46 const unsigned char *p1 = s1, *p2 = s2;
54 47
55 do { 48 do {
56 if (*p1++ != *p2++) 49 if (*p1++ != *p2++)
diff --git a/src/lib/libc/string/memcpy.3 b/src/lib/libc/string/memcpy.3
index 3f4bb643c9..c8265d94a6 100644
--- a/src/lib/libc/string/memcpy.3
+++ b/src/lib/libc/string/memcpy.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,15 +29,14 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)memcpy.3 5.5 (Berkeley) 6/29/91 32.\" $OpenBSD: memcpy.3,v 1.6 2003/06/21 12:04:01 avsm Exp $
37.\" $Id: memcpy.3,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd June 29, 1991
40.Dt MEMCPY 3 35.Dt MEMCPY 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
43.Nm memcpy 38.Nm memcpy
44.Nd copy byte string 39.Nd copy bytes
45.Sh SYNOPSIS 40.Sh SYNOPSIS
46.Fd #include <string.h> 41.Fd #include <string.h>
47.Ft void * 42.Ft void *
@@ -49,36 +44,34 @@
49.Sh DESCRIPTION 44.Sh DESCRIPTION
50The 45The
51.Fn memcpy 46.Fn memcpy
52function 47function copies
53copies
54.Fa len 48.Fa len
55bytes from string 49bytes from buffer
56.Fa src 50.Fa src
57to string 51to buffer
58.Fa dst . 52.Fa dst .
59.Sh RETURN VALUES 53.Sh RETURN VALUES
60The 54The
61.Fn memcpy 55.Fn memcpy
62function 56function returns the original value of
63returns the original value of
64.Fa dst . 57.Fa dst .
65.Sh SEE ALSO 58.Sh SEE ALSO
66.Xr bcopy 3 , 59.Xr bcopy 3 ,
67.Xr memccpy 3 , 60.Xr memccpy 3 ,
68.Xr memmove 3 , 61.Xr memmove 3 ,
69.Xr strcpy 3 62.Xr strcpy 3 ,
63.Xr strlcpy 3
70.Sh STANDARDS 64.Sh STANDARDS
71The 65The
72.Fn memcpy 66.Fn memcpy
73function 67function conforms to
74conforms to
75.St -ansiC . 68.St -ansiC .
76.Sh BUGS 69.Sh BUGS
77In this implementation 70In this implementation
78.Fn memcpy 71.Fn memcpy
79is implemented using 72is implemented using
80.Xr bcopy 3 , 73.Xr bcopy 3 ,
81and therefore the strings may overlap. 74and therefore the buffers may overlap.
82On other systems, copying overlapping strings may produce surprises. 75On other systems, copying overlapping buffers may produce surprises.
83A simpler solution is to not use 76A simpler solution is to not use
84.Fn memcpy . 77.Fn memcpy .
diff --git a/src/lib/libc/string/memmove.3 b/src/lib/libc/string/memmove.3
index 24422e7971..d4a364eb36 100644
--- a/src/lib/libc/string/memmove.3
+++ b/src/lib/libc/string/memmove.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,15 +29,14 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)memmove.3 5.5 (Berkeley) 6/29/91 32.\" $OpenBSD: memmove.3,v 1.6 2003/06/21 12:04:01 avsm Exp $
37.\" $Id: memmove.3,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd June 29, 1991
40.Dt MEMMOVE 3 35.Dt MEMMOVE 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
43.Nm memmove 38.Nm memmove
44.Nd copy byte string 39.Nd copy bytes
45.Sh SYNOPSIS 40.Sh SYNOPSIS
46.Fd #include <string.h> 41.Fd #include <string.h>
47.Ft void * 42.Ft void *
@@ -49,14 +44,13 @@
49.Sh DESCRIPTION 44.Sh DESCRIPTION
50The 45The
51.Fn memmove 46.Fn memmove
52function 47function copies
53copies
54.Fa len 48.Fa len
55bytes from string 49bytes from buffer
56.Fa src 50.Fa src
57to string 51to buffer
58.Fa dst . 52.Fa dst .
59The two strings may overlap; 53The two buffers may overlap;
60the copy is always done in a non-destructive manner. 54the copy is always done in a non-destructive manner.
61.Sh RETURN VALUES 55.Sh RETURN VALUES
62The 56The
@@ -67,10 +61,10 @@ function returns the original value of
67.Xr bcopy 3 , 61.Xr bcopy 3 ,
68.Xr memccpy 3 , 62.Xr memccpy 3 ,
69.Xr memcpy 3 , 63.Xr memcpy 3 ,
70.Xr strcpy 3 64.Xr strcpy 3 ,
65.Xr strlcpy 3
71.Sh STANDARDS 66.Sh STANDARDS
72The 67The
73.Fn memmove 68.Fn memmove
74function 69function conforms to
75conforms to
76.St -ansiC . 70.St -ansiC .
diff --git a/src/lib/libc/string/memset.3 b/src/lib/libc/string/memset.3
index 1afc052182..291b1427dc 100644
--- a/src/lib/libc/string/memset.3
+++ b/src/lib/libc/string/memset.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,8 +29,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)memset.3 5.4 (Berkeley) 6/29/91 32.\" $OpenBSD: memset.3,v 1.5 2003/06/02 20:18:38 millert Exp $
37.\" $Id: memset.3,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd June 29, 1991
40.Dt MEMSET 3 35.Dt MEMSET 3
@@ -49,12 +44,18 @@
49.Sh DESCRIPTION 44.Sh DESCRIPTION
50The 45The
51.Fn memset 46.Fn memset
52function 47function writes
53writes
54.Fa len 48.Fa len
55bytes of value 49bytes of value
56.Fa c 50.Fa c
57(converted to an unsigned char) to the string 51(converted to an
52.Li unsigned char )
53to the string
54.Fa b .
55.Sh RETURN VALUES
56The
57.Fn memset
58function returns the original value of
58.Fa b . 59.Fa b .
59.Sh SEE ALSO 60.Sh SEE ALSO
60.Xr bzero 3 , 61.Xr bzero 3 ,
@@ -62,6 +63,5 @@ bytes of value
62.Sh STANDARDS 63.Sh STANDARDS
63The 64The
64.Fn memset 65.Fn memset
65function 66function conforms to
66conforms to
67.St -ansiC . 67.St -ansiC .
diff --git a/src/lib/libc/string/memset.c b/src/lib/libc/string/memset.c
index 117de2e80b..9bc0556faa 100644
--- a/src/lib/libc/string/memset.c
+++ b/src/lib/libc/string/memset.c
@@ -13,11 +13,7 @@
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software 16 * 3. Neither the name of the University nor the names of its contributors
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 17 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission. 18 * without specific prior written permission.
23 * 19 *
@@ -35,21 +31,17 @@
35 */ 31 */
36 32
37#if defined(LIBC_SCCS) && !defined(lint) 33#if defined(LIBC_SCCS) && !defined(lint)
38/*static char *sccsid = "from: @(#)memset.c 5.6 (Berkeley) 1/26/91";*/ 34static char *rcsid = "$OpenBSD: memset.c,v 1.4 2003/06/11 21:08:16 deraadt Exp $";
39static char *rcsid = "$Id: memset.c,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */ 35#endif /* LIBC_SCCS and not lint */
41 36
42#include <string.h> 37#include <string.h>
43 38
44void * 39void *
45memset(dst, c, n) 40memset(void *dst, int c, size_t n)
46 void *dst;
47 register int c;
48 register size_t n;
49{ 41{
50 42
51 if (n != 0) { 43 if (n != 0) {
52 register char *d = dst; 44 char *d = dst;
53 45
54 do 46 do
55 *d++ = c; 47 *d++ = c;
diff --git a/src/lib/libc/string/rindex.3 b/src/lib/libc/string/rindex.3
deleted file mode 100644
index b13b3513e0..0000000000
--- a/src/lib/libc/string/rindex.3
+++ /dev/null
@@ -1,81 +0,0 @@
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.\" from: @(#)rindex.3 5.2 (Berkeley) 4/19/91
35.\" $Id: rindex.3,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $
36.\"
37.Dd April 19, 1991
38.Dt RINDEX 3
39.Os
40.Sh NAME
41.Nm rindex
42.Nd locate character in string
43.Sh SYNOPSIS
44.Fd #include <string.h>
45.Ft char *
46.Fn rindex "const char *s" "int c"
47.Sh DESCRIPTION
48The
49.Fn rindex
50function
51locates the last character
52matching
53.Fa c
54(converted to a
55.Em char )
56in the null-terminated string
57.Fa s .
58The character c is returned if it is found; otherwise NULL is returned.
59If
60.Fa c
61is
62.Ql \e0 ,
63.Fn rindex
64locates the terminating
65.Ql \e0 .
66.Sh SEE ALSO
67.Xr index 3 ,
68.Xr memchr 3 ,
69.Xr strchr 3 ,
70.Xr strcspn 3 ,
71.Xr strpbrk 3 ,
72.Xr strrchr 3 ,
73.Xr strsep 3 ,
74.Xr strspn 3 ,
75.Xr strstr 3 ,
76.Xr strtok 3
77.Sh HISTORY
78A
79.Fn rindex
80function appeared in
81.At v6 .
diff --git a/src/lib/libc/string/rindex.c b/src/lib/libc/string/rindex.c
index 1b84c92072..b880d0eaeb 100644
--- a/src/lib/libc/string/rindex.c
+++ b/src/lib/libc/string/rindex.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,21 +28,19 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)rindex.c 5.9 (Berkeley) 2/24/91";*/ 31static char *rcsid = "$OpenBSD: rindex.c,v 1.5 2003/06/11 21:08:16 deraadt Exp $";
36static char *rcsid = "$Id: rindex.c,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
39#include <string.h> 34#include <string.h>
40 35
41char * 36char *
42#ifdef STRRCHR 37#ifdef STRRCHR
43strrchr(p, ch) 38strrchr(const char *p, int ch)
44#else 39#else
45rindex(p, ch) 40rindex(const char *p, int ch)
46#endif 41#endif
47 register const char *p, ch;
48{ 42{
49 register char *save; 43 char *save;
50 44
51 for (save = NULL;; ++p) { 45 for (save = NULL;; ++p) {
52 if (*p == ch) 46 if (*p == ch)
diff --git a/src/lib/libc/string/strcasecmp.3 b/src/lib/libc/string/strcasecmp.3
index 46e9010e4f..e1f5d416d1 100644
--- a/src/lib/libc/string/strcasecmp.3
+++ b/src/lib/libc/string/strcasecmp.3
@@ -1,5 +1,7 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California. 1.\" $OpenBSD: strcasecmp.3,v 1.8 2003/06/02 20:18:38 millert Exp $
2.\" All rights reserved. 2.\"
3.\" Copyright (c) 1990, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
3.\" 5.\"
4.\" This code is derived from software contributed to Berkeley by 6.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek. 7.\" Chris Torek.
@@ -11,11 +13,7 @@
11.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission. 18.\" without specific prior written permission.
21.\" 19.\"
@@ -31,14 +29,14 @@
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
33.\" 31.\"
34.\" from: @(#)strcasecmp.3 5.4 (Berkeley) 4/19/91 32.\" @(#)strcasecmp.3 8.1 (Berkeley) 6/9/93
35.\" $Id: strcasecmp.3,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $
36.\" 33.\"
37.Dd April 19, 1991 34.Dd June 9, 1993
38.Dt STRCASECMP 3 35.Dt STRCASECMP 3
39.Os 36.Os
40.Sh NAME 37.Sh NAME
41.Nm strcasecmp 38.Nm strcasecmp ,
39.Nm strncasecmp
42.Nd compare strings, ignoring case 40.Nd compare strings, ignoring case
43.Sh SYNOPSIS 41.Sh SYNOPSIS
44.Fd #include <string.h> 42.Fd #include <string.h>
@@ -51,13 +49,12 @@ The
51.Fn strcasecmp 49.Fn strcasecmp
52and 50and
53.Fn strncasecmp 51.Fn strncasecmp
54functions 52functions compare the null-terminated strings
55compare the null-terminated strings
56.Fa s1 53.Fa s1
57and 54and
58.Fa s2 55.Fa s2
59and return an integer greater than, equal to, or less than 0, 56and return an integer greater than, equal to, or less than 0,
60according as 57according to whether
61.Fa s1 58.Fa s1
62is lexicographically greater than, equal to, or less than 59is lexicographically greater than, equal to, or less than
63.Fa s2 60.Fa s2
@@ -68,7 +65,6 @@ The comparison is done using unsigned characters, so that
68is greater than 65is greater than
69.Ql \e0 . 66.Ql \e0 .
70.Pp 67.Pp
71The
72.Fn strncasecmp 68.Fn strncasecmp
73compares at most 69compares at most
74.Fa len 70.Fa len
@@ -84,5 +80,5 @@ The
84.Fn strcasecmp 80.Fn strcasecmp
85and 81and
86.Fn strncasecmp 82.Fn strncasecmp
87functions are 83functions first appeared in
88.Ud . 84.Bx 4.4 .
diff --git a/src/lib/libc/string/strcasecmp.c b/src/lib/libc/string/strcasecmp.c
index 79bd0081e3..62da063444 100644
--- a/src/lib/libc/string/strcasecmp.c
+++ b/src/lib/libc/string/strcasecmp.c
@@ -1,6 +1,8 @@
1/* $OpenBSD: strcasecmp.c,v 1.5 2003/06/11 21:08:16 deraadt Exp $ */
2
1/* 3/*
2 * Copyright (c) 1987 Regents of the University of California. 4 * Copyright (c) 1987, 1993
3 * All rights reserved. 5 * The Regents of the University of California. All rights reserved.
4 * 6 *
5 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
@@ -10,11 +12,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 15 * 3. Neither the name of the University nor the names of its contributors
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 16 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 17 * without specific prior written permission.
20 * 18 *
@@ -31,13 +29,16 @@
31 * SUCH DAMAGE. 29 * SUCH DAMAGE.
32 */ 30 */
33 31
32#include <string.h>
33
34#if defined(LIBC_SCCS) && !defined(lint) 34#if defined(LIBC_SCCS) && !defined(lint)
35/*static const char sccsid[] = "from: @(#)strcasecmp.c 5.10 (Berkeley) 1/26/91";*/ 35#if 0
36static char *rcsid = "$Id: strcasecmp.c,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $"; 36static char sccsid[] = "@(#)strcasecmp.c 8.1 (Berkeley) 6/4/93";
37#else
38static char *rcsid = "$OpenBSD: strcasecmp.c,v 1.5 2003/06/11 21:08:16 deraadt Exp $";
39#endif
37#endif /* LIBC_SCCS and not lint */ 40#endif /* LIBC_SCCS and not lint */
38 41
39#include <string.h>
40
41typedef unsigned char u_char; 42typedef unsigned char u_char;
42 43
43/* 44/*
@@ -81,12 +82,11 @@ static const u_char charmap[] = {
81}; 82};
82 83
83int 84int
84strcasecmp(s1, s2) 85strcasecmp(const char *s1, const char *s2)
85 const char *s1, *s2;
86{ 86{
87 register const u_char *cm = charmap, 87 const u_char *cm = charmap;
88 *us1 = (const u_char *)s1, 88 const u_char *us1 = (const u_char *)s1;
89 *us2 = (const u_char *)s2; 89 const u_char *us2 = (const u_char *)s2;
90 90
91 while (cm[*us1] == cm[*us2++]) 91 while (cm[*us1] == cm[*us2++])
92 if (*us1++ == '\0') 92 if (*us1++ == '\0')
@@ -95,14 +95,12 @@ strcasecmp(s1, s2)
95} 95}
96 96
97int 97int
98strncasecmp(s1, s2, n) 98strncasecmp(const char *s1, const char *s2, size_t n)
99 const char *s1, *s2;
100 register size_t n;
101{ 99{
102 if (n != 0) { 100 if (n != 0) {
103 register const u_char *cm = charmap, 101 const u_char *cm = charmap;
104 *us1 = (const u_char *)s1, 102 const u_char *us1 = (const u_char *)s1;
105 *us2 = (const u_char *)s2; 103 const u_char *us2 = (const u_char *)s2;
106 104
107 do { 105 do {
108 if (cm[*us1] != cm[*us2++]) 106 if (cm[*us1] != cm[*us2++])
diff --git a/src/lib/libc/string/strcat.3 b/src/lib/libc/string/strcat.3
index 5357d65754..5b878c3e8c 100644
--- a/src/lib/libc/string/strcat.3
+++ b/src/lib/libc/string/strcat.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,14 +29,14 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)strcat.3 5.6 (Berkeley) 6/29/91 32.\" $OpenBSD: strcat.3,v 1.9 2003/06/02 20:18:38 millert Exp $
37.\" $Id: strcat.3,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd July 8, 1997
40.Dt STRCAT 3 35.Dt STRCAT 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
43.Nm strcat 38.Nm strcat ,
39.Nm strncat
44.Nd concatenate strings 40.Nd concatenate strings
45.Sh SYNOPSIS 41.Sh SYNOPSIS
46.Fd #include <string.h> 42.Fd #include <string.h>
@@ -53,8 +49,7 @@ The
53.Fn strcat 49.Fn strcat
54and 50and
55.Fn strncat 51.Fn strncat
56functions 52functions append a copy of the null-terminated string
57append a copy of the null-terminated string
58.Fa append 53.Fa append
59to the end of the null-terminated string 54to the end of the null-terminated string
60.Fa s , 55.Fa s ,
@@ -66,29 +61,71 @@ must have sufficient space to hold the result.
66.Pp 61.Pp
67The 62The
68.Fn strncat 63.Fn strncat
69function 64function appends not more than
70appends not more than
71.Fa count 65.Fa count
72characters. 66characters where space for the terminating
67.Ql \e0
68should not be included in
69.Fa count .
73.Sh RETURN VALUES 70.Sh RETURN VALUES
74The 71The
75.Fn strcat 72.Fn strcat
76and 73and
77.Fn strncat 74.Fn strncat
78functions 75functions return the pointer
79return the pointer
80.Fa s . 76.Fa s .
77.Sh EXAMPLES
78The following appends
79.Dq Li abc
80to
81.Dq Li chararray :
82.Bd -literal -offset indent
83char *letters = "abcdefghi";
84
85(void)strncat(chararray, letters, 3);
86.Ed
87.Pp
88The following example shows how to use
89.Fn strncat
90safely in conjunction with
91.Xr strncpy 3 .
92.Bd -literal -offset indent
93char buf[BUFSIZ];
94char *input, *suffix;
95
96(void)strncpy(buf, input, sizeof(buf) - 1);
97buf[sizeof(buf) - 1] = '\e0';
98(void)strncat(buf, suffix, sizeof(buf) - 1 - strlen(buf));
99.Ed
100.Pp
101The above will copy as many characters from
102.Dq Li input
103to
104.Dq Li buf
105as will fit.
106It then appends as many characters from suffix as will fit (or none
107if there is no space).
108For operations like this, the
109.Xr strlcpy 3
110and
111.Xr strlcat 3
112functions are a better choice, as shown below.
113.Bd -literal -offset indent
114(void)strlcpy(buf, input, sizeof(buf));
115(void)strlcat(buf, suffix, sizeof(buf));
116.Ed
81.Sh SEE ALSO 117.Sh SEE ALSO
82.Xr bcopy 3 , 118.Xr bcopy 3 ,
83.Xr memccpy 3 , 119.Xr memccpy 3 ,
84.Xr memcpy 3 , 120.Xr memcpy 3 ,
85.Xr memmove 3 , 121.Xr memmove 3 ,
86.Xr strcpy 3 122.Xr strcpy 3 ,
123.Xr strlcat 3 ,
124.Xr strlcpy 3
87.Sh STANDARDS 125.Sh STANDARDS
88The 126The
89.Fn strcat 127.Fn strcat
90and 128and
91.Fn strncat 129.Fn strncat
92functions 130functions conform to
93conform to
94.St -ansiC . 131.St -ansiC .
diff --git a/src/lib/libc/string/strcat.c b/src/lib/libc/string/strcat.c
index e741b84f03..885822bae3 100644
--- a/src/lib/libc/string/strcat.c
+++ b/src/lib/libc/string/strcat.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,20 +28,26 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)strcat.c 5.6 (Berkeley) 2/24/91";*/ 31static char *rcsid = "$OpenBSD: strcat.c,v 1.6 2003/07/24 01:15:42 deraadt Exp $";
36static char *rcsid = "$Id: strcat.c,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
34#ifndef _KERNEL
39#include <string.h> 35#include <string.h>
36#else
37#include <lib/libkern/libkern.h>
38#endif
39
40#if defined(APIWARN)
41__warn_references(strcat,
42 "warning: strcat() is almost always misused, please use strlcat()");
43#endif
40 44
41char * 45char *
42strcat(s, append) 46strcat(char *s, const char *append)
43 register char *s;
44 register const char *append;
45{ 47{
46 char *save = s; 48 char *save = s;
47 49
48 for (; *s; ++s); 50 for (; *s; ++s);
49 while (*s++ = *append++); 51 while ((*s++ = *append++) != '\0');
50 return(save); 52 return(save);
51} 53}
diff --git a/src/lib/libc/string/strchr.3 b/src/lib/libc/string/strchr.3
index 18b50301f3..86841bac25 100644
--- a/src/lib/libc/string/strchr.3
+++ b/src/lib/libc/string/strchr.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,29 +29,29 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)strchr.3 5.4 (Berkeley) 6/29/91 32.\" $OpenBSD: strchr.3,v 1.8 2003/06/02 20:18:38 millert Exp $
37.\" $Id: strchr.3,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd June 29, 1991
40.Dt STRCHR 3 35.Dt STRCHR 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
43.Nm strchr 38.Nm strchr ,
44.Nd locate character in string 39.Nm index
40.Nd locate first occurrence of a character in a string
45.Sh SYNOPSIS 41.Sh SYNOPSIS
46.Fd #include <string.h> 42.Fd #include <string.h>
47.Ft char * 43.Ft char *
48.Fn strchr "const char *s" "int c" 44.Fn strchr "const char *s" "int c"
45.Ft char *
46.Fn index "const char *s" "int c"
49.Sh DESCRIPTION 47.Sh DESCRIPTION
50The 48The
51.Fn strchr 49.Fn strchr
52function locates the first occurrence of 50function locates the first occurrence of the character
53.Ar c 51.Fa c
54in the string pointed to by 52in the string
55.Ar s . 53.Fa s .
56The terminating 54The terminating NUL character is considered part of the string.
57.Dv NULL
58character is considered part of the string.
59If 55If
60.Fa c 56.Fa c
61is 57is
@@ -63,16 +59,31 @@ is
63.Fn strchr 59.Fn strchr
64locates the terminating 60locates the terminating
65.Ql \e0 . 61.Ql \e0 .
62.Pp
63The
64.Fn index
65function is an old synonym for
66.Fn strchr .
66.Sh RETURN VALUES 67.Sh RETURN VALUES
67The function 68The
68.Fn strchr 69.Fn strchr
69returns a pointer to the located character, or 70function returns a pointer to the located character or
70.Dv NULL 71.Dv NULL
71if the character does not appear in the string. 72if the character does not appear in the string.
73.Sh EXAMPLES
74After the following call to
75.Fn strchr ,
76.Va p
77will point to the string
78.Qq oobar :
79.Bd -literal -offset indent
80char *p;
81char *s = "foobar";
82
83p = strchr(s, 'o');
84.Ed
72.Sh SEE ALSO 85.Sh SEE ALSO
73.Xr index 3 ,
74.Xr memchr 3 , 86.Xr memchr 3 ,
75.Xr rindex 3 ,
76.Xr strcspn 3 , 87.Xr strcspn 3 ,
77.Xr strpbrk 3 , 88.Xr strpbrk 3 ,
78.Xr strrchr 3 , 89.Xr strrchr 3 ,
@@ -83,6 +94,9 @@ if the character does not appear in the string.
83.Sh STANDARDS 94.Sh STANDARDS
84The 95The
85.Fn strchr 96.Fn strchr
86function 97function conforms to
87conforms to
88.St -ansiC . 98.St -ansiC .
99.Pp
100The
101.Fn index
102function 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
index fecaa85410..d025b9cf7c 100644
--- a/src/lib/libc/string/strcmp.3
+++ b/src/lib/libc/string/strcmp.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,14 +29,14 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)strcmp.3 5.6 (Berkeley) 6/29/91 32.\" $OpenBSD: strcmp.3,v 1.7 2003/06/02 20:18:38 millert Exp $
37.\" $Id: strcmp.3,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd June 29, 1991
40.Dt STRCMP 3 35.Dt STRCMP 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
43.Nm strcmp 38.Nm strcmp ,
39.Nm strncmp
44.Nd compare strings 40.Nd compare strings
45.Sh SYNOPSIS 41.Sh SYNOPSIS
46.Fd #include <string.h> 42.Fd #include <string.h>
@@ -53,8 +49,7 @@ The
53.Fn strcmp 49.Fn strcmp
54and 50and
55.Fn strncmp 51.Fn strncmp
56functions 52functions lexicographically compare the null-terminated strings
57lexicographically compare the null-terminated strings
58.Fa s1 53.Fa s1
59and 54and
60.Fa s2 . 55.Fa s2 .
@@ -64,7 +59,7 @@ The
64and 59and
65.Fn strncmp 60.Fn strncmp
66return an integer greater than, equal to, or less than 0, according 61return an integer greater than, equal to, or less than 0, according
67as the string 62to whether the string
68.Fa s1 63.Fa s1
69is greater than, equal to, or less than the string 64is greater than, equal to, or less than the string
70.Fa s2 . 65.Fa s2 .
@@ -73,9 +68,8 @@ The comparison is done using unsigned characters, so that
73is greater than 68is greater than
74.Ql \e0 . 69.Ql \e0 .
75.Pp 70.Pp
76The
77.Fn strncmp 71.Fn strncmp
78compares not more than 72compares at most
79.Fa len 73.Fa len
80characters. 74characters.
81.Sh SEE ALSO 75.Sh SEE ALSO
@@ -89,6 +83,5 @@ The
89.Fn strcmp 83.Fn strcmp
90and 84and
91.Fn strncmp 85.Fn strncmp
92functions 86functions conform to
93conform to
94.St -ansiC . 87.St -ansiC .
diff --git a/src/lib/libc/string/strcmp.c b/src/lib/libc/string/strcmp.c
index ae19e2e26e..9bda0a8d75 100644
--- a/src/lib/libc/string/strcmp.c
+++ b/src/lib/libc/string/strcmp.c
@@ -13,11 +13,7 @@
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software 16 * 3. Neither the name of the University nor the names of its contributors
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 17 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission. 18 * without specific prior written permission.
23 * 19 *
@@ -35,18 +31,20 @@
35 */ 31 */
36 32
37#if defined(LIBC_SCCS) && !defined(lint) 33#if defined(LIBC_SCCS) && !defined(lint)
38/*static char *sccsid = "from: @(#)strcmp.c 5.5 (Berkeley) 1/26/91";*/ 34static char *rcsid = "$OpenBSD: strcmp.c,v 1.5 2003/06/11 21:08:16 deraadt Exp $";
39static char *rcsid = "$Id: strcmp.c,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */ 35#endif /* LIBC_SCCS and not lint */
41 36
37#ifndef _KERNEL
42#include <string.h> 38#include <string.h>
39#else
40#include <lib/libkern/libkern.h>
41#endif
43 42
44/* 43/*
45 * Compare strings. 44 * Compare strings.
46 */ 45 */
47int 46int
48strcmp(s1, s2) 47strcmp(const char *s1, const char *s2)
49 register const char *s1, *s2;
50{ 48{
51 while (*s1 == *s2++) 49 while (*s1 == *s2++)
52 if (*s1++ == 0) 50 if (*s1++ == 0)
diff --git a/src/lib/libc/string/strcoll.3 b/src/lib/libc/string/strcoll.3
index 12f73f98f2..fe0ff35510 100644
--- a/src/lib/libc/string/strcoll.3
+++ b/src/lib/libc/string/strcoll.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,8 +29,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)strcoll.3 5.6 (Berkeley) 6/29/91 32.\" $OpenBSD: strcoll.3,v 1.5 2003/06/02 20:18:38 millert Exp $
37.\" $Id: strcoll.3,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd June 29, 1991
40.Dt STRCOLL 3 35.Dt STRCOLL 3
@@ -49,14 +44,13 @@
49.Sh DESCRIPTION 44.Sh DESCRIPTION
50The 45The
51.Fn strcoll 46.Fn strcoll
52function 47function lexicographically compares the null-terminated strings
53lexicographically compares the null-terminated strings
54.Fa s1 48.Fa s1
55and 49and
56.Fa s2 50.Fa s2
57according to the current locale collation 51according to the current locale collation
58and returns an integer greater than, equal to, or less than 0, 52and returns an integer greater than, equal to, or less than 0,
59according as 53according to whether
60.Fa s1 54.Fa s1
61is greater than, equal to, or less than 55is greater than, equal to, or less than
62.Fa s2 . 56.Fa s2 .
@@ -70,6 +64,5 @@ is greater than, equal to, or less than
70.Sh STANDARDS 64.Sh STANDARDS
71The 65The
72.Fn strcoll 66.Fn strcoll
73function 67function conforms to
74conforms to
75.St -ansiC . 68.St -ansiC .
diff --git a/src/lib/libc/string/strcoll.c b/src/lib/libc/string/strcoll.c
index 86c742cba9..9622b67281 100644
--- a/src/lib/libc/string/strcoll.c
+++ b/src/lib/libc/string/strcoll.c
@@ -13,11 +13,7 @@
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software 16 * 3. Neither the name of the University nor the names of its contributors
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 17 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission. 18 * without specific prior written permission.
23 * 19 *
@@ -35,8 +31,7 @@
35 */ 31 */
36 32
37#if defined(LIBC_SCCS) && !defined(lint) 33#if defined(LIBC_SCCS) && !defined(lint)
38/*static char *sccsid = "from: @(#)strcoll.c 5.2 (Berkeley) 1/26/91";*/ 34static char *rcsid = "$OpenBSD: strcoll.c,v 1.4 2003/06/11 21:08:29 deraadt Exp $";
39static char *rcsid = "$Id: strcoll.c,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */ 35#endif /* LIBC_SCCS and not lint */
41 36
42#include <string.h> 37#include <string.h>
@@ -45,8 +40,7 @@ static char *rcsid = "$Id: strcoll.c,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $
45 * Compare strings according to LC_COLLATE category of current locale. 40 * Compare strings according to LC_COLLATE category of current locale.
46 */ 41 */
47int 42int
48strcoll(s1, s2) 43strcoll(const char *s1, const char *s2)
49 const char *s1, *s2;
50{ 44{
51 /* LC_COLLATE is unimplemented, hence always "C" */ 45 /* LC_COLLATE is unimplemented, hence always "C" */
52 return (strcmp(s1, s2)); 46 return (strcmp(s1, s2));
diff --git a/src/lib/libc/string/strcpy.3 b/src/lib/libc/string/strcpy.3
index 1ca12c2707..8304508df6 100644
--- a/src/lib/libc/string/strcpy.3
+++ b/src/lib/libc/string/strcpy.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,14 +29,14 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)strcpy.3 5.4 (Berkeley) 6/29/91 32.\" $OpenBSD: strcpy.3,v 1.12 2003/06/02 20:18:38 millert Exp $
37.\" $Id: strcpy.3,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd June 29, 1991
40.Dt STRCPY 3 35.Dt STRCPY 3
41.Os BSD 4 36.Os
42.Sh NAME 37.Sh NAME
43.Nm strcpy 38.Nm strcpy ,
39.Nm strncpy
44.Nd copy strings 40.Nd copy strings
45.Sh SYNOPSIS 41.Sh SYNOPSIS
46.Fd #include <string.h> 42.Fd #include <string.h>
@@ -53,8 +49,7 @@ The
53.Fn strcpy 49.Fn strcpy
54and 50and
55.Fn strncpy 51.Fn strncpy
56functions 52functions copy the string
57copy the string
58.Fa src 53.Fa src
59to 54to
60.Fa dst 55.Fa dst
@@ -62,7 +57,6 @@ to
62.Ql \e0 57.Ql \e0
63character). 58character).
64.Pp 59.Pp
65The
66.Fn strncpy 60.Fn strncpy
67copies not more than 61copies not more than
68.Fa len 62.Fa len
@@ -78,45 +72,79 @@ characters long, and
78.Em not 72.Em not
79terminating 73terminating
80.Fa dst 74.Fa dst
81if 75if the length of
82.Fa src 76.Fa src
83is more than 77is greater than or equal to
84.Fa len 78.Fa len .
85characters long.
86.Sh RETURN VALUES 79.Sh RETURN VALUES
87The 80The
88.Fn strcpy 81.Fn strcpy
89and 82and
90.Fn strncpy 83.Fn strncpy
91functions 84functions return
92return
93.Fa dst . 85.Fa dst .
94.Sh EXAMPLES 86.Sh EXAMPLES
95The following sets 87The following sets
96.Dq Li chararray 88.Va chararray
97to 89to
98.Dq Li abc\e0\e0\e0 : 90.Dq abc\e0\e0\e0 :
99.Bd -literal -offset indent 91.Bd -literal -offset indent
100(void)strncpy(chararray, "abc", 6). 92(void)strncpy(chararray, "abc", 6);
101.Ed 93.Ed
102.Pp 94.Pp
103The following sets 95The following sets
104.Dq Li chararray 96.Va chararray
105to 97to
106.Dq Li abcdef : 98.Dq abcdef
99and does
100.Em not
101null terminate
102.Va chararray
103because the source string is >= the length parameter.
104.Fn strncpy
105.Em only
106null terminates the destination string when the length of the source
107string is less than the length parameter.
107.Bd -literal -offset indent 108.Bd -literal -offset indent
108(void)strncpy(chararray, "abcdefgh", 6); 109(void)strncpy(chararray, "abcdefgh", 6);
109.Ed 110.Ed
111.Pp
112The following copies as many characters from
113.Va input
114to
115.Va buf
116as will fit and null terminates the result.
117Because
118.Fn strncpy
119does
120.Em not
121guarantee to null terminate the string itself, we must do this by hand.
122.Bd -literal -offset indent
123char buf[BUFSIZ];
124
125(void)strncpy(buf, input, sizeof(buf) - 1);
126buf[sizeof(buf) - 1] = '\e0';
127.Ed
128.Pp
129Note that
130.Xr strlcpy 3
131is a better choice for this kind of operation.
132The equivalent using
133.Xr strlcpy 3
134is simply:
135.Bd -literal -offset indent
136(void)strlcpy(buf, input, sizeof(buf));
137.Ed
110.Sh SEE ALSO 138.Sh SEE ALSO
111.Xr bcopy 3 , 139.Xr bcopy 3 ,
112.Xr memccpy 3 , 140.Xr memccpy 3 ,
113.Xr memcpy 3 , 141.Xr memcpy 3 ,
114.Xr memmove 3 142.Xr memmove 3 ,
143.Xr strlcpy 3
115.Sh STANDARDS 144.Sh STANDARDS
116The 145The
117.Fn strcpy 146.Fn strcpy
118and 147and
119.Fn strncpy 148.Fn strncpy
120functions 149functions conform to
121conform to
122.St -ansiC . 150.St -ansiC .
diff --git a/src/lib/libc/string/strcpy.c b/src/lib/libc/string/strcpy.c
index 669bfde23e..e5c3d7dcbe 100644
--- a/src/lib/libc/string/strcpy.c
+++ b/src/lib/libc/string/strcpy.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,19 +28,25 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)strcpy.c 5.7 (Berkeley) 2/24/91";*/ 31static char *rcsid = "$OpenBSD: strcpy.c,v 1.6 2003/07/24 01:15:42 deraadt Exp $";
36static char *rcsid = "$Id: strcpy.c,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
34#ifndef _KERNEL
39#include <string.h> 35#include <string.h>
36#else
37#include <lib/libkern/libkern.h>
38#endif
39
40#if defined(APIWARN)
41__warn_references(strcpy,
42 "warning: strcpy() is almost always misused, please use strlcpy()");
43#endif
40 44
41char * 45char *
42strcpy(to, from) 46strcpy(char *to, const char *from)
43 register char *to;
44 register const char *from;
45{ 47{
46 char *save = to; 48 char *save = to;
47 49
48 for (; *to = *from; ++from, ++to); 50 for (; (*to = *from) != '\0'; ++from, ++to);
49 return(save); 51 return(save);
50} 52}
diff --git a/src/lib/libc/string/strcspn.3 b/src/lib/libc/string/strcspn.3
index cc9e5c2fe3..6dfe1b276e 100644
--- a/src/lib/libc/string/strcspn.3
+++ b/src/lib/libc/string/strcspn.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,8 +29,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)strcspn.3 5.3 (Berkeley) 6/29/91 32.\" $OpenBSD: strcspn.3,v 1.6 2003/06/02 20:18:38 millert Exp $
37.\" $Id: strcspn.3,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd June 29, 1991
40.Dt STRCSPN 3 35.Dt STRCSPN 3
@@ -49,27 +44,36 @@
49.Sh DESCRIPTION 44.Sh DESCRIPTION
50The 45The
51.Fn strcspn 46.Fn strcspn
52function 47function spans the initial part of the null-terminated string
53spans the initial part of the null-terminated string
54.Fa s 48.Fa s
55as long as the characters from 49as long as the characters from
56.Fa s 50.Fa s
57do not occur in string 51do not occur in string
58.Fa charset 52.Fa charset
59(it 53(it spans the
60spans the
61.Em complement 54.Em complement
62of 55of
63.Fa charset ) . 56.Fa charset ) .
64.Sh RETURN VALUES 57.Sh RETURN VALUES
65The 58The
66.Fn strcspn 59.Fn strcspn
67function 60function returns the number of characters spanned.
68returns the number of characters spanned. 61.Sh EXAMPLES
62The following call to
63.Fn strcspn
64will return 3, since the first three characters of string
65.Fa s
66do not occur in string
67.Fa charset :
68.Bd -literal -offset indent
69char *s = "foobar";
70char *charset = "bar";
71size_t span;
72
73span = strcspn(s, charset);
74.Ed
69.Sh SEE ALSO 75.Sh SEE ALSO
70.Xr index 3 ,
71.Xr memchr 3 , 76.Xr memchr 3 ,
72.Xr rindex 3 ,
73.Xr strchr 3 , 77.Xr strchr 3 ,
74.Xr strpbrk 3 , 78.Xr strpbrk 3 ,
75.Xr strrchr 3 , 79.Xr strrchr 3 ,
@@ -80,6 +84,5 @@ returns the number of characters spanned.
80.Sh STANDARDS 84.Sh STANDARDS
81The 85The
82.Fn strcspn 86.Fn strcspn
83function 87function conforms to
84conforms to
85.St -ansiC . 88.St -ansiC .
diff --git a/src/lib/libc/string/strcspn.c b/src/lib/libc/string/strcspn.c
index acb4d2a3af..f96f903809 100644
--- a/src/lib/libc/string/strcspn.c
+++ b/src/lib/libc/string/strcspn.c
@@ -13,11 +13,7 @@
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software 16 * 3. Neither the name of the University nor the names of its contributors
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 17 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission. 18 * without specific prior written permission.
23 * 19 *
@@ -35,8 +31,7 @@
35 */ 31 */
36 32
37#if defined(LIBC_SCCS) && !defined(lint) 33#if defined(LIBC_SCCS) && !defined(lint)
38/*static char *sccsid = "from: @(#)strcspn.c 5.6 (Berkeley) 1/26/91";*/ 34static char *rcsid = "$OpenBSD: strcspn.c,v 1.4 2003/06/11 21:08:16 deraadt Exp $";
39static char *rcsid = "$Id: strcspn.c,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */ 35#endif /* LIBC_SCCS and not lint */
41 36
42#include <string.h> 37#include <string.h>
@@ -45,12 +40,10 @@ static char *rcsid = "$Id: strcspn.c,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $
45 * Span the complement of string s2. 40 * Span the complement of string s2.
46 */ 41 */
47size_t 42size_t
48strcspn(s1, s2) 43strcspn(const char *s1, const char *s2)
49 const char *s1;
50 register const char *s2;
51{ 44{
52 register const char *p, *spanp; 45 const char *p, *spanp;
53 register char c, sc; 46 char c, sc;
54 47
55 /* 48 /*
56 * Stop as soon as we find any character from s2. Note that there 49 * Stop as soon as we find any character from s2. Note that there
diff --git a/src/lib/libc/string/strdup.3 b/src/lib/libc/string/strdup.3
index 925cbf3d46..59b77f7a16 100644
--- a/src/lib/libc/string/strdup.3
+++ b/src/lib/libc/string/strdup.3
@@ -1,5 +1,7 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California. 1.\" $OpenBSD: strdup.3,v 1.12 2003/06/02 20:18:38 millert Exp $
2.\" All rights reserved. 2.\"
3.\" Copyright (c) 1990, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
3.\" 5.\"
4.\" Redistribution and use in source and binary forms, with or without 6.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions 7.\" modification, are permitted provided that the following conditions
@@ -9,11 +11,7 @@
9.\" 2. Redistributions in binary form must reproduce the above copyright 11.\" 2. Redistributions in binary form must reproduce the above copyright
10.\" notice, this list of conditions and the following disclaimer in the 12.\" notice, this list of conditions and the following disclaimer in the
11.\" documentation and/or other materials provided with the distribution. 13.\" documentation and/or other materials provided with the distribution.
12.\" 3. All advertising materials mentioning features or use of this software 14.\" 3. Neither the name of the University nor the names of its contributors
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 15.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission. 16.\" without specific prior written permission.
19.\" 17.\"
@@ -29,10 +27,9 @@
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE. 28.\" SUCH DAMAGE.
31.\" 29.\"
32.\" from: @(#)strdup.3 5.3 (Berkeley) 4/19/91 30.\" @(#)strdup.3 8.1 (Berkeley) 6/9/93
33.\" $Id: strdup.3,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $
34.\" 31.\"
35.Dd April 19, 1991 32.Dd June 9, 1993
36.Dt STRDUP 3 33.Dt STRDUP 3
37.Os 34.Os
38.Sh NAME 35.Sh NAME
@@ -41,25 +38,47 @@
41.Sh SYNOPSIS 38.Sh SYNOPSIS
42.Fd #include <string.h> 39.Fd #include <string.h>
43.Ft char * 40.Ft char *
44.Fn strdup "const char *str" 41.Fn strdup "const char *s"
45.Sh DESCRIPTION 42.Sh DESCRIPTION
46The 43The
47.Fn strdup 44.Fn strdup
48function 45function allocates sufficient memory for a copy of the string
49allocates sufficient memory for a copy 46.Fa s ,
50of the string
51.Fa str ,
52does the copy, and returns a pointer to it. 47does the copy, and returns a pointer to it.
53The pointer may subsequently be used as an 48The pointer may subsequently be used as an argument to the function
54argument to the function
55.Xr free 3 . 49.Xr free 3 .
50.Pp
51If insufficient memory is available,
52.Dv NULL
53is returned.
54.Sh EXAMPLES
55The following will point
56.Va p
57to an allocated area of memory containing the null-terminated string
58.Qq foobar :
59.Bd -literal -offset indent
60char *p;
61
62if ((p = strdup("foobar")) == NULL) {
63 fprintf(stderr, "Out of memory.\en");
64 exit(1);
65}
66.Ed
67.Sh ERRORS
68The
69.Fn strdup
70function may fail and set the external variable
71.Va errno
72for any of the errors specified for the library function
73.Xr malloc 3 .
56.Sh SEE ALSO 74.Sh SEE ALSO
57.Xr free 3 , 75.Xr free 3 ,
58.Xr malloc 3 , 76.Xr malloc 3 ,
59.Xt strcpy 3 , 77.Xr strcpy 3 ,
60.Xt strlen 3 78.Xr strlcpy 3 ,
79.Xr strlen 3
61.Sh HISTORY 80.Sh HISTORY
62The 81The
63.Fn strdup 82.Fn strdup
64function 83function first appeared in
65.Ud . 84.Bx 4.4 .
diff --git a/src/lib/libc/string/strdup.c b/src/lib/libc/string/strdup.c
index 27ede44110..bbea59888c 100644
--- a/src/lib/libc/string/strdup.c
+++ b/src/lib/libc/string/strdup.c
@@ -1,6 +1,8 @@
1/* $OpenBSD: strdup.c,v 1.5 2003/06/11 21:08:16 deraadt Exp $ */
2
1/* 3/*
2 * Copyright (c) 1988 The Regents of the University of California. 4 * Copyright (c) 1988, 1993
3 * All rights reserved. 5 * The Regents of the University of California. All rights reserved.
4 * 6 *
5 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
@@ -10,11 +12,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 15 * 3. Neither the name of the University nor the names of its contributors
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 16 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 17 * without specific prior written permission.
20 * 18 *
@@ -32,23 +30,28 @@
32 */ 30 */
33 31
34#if defined(LIBC_SCCS) && !defined(lint) 32#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)strdup.c 5.4 (Berkeley) 2/24/91";*/ 33#if 0
36static char *rcsid = "$Id: strdup.c,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $"; 34static char sccsid[] = "@(#)strdup.c 8.1 (Berkeley) 6/4/93";
35#else
36static char *rcsid = "$OpenBSD: strdup.c,v 1.5 2003/06/11 21:08:16 deraadt Exp $";
37#endif
37#endif /* LIBC_SCCS and not lint */ 38#endif /* LIBC_SCCS and not lint */
38 39
40#include <sys/types.h>
41
42#include <stddef.h>
39#include <stdlib.h> 43#include <stdlib.h>
40#include <string.h> 44#include <string.h>
41 45
42char * 46char *
43strdup(str) 47strdup(const char *str)
44 const char *str;
45{ 48{
46 size_t len; 49 size_t siz;
47 char *copy; 50 char *copy;
48 51
49 len = strlen(str) + 1; 52 siz = strlen(str) + 1;
50 if (!(copy = malloc(len))) 53 if ((copy = malloc(siz)) == NULL)
51 return((char *)NULL); 54 return(NULL);
52 memcpy(copy, str, len); 55 (void)memcpy(copy, str, siz);
53 return(copy); 56 return(copy);
54} 57}
diff --git a/src/lib/libc/string/strerror.3 b/src/lib/libc/string/strerror.3
index c9d8504dbb..fa573bc72a 100644
--- a/src/lib/libc/string/strerror.3
+++ b/src/lib/libc/string/strerror.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,12 +29,11 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)strerror.3 6.9 (Berkeley) 6/29/91 32.\" $OpenBSD: strerror.3,v 1.6 2003/06/02 20:18:38 millert Exp $
37.\" $Id: strerror.3,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd June 29, 1991
40.Dt STRERROR 3 35.Dt STRERROR 3
41.Os BSD 4 36.Os
42.Sh NAME 37.Sh NAME
43.Nm strerror 38.Nm strerror
44.Nd get error message string 39.Nd get error message string
@@ -46,15 +41,35 @@
46.Fd #include <string.h> 41.Fd #include <string.h>
47.Ft char * 42.Ft char *
48.Fn strerror "int errnum" 43.Fn strerror "int errnum"
44.Ft int
45.Fn strerror_r "int errnum" "char *strerrbuf" "size_t buflen"
49.Sh DESCRIPTION 46.Sh DESCRIPTION
50The 47The
51.Fn strerror 48.Fn strerror
52function returns a pointer to the language-dependent error message 49function returns a pointer to the language-dependent error message
53string affiliated with an error number. 50string affiliated with the specified error number
51.Fa errnum .
52The returned string contains a maximum of
53.Dv NL_TEXTMAX
54characters, including the trailing NUL.
54.Pp 55.Pp
55The array pointed to is not to be modified by the program, but may be 56The array pointed to is not to be modified by the program, but may be
56overwritten by subsequent calls to 57overwritten by subsequent calls to
57.Fn strerror . 58.Fn strerror .
59.Pp
60.Fn strerror_r
61is a thread safe version of
62.Fn strerror
63that places the error message in the given buffer
64.Fa strerrbuf .
65If the error message is larger then
66.Fa buflen
67the message will be truncated to fit within buflen and
68.Er ERANGE
69is returned.
70.Fn strerror_r
71returns zero upon successful completion.
72An error number is returned, otherwise.
58.Sh SEE ALSO 73.Sh SEE ALSO
59.Xr intro 2 , 74.Xr intro 2 ,
60.Xr perror 3 , 75.Xr perror 3 ,
@@ -64,3 +79,7 @@ The
64.Fn strerror 79.Fn strerror
65function conforms to 80function conforms to
66.St -ansiC . 81.St -ansiC .
82The
83.Fn strerror_r
84function conforms to
85.St -p1003.1 .
diff --git a/src/lib/libc/string/strerror.c b/src/lib/libc/string/strerror.c
index c3f5ab5d98..6496f50afd 100644
--- a/src/lib/libc/string/strerror.c
+++ b/src/lib/libc/string/strerror.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,8 +28,7 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)strerror.c 5.6 (Berkeley) 5/4/91";*/ 31static char *rcsid = "$OpenBSD: strerror.c,v 1.5 2003/06/11 21:08:16 deraadt Exp $";
36static char *rcsid = "$Id: strerror.c,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
39#include <string.h> 34#include <string.h>
@@ -45,11 +40,10 @@ static char *rcsid = "$Id: strerror.c,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp
45 * internal function __strerror(). 40 * internal function __strerror().
46 */ 41 */
47 42
48extern char *__strerror __P((int, char *)); 43extern char *__strerror(int, char *);
49 44
50char * 45char *
51strerror(num) 46strerror(int num)
52 int num;
53{ 47{
54 static char buf[NL_TEXTMAX]; 48 static char buf[NL_TEXTMAX];
55 return __strerror(num, buf); 49 return __strerror(num, buf);
diff --git a/src/lib/libc/string/strerror_r.c b/src/lib/libc/string/strerror_r.c
new file mode 100644
index 0000000000..aab6db5303
--- /dev/null
+++ b/src/lib/libc/string/strerror_r.c
@@ -0,0 +1,30 @@
1/* $OpenBSD: strerror_r.c,v 1.1 2002/11/21 20:45:05 marc Exp $ */
2/* Public Domain <marc@snafu.org> */
3
4#if defined(LIBC_SCCS) && !defined(lint)
5static char *rcsid = "$OpenBSD: strerror_r.c,v 1.1 2002/11/21 20:45:05 marc Exp $";
6#endif /* LIBC_SCCS and not lint */
7
8#include <errno.h>
9#include <limits.h>
10#include <string.h>
11
12extern char *__strerror(int, char *);
13
14int
15strerror_r(int errnum, char *strerrbuf, size_t buflen)
16{
17 int save_errno;
18 int ret_errno;
19 char buf[NL_TEXTMAX];
20
21 save_errno = errno;
22 errno = 0;
23 __strerror(errnum, buf);
24 if (strlcpy(strerrbuf, buf, buflen) >= buflen)
25 errno = ERANGE;
26 ret_errno = errno;
27 errno = save_errno;
28
29 return (ret_errno);
30}
diff --git a/src/lib/libc/string/strftime.3 b/src/lib/libc/string/strftime.3
deleted file mode 100644
index f14db4bb13..0000000000
--- a/src/lib/libc/string/strftime.3
+++ /dev/null
@@ -1,202 +0,0 @@
1.\" Copyright (c) 1989, 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.\" from: @(#)strftime.3 5.12 (Berkeley) 6/29/91
37.\" $Id: strftime.3,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $
38.\"
39.Dd June 29, 1991
40.Dt STRFTIME 3
41.Os
42.Sh NAME
43.Nm strftime
44.Nd format date and time
45.Sh SYNOPSIS
46.Fd #include <time.h>
47.Ft size_t
48.Fn strftime "char *buf" "size_t maxsize" "const char *format" "const struct tm *timeptr"
49.Sh DESCRIPTION
50The
51.Fn strftime
52function formats the information from
53.Fa timeptr
54into the buffer
55.Fa buf
56according to the string pointed to by
57.Fa format .
58.Pp
59The
60.Fa format
61string consists of zero or more conversion specifications and
62ordinary characters.
63All ordinary characters are copied directly into the buffer.
64A conversion specification consists of a percent sign
65.Ql %
66and one other character.
67.Pp
68No more than
69.Fa maxsize
70characters will be placed into the array.
71If the total number of resulting characters, including the terminating
72null character, is not more than
73.Fa maxsize ,
74.Fn strftime
75returns the number of characters in the array, not counting the
76terminating null.
77Otherwise, zero is returned.
78.Pp
79Each conversion specification is replaced by the characters as
80follows which are then copied into the buffer.
81.Bl -tag -width "xxxx"
82.It Cm \&%A
83is replaced by the locale's full weekday name.
84.It Cm %a
85is replaced by the locale's abbreviated weekday name.
86.It Cm \&%B
87is replaced by the locale's full month name.
88.It Cm \&%b No or Cm \&%h
89is replaced by the locale's abbreviated month name.
90.It Cm \&%C
91is replaced by the century (a year divided by 100 and truncated to an integer)
92as a decimal number (00-99).
93.It Cm \&%c
94is replaced by the locale's appropriate date and time representation.
95.It Cm \&%D
96is replaced by the date in the format
97.Dq Li %m/%d/%y .
98.It Cm \&%d
99is replaced by the day of the month as a decimal number (01-31).
100.It Cm \&%e
101is replaced by the day of month as a decimal number (1-31);
102single digits are preceded by a blank.
103.It Cm \&%H
104is replaced by the hour (24-hour clock) as a decimal number (00-23).
105.It Cm \&%I
106is replaced by the hour (12-hour clock) as a decimal number (01-12).
107.It Cm \&%j
108is replaced by the day of the year as a decimal number (001-366).
109.It Cm \&%k
110is replaced by the hour (24-hour clock) as a decimal number (0-23);
111single digits are preceded by a blank.
112.It Cm \&%l
113is replaced by the hour (12-hour clock) as a decimal number (1-12);
114single digits are preceded by a blank.
115.It Cm \&%M
116is replaced by the minute as a decimal number (00-59).
117.It Cm %m
118is replaced by the month as a decimal number (01-12).
119.It Cm %n
120is replaced by a newline.
121.It Cm %p
122is replaced by the locale's equivalent of either
123.Dq Tn AM
124or
125.Dq Tn PM .
126.It Cm \&%R
127is replaced by the time in the format
128.Dq Li %H:%M .
129.It Cm \&%r
130is replaced by the locale's representation of 12-hour clock time
131using AM/PM notation.
132.It Cm \&%T
133is replaced by the time in the format
134.Dq Li %H:%M:%S .
135.It Cm \&%t
136is replaced by a tab.
137.It Cm \&%S
138is replaced by the second as a decimal number (00-60).
139.It Cm %s
140is replaced by the number of seconds since the Epoch, UCT (see
141.Xr mktime 3 ) .
142.It Cm \&%U
143is replaced by the week number of the year (Sunday as the first day of
144the week) as a decimal number (00-53).
145.It Cm \&%u
146is replaced by the weekday (Monday as the first day of the week)
147as a decimal number (1-7).
148.It Cm \&%V
149is replaced by the week number of the year (Monday as the first day of
150the week) as a decimal number (01-53). If the week containing January
1511 has four or more days in the new year, then it is week 1; otherwise
152it is week 53 of the previous year, and the next week is week 1.
153.It Cm \&%W
154is replaced by the week number of the year (Monday as the first day of
155the week) as a decimal number (00-53).
156.It Cm \&%w
157is replaced by the weekday (Sunday as the first day of the week)
158as a decimal number (0-6).
159.It Cm \&%X
160is replaced by the locale's appropriate date representation.
161.It Cm \&%x
162is replaced by the locale's appropriate time representation.
163.It Cm \&%Y
164is replaced by the year with century as a decimal number.
165.It Cm \&%y
166is replaced by the year without century as a decimal number (00-99).
167.It Cm \&%Z
168is replaced by the time zone name.
169.It Cm %%
170is replaced by
171.Ql % .
172.El
173.Sh SEE ALSO
174.Xr date 1 ,
175.Xr ctime 3 ,
176.Xr printf 1 ,
177.Xr printf 3
178.Sh STANDARDS
179The
180.Fn strftime
181function
182conforms to
183.St -ansiC .
184The
185.Ql \&%C ,
186.Ql \&%D ,
187.Ql \&%e ,
188.Ql \&%h ,
189.Ql \&%k ,
190.Ql \&%l ,
191.Ql \&%n ,
192.Ql \&%r ,
193.Ql \&%R ,
194.Ql \&%s .
195.Ql \&%t ,
196.Ql \&%T ,
197.Ql \&%u ,
198and
199.Ql \&%V
200conversion specifications are extensions.
201.Sh BUGS
202There is no conversion specification for the phase of the moon.
diff --git a/src/lib/libc/string/strftime.c b/src/lib/libc/string/strftime.c
deleted file mode 100644
index fffa9ecbb0..0000000000
--- a/src/lib/libc/string/strftime.c
+++ /dev/null
@@ -1,317 +0,0 @@
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)
35/*static char *sccsid = "from: @(#)strftime.c 5.11 (Berkeley) 2/24/91";*/
36static char *rcsid = "$Id: strftime.c,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */
38
39#include <sys/localedef.h>
40#include <locale.h>
41#include <string.h>
42#include <tzfile.h>
43#include <time.h>
44
45static size_t gsize;
46static char *pt;
47static int _add(), _conv(), _secs();
48static size_t _fmt();
49
50size_t
51strftime(s, maxsize, format, t)
52 char *s;
53 size_t maxsize;
54 const char *format;
55 const struct tm *t;
56{
57 tzset();
58
59 pt = s;
60 if ((gsize = maxsize) < 1)
61 return(0);
62 if (_fmt(format, t)) {
63 *pt = '\0';
64 return(maxsize - gsize);
65 }
66 return(0);
67}
68
69#define SUN_WEEK(t) (((t)->tm_yday + 7 - \
70 ((t)->tm_wday)) / 7)
71#define MON_WEEK(t) (((t)->tm_yday + 7 - \
72 ((t)->tm_wday ? (t)->tm_wday - 1 : 6)) / 7)
73static size_t
74_fmt(format, t)
75 register char *format;
76 struct tm *t;
77{
78 for (; *format; ++format) {
79 if (*format == '%') {
80 ++format;
81 if (*format == 'E') {
82 /* Alternate Era */
83 ++format;
84 } else if (*format == 'O') {
85 /* Alternate numeric symbols */
86 ++format;
87 }
88 switch(*format) {
89 case '\0':
90 --format;
91 break;
92 case 'A':
93 if (t->tm_wday < 0 || t->tm_wday > 6)
94 return(0);
95 if (!_add(_CurrentTimeLocale->day[t->tm_wday]))
96 return(0);
97 continue;
98 case 'a':
99 if (t->tm_wday < 0 || t->tm_wday > 6)
100 return(0);
101 if (!_add(_CurrentTimeLocale->abday[t->tm_wday]))
102 return(0);
103 continue;
104 case 'B':
105 if (t->tm_mon < 0 || t->tm_mon > 11)
106 return(0);
107 if (!_add(_CurrentTimeLocale->mon[t->tm_mon]))
108 return(0);
109 continue;
110 case 'b':
111 case 'h':
112 if (t->tm_mon < 0 || t->tm_mon > 11)
113 return(0);
114 if (!_add(_CurrentTimeLocale->abmon[t->tm_mon]))
115 return(0);
116 continue;
117 case 'C':
118 if (!_conv((t->tm_year + TM_YEAR_BASE) / 100,
119 2, '0'))
120 return(0);
121 continue;
122 case 'c':
123 if (!_fmt(_CurrentTimeLocale->d_t_fmt, t))
124 return(0);
125 continue;
126 case 'D':
127 if (!_fmt("%m/%d/%y", t))
128 return(0);
129 continue;
130 case 'd':
131 if (!_conv(t->tm_mday, 2, '0'))
132 return(0);
133 continue;
134 case 'e':
135 if (!_conv(t->tm_mday, 2, ' '))
136 return(0);
137 continue;
138 case 'H':
139 if (!_conv(t->tm_hour, 2, '0'))
140 return(0);
141 continue;
142 case 'I':
143 if (!_conv(t->tm_hour % 12 ?
144 t->tm_hour % 12 : 12, 2, '0'))
145 return(0);
146 continue;
147 case 'j':
148 if (!_conv(t->tm_yday + 1, 3, '0'))
149 return(0);
150 continue;
151 case 'k':
152 if (!_conv(t->tm_hour, 2, ' '))
153 return(0);
154 continue;
155 case 'l':
156 if (!_conv(t->tm_hour % 12 ?
157 t->tm_hour % 12: 12, 2, ' '))
158 return(0);
159 continue;
160 case 'M':
161 if (!_conv(t->tm_min, 2, '0'))
162 return(0);
163 continue;
164 case 'm':
165 if (!_conv(t->tm_mon + 1, 2, '0'))
166 return(0);
167 continue;
168 case 'n':
169 if (!_add("\n"))
170 return(0);
171 continue;
172 case 'p':
173 if (!_add(_CurrentTimeLocale->am_pm[t->tm_hour >= 12]))
174 return(0);
175 continue;
176 case 'R':
177 if (!_fmt("%H:%M", t))
178 return(0);
179 continue;
180 case 'r':
181 if (!_fmt(_CurrentTimeLocale->t_fmt_ampm, t))
182 return(0);
183 continue;
184 case 'S':
185 if (!_conv(t->tm_sec, 2, '0'))
186 return(0);
187 continue;
188 case 's':
189 if (!_secs(t))
190 return(0);
191 continue;
192 case 'T':
193 if (!_fmt("%H:%M:%S", t))
194 return(0);
195 continue;
196 case 't':
197 if (!_add("\t"))
198 return(0);
199 continue;
200 case 'U':
201 if (!_conv(SUN_WEEK(t), 2, '0'))
202 return(0);
203 continue;
204 case 'u':
205 if (!_conv(t->tm_wday ? t->tm_wday : 7, 2, '0'))
206 return(0);
207 continue;
208 case 'V':
209 {
210 /* ISO 8601 Week Of Year:
211 If the week (Monday - Sunday) containing
212 January 1 has four or more days in the new
213 year, then it is week 1; otherwise it is
214 week 53 of the previous year and the next
215 week is week one. */
216
217 int week = MON_WEEK(t);
218
219 if (((t->tm_yday + 7 - (t->tm_wday + 1)) % 7) >= 4) {
220 week++;
221 } else if (week == 0) {
222 week = 53;
223 }
224
225 if (!_conv(week, 2, '0'))
226 return(0);
227 continue;
228 }
229 case 'W':
230 if (!_conv(MON_WEEK(t), 2, '0'))
231 return(0);
232 continue;
233 case 'w':
234 if (!_conv(t->tm_wday, 1, '0'))
235 return(0);
236 continue;
237 case 'x':
238 if (!_fmt(_CurrentTimeLocale->d_fmt, t))
239 return(0);
240 continue;
241 case 'X':
242 if (!_fmt(_CurrentTimeLocale->t_fmt, t))
243 return(0);
244 continue;
245 case 'y':
246 if (!_conv((t->tm_year + TM_YEAR_BASE) % 100,
247 2, '0'))
248 return(0);
249 continue;
250 case 'Y':
251 if (!_conv((t->tm_year + TM_YEAR_BASE), 4, '0'))
252 return(0);
253 continue;
254 case 'Z':
255 if (t->tm_zone && !_add(t->tm_zone))
256 return(0);
257 continue;
258 case '%':
259 /*
260 * X311J/88-090 (4.12.3.5): if conversion char is
261 * undefined, behavior is undefined. Print out the
262 * character itself as printf(3) does.
263 */
264 default:
265 break;
266 }
267 }
268 if (!gsize--)
269 return(0);
270 *pt++ = *format;
271 }
272 return(gsize);
273}
274
275static
276_secs(t)
277 struct tm *t;
278{
279 static char buf[15];
280 register time_t s;
281 register char *p;
282 struct tm tmp;
283
284 /* Make a copy, mktime(3) modifies the tm struct. */
285 tmp = *t;
286 s = mktime(&tmp);
287 for (p = buf + sizeof(buf) - 2; s > 0 && p > buf; s /= 10)
288 *p-- = s % 10 + '0';
289 return(_add(++p));
290}
291
292static
293_conv(n, digits, pad)
294 int n, digits;
295 char pad;
296{
297 static char buf[10];
298 register char *p;
299
300 for (p = buf + sizeof(buf) - 2; n > 0 && p > buf; n /= 10, --digits)
301 *p-- = n % 10 + '0';
302 while (p > buf && digits-- > 0)
303 *p-- = pad;
304 return(_add(++p));
305}
306
307static
308_add(str)
309 register char *str;
310{
311 for (;; ++pt, --gsize) {
312 if (!gsize)
313 return(0);
314 if (!(*pt = *str++))
315 return(1);
316 }
317}
diff --git a/src/lib/libc/string/string.3 b/src/lib/libc/string/string.3
index aaf97e0321..89034ac24c 100644
--- a/src/lib/libc/string/string.3
+++ b/src/lib/libc/string/string.3
@@ -11,11 +11,7 @@
11.\" 2. Redistributions in binary form must reproduce the above copyright 11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the 12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution. 13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software 14.\" 3. Neither the name of the University nor the names of its contributors
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 15.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission. 16.\" without specific prior written permission.
21.\" 17.\"
@@ -31,38 +27,20 @@
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE. 28.\" SUCH DAMAGE.
33.\" 29.\"
34.\" from: @(#)string.3 6.9 (Berkeley) 4/19/91 30.\" $OpenBSD: string.3,v 1.10 2004/02/09 20:53:12 jmc Exp $
35.\" $Id: string.3,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $
36.\" 31.\"
37.Dd April 19, 1991 32.Dd April 19, 1991
38.Dt STRING 3 33.Dt STRING 3
39.Os BSD 4 34.Os
40.Sh NAME 35.Sh NAME
41.Nm strcat , 36.Nm string
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 strncpy ,
51.Nm strerror ,
52.Nm strlen ,
53.Nm strpbrk ,
54.Nm strsep,
55.Nm strspn ,
56.Nm strcspn ,
57.Nm strstr ,
58.Nm strtok ,
59.Nm index ,
60.Nm rindex
61.Nd string specific functions 37.Nd string specific functions
62.Sh SYNOPSIS 38.Sh SYNOPSIS
63.Fd #include <string.h> 39.Fd #include <string.h>
64.Ft char * 40.Ft char *
65.Fn strcat "char *s" "const char * append" 41.Fn strcat "char *s" "const char *append"
42.Ft char *
43.Fn strlcat "char *s" "const char *append" "size_t size"
66.Ft char * 44.Ft char *
67.Fn strncat "char *s" "const char *append" "size_t count" 45.Fn strncat "char *s" "const char *append" "size_t count"
68.Ft char * 46.Ft char *
@@ -80,6 +58,8 @@
80.Ft char * 58.Ft char *
81.Fn strcpy "char *dst" "const char *src" 59.Fn strcpy "char *dst" "const char *src"
82.Ft char * 60.Ft char *
61.Fn strlcpy "char *dst" "const char *src" "size_t size"
62.Ft char *
83.Fn strncpy "char *dst" "const char *src" "size_t count" 63.Fn strncpy "char *dst" "const char *src" "size_t count"
84.Ft char * 64.Ft char *
85.Fn strerror "int errno" 65.Fn strerror "int errno"
@@ -103,7 +83,7 @@
103.Fn rindex "const char *s" "int c" 83.Fn rindex "const char *s" "int c"
104.Sh DESCRIPTION 84.Sh DESCRIPTION
105The string functions 85The string functions
106functions manipulate strings terminated by a 86manipulate strings terminated by a
107null byte. 87null byte.
108.Pp 88.Pp
109See the specific manual pages for more information. 89See the specific manual pages for more information.
@@ -115,23 +95,25 @@ Except as noted in their specific manual pages,
115the string functions do not test the destination 95the string functions do not test the destination
116for size limitations. 96for size limitations.
117.Sh SEE ALSO 97.Sh SEE ALSO
98.Xr bstring 3 ,
118.Xr index 3 , 99.Xr index 3 ,
100.Xr rindex 3 ,
101.Xr strcasecmp 3 ,
119.Xr strcat 3 , 102.Xr strcat 3 ,
120.Xr strchr 3 , 103.Xr strchr 3 ,
121.Xr strrchr 3 ,
122.Xr strcmp 3 , 104.Xr strcmp 3 ,
123.Xr strcasecmp 3 ,
124.Xr strcpy 3 , 105.Xr strcpy 3 ,
106.Xr strcspn 3 ,
125.Xr strerror 3 , 107.Xr strerror 3 ,
108.Xr strlcat 3 ,
109.Xr strlcpy 3 ,
126.Xr strlen 3 , 110.Xr strlen 3 ,
127.Xr strpbrk 3 , 111.Xr strpbrk 3 ,
112.Xr strrchr 3 ,
128.Xr strsep 3 , 113.Xr strsep 3 ,
129.Xr strspn 3 , 114.Xr strspn 3 ,
130.Xr strcspn 3 ,
131.Xr strstr 3 , 115.Xr strstr 3 ,
132.Xr strtok 3 , 116.Xr strtok 3
133.Xr rindex 3
134.Xr bstring 3
135.Sh STANDARDS 117.Sh STANDARDS
136The 118The
137.Fn strcat , 119.Fn strcat ,
@@ -145,12 +127,10 @@ The
145.Fn strerror , 127.Fn strerror ,
146.Fn strlen , 128.Fn strlen ,
147.Fn strpbrk , 129.Fn strpbrk ,
148.Fn strsep ,
149.Fn strspn , 130.Fn strspn ,
150.Fn strcspn , 131.Fn strcspn ,
151.Fn strstr , 132.Fn strstr ,
152and 133and
153.Fn strtok 134.Fn strtok
154functions 135functions conform to
155conform to
156.St -ansiC . 136.St -ansiC .
diff --git a/src/lib/libc/string/strlcat.c b/src/lib/libc/string/strlcat.c
new file mode 100644
index 0000000000..2b6f1adbb4
--- /dev/null
+++ b/src/lib/libc/string/strlcat.c
@@ -0,0 +1,59 @@
1/* $OpenBSD: strlcat.c,v 1.11 2003/06/17 21:56:24 millert Exp $ */
2
3/*
4 * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
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 THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#if defined(LIBC_SCCS) && !defined(lint)
20static char *rcsid = "$OpenBSD: strlcat.c,v 1.11 2003/06/17 21:56:24 millert Exp $";
21#endif /* LIBC_SCCS and not lint */
22
23#include <sys/types.h>
24#include <string.h>
25
26/*
27 * Appends src to string dst of size siz (unlike strncat, siz is the
28 * full size of dst, not space left). At most siz-1 characters
29 * will be copied. Always NUL terminates (unless siz <= strlen(dst)).
30 * Returns strlen(src) + MIN(siz, strlen(initial dst)).
31 * If retval >= siz, truncation occurred.
32 */
33size_t
34strlcat(char *dst, const char *src, size_t siz)
35{
36 register char *d = dst;
37 register const char *s = src;
38 register size_t n = siz;
39 size_t dlen;
40
41 /* Find the end of dst and adjust bytes left but don't go past end */
42 while (n-- != 0 && *d != '\0')
43 d++;
44 dlen = d - dst;
45 n = siz - dlen;
46
47 if (n == 0)
48 return(dlen + strlen(s));
49 while (*s != '\0') {
50 if (n != 1) {
51 *d++ = *s;
52 n--;
53 }
54 s++;
55 }
56 *d = '\0';
57
58 return(dlen + (s - src)); /* count does not include NUL */
59}
diff --git a/src/lib/libc/string/strlcpy.3 b/src/lib/libc/string/strlcpy.3
new file mode 100644
index 0000000000..b392588879
--- /dev/null
+++ b/src/lib/libc/string/strlcpy.3
@@ -0,0 +1,179 @@
1.\" $OpenBSD: strlcpy.3,v 1.16 2003/06/17 21:56:24 millert Exp $
2.\"
3.\" Copyright (c) 1998, 2000 Todd C. Miller <Todd.Miller@courtesan.com>
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 THE AUTHOR DISCLAIMS ALL WARRANTIES
10.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16.\"
17.Dd June 22, 1998
18.Dt STRLCPY 3
19.Os
20.Sh NAME
21.Nm strlcpy ,
22.Nm strlcat
23.Nd size-bounded string copying and concatenation
24.Sh SYNOPSIS
25.Fd #include <string.h>
26.Ft size_t
27.Fn strlcpy "char *dst" "const char *src" "size_t size"
28.Ft size_t
29.Fn strlcat "char *dst" "const char *src" "size_t size"
30.Sh DESCRIPTION
31The
32.Fn strlcpy
33and
34.Fn strlcat
35functions copy and concatenate strings respectively.
36They are designed
37to be safer, more consistent, and less error prone replacements for
38.Xr strncpy 3
39and
40.Xr strncat 3 .
41Unlike those functions,
42.Fn strlcpy
43and
44.Fn strlcat
45take the full size of the buffer (not just the length) and guarantee to
46NUL-terminate the result (as long as
47.Fa size
48is larger than 0 or, in the case of
49.Fn strlcat ,
50as long as there is at least one byte free in
51.Fa dst ) .
52Note that you should include a byte for the NUL in
53.Fa size .
54Also note that
55.Fn strlcpy
56and
57.Fn strlcat
58only operate on true
59.Dq C
60strings.
61This means that for
62.Fn strlcpy
63.Fa src
64must be NUL-terminated and for
65.Fn strlcat
66both
67.Fa src
68and
69.Fa dst
70must be NUL-terminated.
71.Pp
72The
73.Fn strlcpy
74function copies up to
75.Fa size
76- 1 characters from the NUL-terminated string
77.Fa src
78to
79.Fa dst ,
80NUL-terminating the result.
81.Pp
82The
83.Fn strlcat
84function appends the NUL-terminated string
85.Fa src
86to the end of
87.Fa dst .
88It will append at most
89.Fa size
90- strlen(dst) - 1 bytes, NUL-terminating the result.
91.Sh RETURN VALUES
92The
93.Fn strlcpy
94and
95.Fn strlcat
96functions return the total length of the string they tried to create.
97For
98.Fn strlcpy
99that means the length of
100.Fa src .
101For
102.Fn strlcat
103that means the initial length of
104.Fa dst
105plus
106the length of
107.Fa src .
108While this may seem somewhat confusing it was done to make
109truncation detection simple.
110.Pp
111Note however, that if
112.Fn strlcat
113traverses
114.Fa size
115characters without finding a NUL, the length of the string is considered
116to be
117.Fa size
118and the destination string will not be NUL-terminated (since there was
119no space for the NUL).
120This keeps
121.Fn strlcat
122from running off the end of a string.
123In practice this should not happen (as it means that either
124.Fa size
125is incorrect or that
126.Fa dst
127is not a proper
128.Dq C
129string).
130The check exists to prevent potential security problems in incorrect code.
131.Sh EXAMPLES
132The following code fragment illustrates the simple case:
133.Bd -literal -offset indent
134char *s, *p, buf[BUFSIZ];
135
136\&...
137
138(void)strlcpy(buf, s, sizeof(buf));
139(void)strlcat(buf, p, sizeof(buf));
140.Ed
141.Pp
142To detect truncation, perhaps while building a pathname, something
143like the following might be used:
144.Bd -literal -offset indent
145char *dir, *file, pname[MAXPATHLEN];
146
147\&...
148
149if (strlcpy(pname, dir, sizeof(pname)) >= sizeof(pname))
150 goto toolong;
151if (strlcat(pname, file, sizeof(pname)) >= sizeof(pname))
152 goto toolong;
153.Ed
154.Pp
155Since we know how many characters we copied the first time, we can
156speed things up a bit by using a copy instead of an append:
157.Bd -literal -offset indent
158char *dir, *file, pname[MAXPATHLEN];
159size_t n;
160
161\&...
162
163n = strlcpy(pname, dir, sizeof(pname));
164if (n >= sizeof(pname))
165 goto toolong;
166if (strlcpy(pname + n, file, sizeof(pname) - n) >= sizeof(pname) - n)
167 goto toolong;
168.Ed
169.Pp
170However, one may question the validity of such optimizations, as they
171defeat the whole purpose of
172.Fn strlcpy
173and
174.Fn strlcat .
175As a matter of fact, the first version of this manual page got it wrong.
176.Sh SEE ALSO
177.Xr snprintf 3 ,
178.Xr strncat 3 ,
179.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..82cbfac016
--- /dev/null
+++ b/src/lib/libc/string/strlcpy.c
@@ -0,0 +1,55 @@
1/* $OpenBSD: strlcpy.c,v 1.8 2003/06/17 21:56:24 millert Exp $ */
2
3/*
4 * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
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 THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#if defined(LIBC_SCCS) && !defined(lint)
20static char *rcsid = "$OpenBSD: strlcpy.c,v 1.8 2003/06/17 21:56:24 millert Exp $";
21#endif /* LIBC_SCCS and not lint */
22
23#include <sys/types.h>
24#include <string.h>
25
26/*
27 * Copy src to string dst of size siz. At most siz-1 characters
28 * will be copied. Always NUL terminates (unless siz == 0).
29 * Returns strlen(src); if retval >= siz, truncation occurred.
30 */
31size_t
32strlcpy(char *dst, const char *src, size_t siz)
33{
34 register char *d = dst;
35 register const char *s = src;
36 register size_t n = siz;
37
38 /* Copy as many bytes as will fit */
39 if (n != 0 && --n != 0) {
40 do {
41 if ((*d++ = *s++) == 0)
42 break;
43 } while (--n != 0);
44 }
45
46 /* Not enough room in dst, add NUL and traverse rest of src */
47 if (n == 0) {
48 if (siz != 0)
49 *d = '\0'; /* NUL-terminate dst */
50 while (*s++)
51 ;
52 }
53
54 return(s - src - 1); /* count does not include NUL */
55}
diff --git a/src/lib/libc/string/strlen.3 b/src/lib/libc/string/strlen.3
index f4aff363ee..32bbc88542 100644
--- a/src/lib/libc/string/strlen.3
+++ b/src/lib/libc/string/strlen.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,15 +29,14 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)strlen.3 5.4 (Berkeley) 6/29/91 32.\" $OpenBSD: strlen.3,v 1.5 2003/06/02 20:18:38 millert Exp $
37.\" $Id: strlen.3,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd June 29, 1991
40.Dt STRLEN 3 35.Dt STRLEN 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
43.Nm strlen 38.Nm strlen
44.Nd find length of string 39.Nd find length of a string
45.Sh SYNOPSIS 40.Sh SYNOPSIS
46.Fd #include <string.h> 41.Fd #include <string.h>
47.Ft size_t 42.Ft size_t
@@ -49,23 +44,18 @@
49.Sh DESCRIPTION 44.Sh DESCRIPTION
50The 45The
51.Fn strlen 46.Fn strlen
52function 47function computes the length of the string
53computes the length of the string
54.Fa s . 48.Fa s .
55.Sh RETURN VALUES 49.Sh RETURN VALUES
56The 50The
57.Fn strlen 51.Fn strlen
58function 52function returns the number of characters that precede the terminating
59returns 53.Tn NUL
60the number of characters that precede the
61terminating
62.Dv NUL
63character. 54character.
64.Sh SEE ALSO 55.Sh SEE ALSO
65.Xr string 3 56.Xr string 3
66.Sh STANDARDS 57.Sh STANDARDS
67The 58The
68.Fn strlen 59.Fn strlen
69function 60function conforms to
70conforms to
71.St -ansiC . 61.St -ansiC .
diff --git a/src/lib/libc/string/strlen.c b/src/lib/libc/string/strlen.c
index d23aadafc0..298a9966a3 100644
--- a/src/lib/libc/string/strlen.c
+++ b/src/lib/libc/string/strlen.c
@@ -1,6 +1,8 @@
1/* $OpenBSD: strlen.c,v 1.6 2003/06/11 21:08:16 deraadt Exp $ */
2
1/*- 3/*-
2 * Copyright (c) 1990 The Regents of the University of California. 4 * Copyright (c) 1990, 1993
3 * All rights reserved. 5 * The Regents of the University of California. All rights reserved.
4 * 6 *
5 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
@@ -10,11 +12,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 15 * 3. Neither the name of the University nor the names of its contributors
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 16 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 17 * without specific prior written permission.
20 * 18 *
@@ -32,19 +30,22 @@
32 */ 30 */
33 31
34#if defined(LIBC_SCCS) && !defined(lint) 32#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)strlen.c 5.5 (Berkeley) 1/26/91";*/ 33static char *rcsid = "$OpenBSD: strlen.c,v 1.6 2003/06/11 21:08:16 deraadt Exp $";
36static char *rcsid = "$Id: strlen.c,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 34#endif /* LIBC_SCCS and not lint */
38 35
36#if !defined(_KERNEL) && !defined(_STANDALONE)
39#include <string.h> 37#include <string.h>
38#else
39#include <lib/libkern/libkern.h>
40#endif
40 41
41size_t 42size_t
42strlen(str) 43strlen(const char *str)
43 const char *str;
44{ 44{
45 register const char *s; 45 const char *s;
46 46
47 for (s = str; *s; ++s); 47 for (s = str; *s; ++s)
48 return(s - str); 48 ;
49 return (s - str);
49} 50}
50 51
diff --git a/src/lib/libc/string/strmode.3 b/src/lib/libc/string/strmode.3
index 1907e7ab03..bc45c4ce1f 100644
--- a/src/lib/libc/string/strmode.3
+++ b/src/lib/libc/string/strmode.3
@@ -1,5 +1,7 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California. 1.\" $OpenBSD: strmode.3,v 1.11 2003/09/02 18:24:21 jmc Exp $
2.\" All rights reserved. 2.\"
3.\" Copyright (c) 1990, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
3.\" 5.\"
4.\" Redistribution and use in source and binary forms, with or without 6.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions 7.\" modification, are permitted provided that the following conditions
@@ -9,11 +11,7 @@
9.\" 2. Redistributions in binary form must reproduce the above copyright 11.\" 2. Redistributions in binary form must reproduce the above copyright
10.\" notice, this list of conditions and the following disclaimer in the 12.\" notice, this list of conditions and the following disclaimer in the
11.\" documentation and/or other materials provided with the distribution. 13.\" documentation and/or other materials provided with the distribution.
12.\" 3. All advertising materials mentioning features or use of this software 14.\" 3. Neither the name of the University nor the names of its contributors
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 15.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission. 16.\" without specific prior written permission.
19.\" 17.\"
@@ -29,10 +27,9 @@
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE. 28.\" SUCH DAMAGE.
31.\" 29.\"
32.\" from: @(#)strmode.3 5.4 (Berkeley) 7/31/91 30.\" @(#)strmode.3 8.3 (Berkeley) 7/28/94
33.\" $Id: strmode.3,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $
34.\" 31.\"
35.Dd July 31, 1991 32.Dd July 28, 1994
36.Dt STRMODE 3 33.Dt STRMODE 3
37.Os 34.Os
38.Sh NAME 35.Sh NAME
@@ -45,15 +42,13 @@
45.Sh DESCRIPTION 42.Sh DESCRIPTION
46The 43The
47.Fn strmode 44.Fn strmode
48function 45function converts a file
49converts a file
50.Fa mode 46.Fa mode
51(the type and permission information associated with an inode, see 47(the type and permission information associated with an inode, see
52.Xr stat 2 ) 48.Xr stat 2 )
53into a symbolic string which is stored in the location referenced by 49into a symbolic string which is stored in the location referenced by
54.Fa bp . 50.Fa bp .
55This stored string is eleven characters in length plus a trailing 51This stored string is eleven characters in length plus a trailing null byte.
56.Dv NULL .
57.Pp 52.Pp
58The first character is the inode type, and will be one of the following: 53The first character is the inode type, and will be one of the following:
59.Pp 54.Pp
@@ -69,10 +64,12 @@ directory
69.It l 64.It l
70symbolic link 65symbolic link
71.It p 66.It p
72fifo 67FIFO
73.It s 68.It s
74socket 69socket
75.It ? 70.It w
71whiteout
72.It \&?
76unknown inode type 73unknown inode type
77.El 74.El
78.Pp 75.Pp
@@ -80,46 +77,58 @@ The next nine characters encode three sets of permissions, in three
80characters each. 77characters each.
81The first three characters are the permissions for the owner of the 78The first three characters are the permissions for the owner of the
82file, the second three for the group the file belongs to, and the 79file, the second three for the group the file belongs to, and the
83third for the ``other'', or default, set of users. 80third for the
81.Dq other ,
82or default, set of users.
84.Pp 83.Pp
85Permission checking is done as specifically as possible. 84Permission checking is done as specifically as possible.
86If read permission is denied to the owner of a file in the first set 85If read permission is denied to the owner of a file in the first set
87of permissions, the owner of the file will not be able to read the file. 86of permissions, the owner of the file will not be able to read the file.
88This is true even if the owner is in the file's group and the group 87This is true even if the owner is in the file's group and the group
89permissions allow reading or the ``other'' permissions allow reading. 88permissions allow reading or the
89.Dq other
90permissions allow reading.
90.Pp 91.Pp
91If the first character of the three character set is an ``r'', the file is 92If the first character of the three character set is an
92readable for that set of users; if a dash ``\-'', it is not readable. 93.Sq r ,
94the file is readable for that set of users; if a dash
95.Pq Ql - ,
96it is not readable.
93.Pp 97.Pp
94If the second character of the three character set is a ``w'', the file is 98If the second character of the three character set is a
95writable for that set of users; if a dash ``\-'', it is not writable. 99.Sq w ,
100the file is writable for that set of users; if a dash
101.Pq Ql - ,
102it is not writable.
96.Pp 103.Pp
97The third character is the first of the following characters that apply: 104The third character is the first of the following characters that apply:
98.Bl -tag -width xxxx 105.Bl -tag -width xxxx
99.It S 106.It S
100If the character is part of the owner permissions and the file is not 107If the character is part of the owner permissions and the file is not
101executable or the directory is not searchable, by the owner, and the 108executable or the directory is not searchable by the owner, and the
102set-user-id bit is set. 109set-user-ID bit is set.
103.It S 110.It S
104If the character is part of the group permissions and the file is not 111If the character is part of the group permissions and the file is not
105executable or the directory is not searchable, by the group, and the 112executable or the directory is not searchable by the group, and the
106set-group-id bit is set. 113set-group-ID bit is set.
107.It T 114.It T
108If the character is part of the other permissions and the file is not 115If the character is part of the other permissions and the file is not
109executable or the directory is not searchable, by others, and the ``sticky'' 116executable or the directory is not searchable by others, and the
117.Dq sticky
110.Pq Dv S_ISVTX 118.Pq Dv S_ISVTX
111bit is set. 119bit is set.
112.It s 120.It s
113If the character is part of the owner permissions and the file is 121If the character is part of the owner permissions and the file is
114executable or the directory searchable, by the owner, and the set-user-id 122executable or the directory searchable by the owner, and the set-user-ID
115bit is set. 123bit is set.
116.It s 124.It s
117If the character is part of the group permissions and the file is 125If the character is part of the group permissions and the file is
118executable or the directory searchable, by the group, and the set-group-id 126executable or the directory searchable by the group, and the set-group-ID
119bit is set. 127bit is set.
120.It t 128.It t
121If the character is part of the other permissions and the file is 129If the character is part of the other permissions and the file is
122executable or the directory searchable, by others, and the ``sticky'' 130executable or the directory searchable by others, and the
131.Dq sticky
123.Pq Dv S_ISVTX 132.Pq Dv S_ISVTX
124bit is set. 133bit is set.
125.It x 134.It x
@@ -128,14 +137,15 @@ The file is executable or the directory is searchable.
128None of the above apply. 137None of the above apply.
129.El 138.El
130.Pp 139.Pp
131The last character is a plus sign ``+'' if any there are any alternate 140The last character is a plus sign
141.Pq Ql +
142if there are any alternate
132or additional access control methods associated with the inode, otherwise 143or additional access control methods associated with the inode, otherwise
133it will be a space. 144it will be a space.
134.Sh RETURN VALUES 145.Sh RETURN VALUES
135The 146The
136.Fn strmode 147.Fn strmode
137function 148function always returns 0.
138always returns 0.
139.Sh SEE ALSO 149.Sh SEE ALSO
140.Xr chmod 1 , 150.Xr chmod 1 ,
141.Xr find 1 , 151.Xr find 1 ,
@@ -145,5 +155,5 @@ always returns 0.
145.Sh HISTORY 155.Sh HISTORY
146The 156The
147.Fn strmode 157.Fn strmode
148function 158function first appeared in
149.Ud . 159.Bx 4.4 .
diff --git a/src/lib/libc/string/strmode.c b/src/lib/libc/string/strmode.c
index 441fc76e90..bd78403cb2 100644
--- a/src/lib/libc/string/strmode.c
+++ b/src/lib/libc/string/strmode.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,18 +28,17 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)strmode.c 5.3 (Berkeley) 5/18/90";*/ 31static char *rcsid = "$OpenBSD: strmode.c,v 1.5 2003/06/11 21:08:16 deraadt Exp $";
36static char *rcsid = "$Id: strmode.c,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
39#include <sys/types.h> 34#include <sys/types.h>
40#include <sys/stat.h> 35#include <sys/stat.h>
41#include <string.h> 36#include <string.h>
42 37
38/* XXX mode should be mode_t */
39
43void 40void
44strmode(mode, p) 41strmode(int mode, char *p)
45 register mode_t mode;
46 register char *p;
47{ 42{
48 /* print type */ 43 /* print type */
49 switch (mode & S_IFMT) { 44 switch (mode & S_IFMT) {
@@ -70,6 +65,11 @@ strmode(mode, p)
70 *p++ = 'p'; 65 *p++ = 'p';
71 break; 66 break;
72#endif 67#endif
68#ifdef S_IFWHT
69 case S_IFWHT: /* whiteout */
70 *p++ = 'w';
71 break;
72#endif
73 default: /* unknown */ 73 default: /* unknown */
74 *p++ = '?'; 74 *p++ = '?';
75 break; 75 break;
diff --git a/src/lib/libc/string/strncat.c b/src/lib/libc/string/strncat.c
index 3d96452af4..05d35e0900 100644
--- a/src/lib/libc/string/strncat.c
+++ b/src/lib/libc/string/strncat.c
@@ -13,11 +13,7 @@
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software 16 * 3. Neither the name of the University nor the names of its contributors
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 17 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission. 18 * without specific prior written permission.
23 * 19 *
@@ -35,8 +31,7 @@
35 */ 31 */
36 32
37#if defined(LIBC_SCCS) && !defined(lint) 33#if defined(LIBC_SCCS) && !defined(lint)
38/*static char *sccsid = "from: @(#)strncat.c 5.6 (Berkeley) 1/26/91";*/ 34static char *rcsid = "$OpenBSD: strncat.c,v 1.4 2003/06/11 21:08:16 deraadt Exp $";
39static char *rcsid = "$Id: strncat.c,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */ 35#endif /* LIBC_SCCS and not lint */
41 36
42#include <string.h> 37#include <string.h>
@@ -46,14 +41,11 @@ static char *rcsid = "$Id: strncat.c,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $
46 * are written at dst (at most n+1 bytes being appended). Return dst. 41 * are written at dst (at most n+1 bytes being appended). Return dst.
47 */ 42 */
48char * 43char *
49strncat(dst, src, n) 44strncat(char *dst, const char *src, size_t n)
50 char *dst;
51 const char *src;
52 register size_t n;
53{ 45{
54 if (n != 0) { 46 if (n != 0) {
55 register char *d = dst; 47 char *d = dst;
56 register const char *s = src; 48 const char *s = src;
57 49
58 while (*d != 0) 50 while (*d != 0)
59 d++; 51 d++;
diff --git a/src/lib/libc/string/strncmp.c b/src/lib/libc/string/strncmp.c
index 0638d4dcf2..82420e215e 100644
--- a/src/lib/libc/string/strncmp.c
+++ b/src/lib/libc/string/strncmp.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,16 +28,17 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)strncmp.c 5.6 (Berkeley) 1/26/91";*/ 31static char *rcsid = "$OpenBSD: strncmp.c,v 1.5 2003/06/11 21:08:16 deraadt Exp $";
36static char *rcsid = "$Id: strncmp.c,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
34#ifndef _KERNEL
39#include <string.h> 35#include <string.h>
36#else
37#include <lib/libkern/libkern.h>
38#endif
40 39
41int 40int
42strncmp(s1, s2, n) 41strncmp(const char *s1, const char *s2, size_t n)
43 register const char *s1, *s2;
44 register size_t n;
45{ 42{
46 43
47 if (n == 0) 44 if (n == 0)
diff --git a/src/lib/libc/string/strncpy.c b/src/lib/libc/string/strncpy.c
index 5215311b75..00493f4f7f 100644
--- a/src/lib/libc/string/strncpy.c
+++ b/src/lib/libc/string/strncpy.c
@@ -13,11 +13,7 @@
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software 16 * 3. Neither the name of the University nor the names of its contributors
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 17 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission. 18 * without specific prior written permission.
23 * 19 *
@@ -35,8 +31,7 @@
35 */ 31 */
36 32
37#if defined(LIBC_SCCS) && !defined(lint) 33#if defined(LIBC_SCCS) && !defined(lint)
38/*static char *sccsid = "from: @(#)strncpy.c 5.6 (Berkeley) 1/26/91";*/ 34static char *rcsid = "$OpenBSD: strncpy.c,v 1.4 2003/06/11 21:08:16 deraadt Exp $";
39static char *rcsid = "$Id: strncpy.c,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */ 35#endif /* LIBC_SCCS and not lint */
41 36
42#include <string.h> 37#include <string.h>
@@ -46,14 +41,11 @@ static char *rcsid = "$Id: strncpy.c,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $
46 * Return dst. 41 * Return dst.
47 */ 42 */
48char * 43char *
49strncpy(dst, src, n) 44strncpy(char *dst, const char *src, size_t n)
50 char *dst;
51 const char *src;
52 register size_t n;
53{ 45{
54 if (n != 0) { 46 if (n != 0) {
55 register char *d = dst; 47 char *d = dst;
56 register const char *s = src; 48 const char *s = src;
57 49
58 do { 50 do {
59 if ((*d++ = *s++) == 0) { 51 if ((*d++ = *s++) == 0) {
diff --git a/src/lib/libc/string/strpbrk.3 b/src/lib/libc/string/strpbrk.3
index 8578546c05..7e54f9de54 100644
--- a/src/lib/libc/string/strpbrk.3
+++ b/src/lib/libc/string/strpbrk.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,8 +29,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)strpbrk.3 5.4 (Berkeley) 6/29/91 32.\" $OpenBSD: strpbrk.3,v 1.6 2003/06/02 20:18:38 millert Exp $
37.\" $Id: strpbrk.3,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd June 29, 1991
40.Dt STRPBRK 3 35.Dt STRPBRK 3
@@ -49,8 +44,7 @@
49.Sh DESCRIPTION 44.Sh DESCRIPTION
50The 45The
51.Fn strpbrk 46.Fn strpbrk
52function 47function locates in the null-terminated string
53locates in the null-terminated string
54.Fa s 48.Fa s
55the first occurrence of any character in the string 49the first occurrence of any character in the string
56.Fa charset 50.Fa charset
@@ -58,13 +52,12 @@ and returns a pointer to this character.
58If no characters from 52If no characters from
59.Fa charset 53.Fa charset
60occur anywhere in 54occur anywhere in
61.Fa s 55.Fa s ,
62.Fn strpbrk 56.Fn strpbrk
63returns NULL. 57returns
58.Dv NULL .
64.Sh SEE ALSO 59.Sh SEE ALSO
65.Xr index 3 ,
66.Xr memchr 3 , 60.Xr memchr 3 ,
67.Xr rindex 3 ,
68.Xr strchr 3 , 61.Xr strchr 3 ,
69.Xr strcspn 3 , 62.Xr strcspn 3 ,
70.Xr strrchr 3 , 63.Xr strrchr 3 ,
@@ -75,6 +68,5 @@ returns NULL.
75.Sh STANDARDS 68.Sh STANDARDS
76The 69The
77.Fn strpbrk 70.Fn strpbrk
78function 71function conforms to
79conforms to
80.St -ansiC . 72.St -ansiC .
diff --git a/src/lib/libc/string/strpbrk.c b/src/lib/libc/string/strpbrk.c
index f1d542a525..024c42bdc3 100644
--- a/src/lib/libc/string/strpbrk.c
+++ b/src/lib/libc/string/strpbrk.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,8 +28,7 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)strpbrk.c 5.8 (Berkeley) 1/26/91";*/ 31static char *rcsid = "$OpenBSD: strpbrk.c,v 1.4 2003/06/11 21:08:16 deraadt Exp $";
36static char *rcsid = "$Id: strpbrk.c,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
39#include <string.h> 34#include <string.h>
@@ -42,11 +37,10 @@ static char *rcsid = "$Id: strpbrk.c,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $
42 * Find the first occurrence in s1 of a character in s2 (excluding NUL). 37 * Find the first occurrence in s1 of a character in s2 (excluding NUL).
43 */ 38 */
44char * 39char *
45strpbrk(s1, s2) 40strpbrk(const char *s1, const char *s2)
46 register const char *s1, *s2;
47{ 41{
48 register const char *scanp; 42 const char *scanp;
49 register int c, sc; 43 int c, sc;
50 44
51 while ((c = *s1++) != 0) { 45 while ((c = *s1++) != 0) {
52 for (scanp = s2; (sc = *scanp++) != 0;) 46 for (scanp = s2; (sc = *scanp++) != 0;)
diff --git a/src/lib/libc/string/strrchr.3 b/src/lib/libc/string/strrchr.3
index 1d98cbff24..d7e0eeff85 100644
--- a/src/lib/libc/string/strrchr.3
+++ b/src/lib/libc/string/strrchr.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,28 +29,31 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)strrchr.3 5.3 (Berkeley) 6/29/91 32.\" $OpenBSD: strrchr.3,v 1.7 2003/06/02 20:18:38 millert Exp $
37.\" $Id: strrchr.3,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd June 29, 1991
40.Dt STRRCHR 3 35.Dt STRRCHR 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
43.Nm strrchr 38.Nm strrchr ,
44.Nd locate character in string 39.Nm rindex
40.Nd locate last occurrence of a character in a string
45.Sh SYNOPSIS 41.Sh SYNOPSIS
46.Fd #include <string.h> 42.Fd #include <string.h>
47.Ft char * 43.Ft char *
48.Fn strrchr "const char *s" "int c" 44.Fn strrchr "const char *s" "int c"
45.Ft char *
46.Fn rindex "const char *s" "int c"
49.Sh DESCRIPTION 47.Sh DESCRIPTION
50The 48The
51.Fn strrchr 49.Fn strrchr
52function 50function locates the last occurrence of the character
53locates the last occurrence of
54.Fa c 51.Fa c
55(converted to a char)
56in the string 52in the string
57.Fa s . 53.Fa s .
54The terminating
55.Tn NUL
56character is considered part of the string.
58If 57If
59.Fa c 58.Fa c
60is 59is
@@ -62,20 +61,31 @@ is
62.Fn strrchr 61.Fn strrchr
63locates the terminating 62locates the terminating
64.Ql \e0 . 63.Ql \e0 .
64.Pp
65The
66.Fn rindex
67function is an old synonym for
68.Fn strrchr .
65.Sh RETURN VALUES 69.Sh RETURN VALUES
66The 70The
67.Fn strrchr 71.Fn strrchr
68function 72function returns a pointer to the located character or
69returns a pointer to the character, 73.Dv NULL
70or a null 74if the character does not appear in the string.
71pointer if 75.Sh EXAMPLES
72.Fa c 76After the following call to
73does not occur anywhere in 77.Fn strrchr ,
74.Fa s . 78.Va p
79will point to the string
80.Qq obar :
81.Bd -literal -offset indent
82char *p;
83char *s = "foobar";
84
85p = strrchr(s, 'o');
86.Ed
75.Sh SEE ALSO 87.Sh SEE ALSO
76.Xr index 3 ,
77.Xr memchr 3 , 88.Xr memchr 3 ,
78.Xr rindex 3 ,
79.Xr strchr 3 , 89.Xr strchr 3 ,
80.Xr strcspn 3 , 90.Xr strcspn 3 ,
81.Xr strpbrk 3 , 91.Xr strpbrk 3 ,
@@ -86,6 +96,9 @@ does not occur anywhere in
86.Sh STANDARDS 96.Sh STANDARDS
87The 97The
88.Fn strrchr 98.Fn strrchr
89function 99function conforms to
90conforms to
91.St -ansiC . 100.St -ansiC .
101.Pp
102The
103.Fn rindex
104function 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
index 21aa7376f2..ddcc22916a 100644
--- a/src/lib/libc/string/strsep.3
+++ b/src/lib/libc/string/strsep.3
@@ -1,8 +1,11 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California. 1.\" $OpenBSD: strsep.3,v 1.11 2003/06/02 20:18:38 millert Exp $
2.\" All rights reserved. 2.\"
3.\" Copyright (c) 1990, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
3.\" 5.\"
4.\" This code is derived from software contributed to Berkeley by 6.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek. 7.\" Chris Torek.
8.\"
6.\" Redistribution and use in source and binary forms, with or without 9.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions 10.\" modification, are permitted provided that the following conditions
8.\" are met: 11.\" are met:
@@ -11,11 +14,7 @@
11.\" 2. Redistributions in binary form must reproduce the above copyright 14.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the 15.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution. 16.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software 17.\" 3. Neither the name of the University nor the names of its contributors
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 18.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission. 19.\" without specific prior written permission.
21.\" 20.\"
@@ -31,10 +30,9 @@
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE. 31.\" SUCH DAMAGE.
33.\" 32.\"
34.\" from: @(#)strsep.3 5.3 (Berkeley) 4/19/91 33.\" @(#)strsep.3 8.1 (Berkeley) 6/9/93
35.\" $Id: strsep.3,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $
36.\" 34.\"
37.Dd April 19, 1991 35.Dd June 9, 1993
38.Dt STRSEP 3 36.Dt STRSEP 3
39.Os 37.Os
40.Sh NAME 38.Sh NAME
@@ -43,27 +41,37 @@
43.Sh SYNOPSIS 41.Sh SYNOPSIS
44.Fd #include <string.h> 42.Fd #include <string.h>
45.Ft char * 43.Ft char *
46.Fn strsep "char **stringp" "char *delim" 44.Fn strsep "char **stringp" "const char *delim"
47.Sh DESCRIPTION 45.Sh DESCRIPTION
48The 46The
49.Fn strsep 47.Fn strsep
50locates in the null-terminated string at 48function locates, in the string referenced by
51.Fa *stringp
52the first occurrence of any character in
53.Fa delim
54and replaces this with a
55.Ql \e0 ,
56records the location of the immediate following character in
57.Fa *stringp , 49.Fa *stringp ,
58then returns the original value of 50the first occurrence of any character in the string
51.Fa delim
52(or the terminating
53.Ql \e0
54character) and replaces it with a
55.Ql \e0 .
56The location of the next character after the delimiter character
57(or
58.Dv NULL ,
59if the end of the string was reached) is stored in
59.Fa *stringp . 60.Fa *stringp .
60If no delimiter characters are found, 61The original value of
61.Fn strsep
62sets
63.Fa *stringp 62.Fa *stringp
63is returned.
64.Pp
65An
66.Dq empty
67field, i.e., one caused by two adjacent delimiter characters,
68can be detected by comparing the location referenced by the pointer returned
69by
70.Fn strsep
64to 71to
65.Dv NULL ; 72.Ql \e0 .
66if 73.Pp
74If
67.Fa *stringp 75.Fa *stringp
68is initially 76is initially
69.Dv NULL , 77.Dv NULL ,
@@ -73,20 +81,32 @@ returns
73.Sh EXAMPLES 81.Sh EXAMPLES
74The following uses 82The following uses
75.Fn strsep 83.Fn strsep
76to parse strings containing runs of white space, 84to parse a string, containing tokens delimited by whitespace, into an
77making up an argument vector: 85argument vector:
78.Bd -literal -offset indent 86.Bd -literal -offset indent
79char inputstring[100]; 87char **ap, *argv[10], *inputstring;
80char **argv[51], **ap = argv, *p, *val; 88
81/* set up inputstring */ 89for (ap = argv; ap < &argv[9] &&
82for (p = inputstring; p != NULL; ) { 90 (*ap = strsep(&inputstring, " \et")) != NULL;) {
83 while ((val = strsep(&p, " \et")) != NULL && *val == '\e0'); 91 if (**ap != '\e0')
84 *ap++ = val; 92 ap++;
85} 93}
86*ap = 0; 94*ap = NULL;
87.Ed 95.Ed
88.Sh HISTORY 96.Sh HISTORY
89The 97The
90.Fn strsep 98.Fn strsep
91function is 99function is intended as a replacement for the
92.Ud . 100.Fn strtok
101function.
102While the
103.Fn strtok
104function should be preferred for portability reasons (it conforms to
105.St -ansiC )
106it is unable to handle empty fields, i.e., detect fields delimited by
107two adjacent delimiter characters, or to be used for more than a single
108string at a time.
109The
110.Fn strsep
111function first appeared in
112.Bx 4.4 .
diff --git a/src/lib/libc/string/strsep.c b/src/lib/libc/string/strsep.c
index 69be7fe046..337d78e466 100644
--- a/src/lib/libc/string/strsep.c
+++ b/src/lib/libc/string/strsep.c
@@ -1,6 +1,8 @@
1/* $OpenBSD: strsep.c,v 1.5 2003/06/11 21:08:16 deraadt Exp $ */
2
1/*- 3/*-
2 * Copyright (c) 1990 The Regents of the University of California. 4 * Copyright (c) 1990, 1993
3 * All rights reserved. 5 * The Regents of the University of California. All rights reserved.
4 * 6 *
5 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
@@ -10,11 +12,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 15 * 3. Neither the name of the University nor the names of its contributors
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 16 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 17 * without specific prior written permission.
20 * 18 *
@@ -31,15 +29,19 @@
31 * SUCH DAMAGE. 29 * SUCH DAMAGE.
32 */ 30 */
33 31
32#include <string.h>
33#include <stdio.h>
34
34#if defined(LIBC_SCCS) && !defined(lint) 35#if defined(LIBC_SCCS) && !defined(lint)
35/*static const char sccsid[] = "from: @(#)strsep.c 5.4 (Berkeley) 1/26/91";*/ 36#if 0
36static char *rcsid = "$Id: strsep.c,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $"; 37static char sccsid[] = "@(#)strsep.c 8.1 (Berkeley) 6/4/93";
38#else
39static char *rcsid = "$OpenBSD: strsep.c,v 1.5 2003/06/11 21:08:16 deraadt Exp $";
40#endif
37#endif /* LIBC_SCCS and not lint */ 41#endif /* LIBC_SCCS and not lint */
38 42
39#include <string.h>
40
41/* 43/*
42 * Get next token from string *stringp, where tokens are nonempty 44 * Get next token from string *stringp, where tokens are possibly-empty
43 * strings separated by characters from delim. 45 * strings separated by characters from delim.
44 * 46 *
45 * Writes NULs into the string at *stringp to end tokens. 47 * Writes NULs into the string at *stringp to end tokens.
@@ -47,16 +49,14 @@ static char *rcsid = "$Id: strsep.c,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $"
47 * On return, *stringp points past the last NUL written (if there might 49 * On return, *stringp points past the last NUL written (if there might
48 * be further tokens), or is NULL (if there are definitely no more tokens). 50 * be further tokens), or is NULL (if there are definitely no more tokens).
49 * 51 *
50 * If *stringp is NULL, strtoken returns NULL. 52 * If *stringp is NULL, strsep returns NULL.
51 */ 53 */
52char * 54char *
53strsep(stringp, delim) 55strsep(char **stringp, const char *delim)
54 register char **stringp;
55 register const char *delim;
56{ 56{
57 register char *s; 57 char *s;
58 register const char *spanp; 58 const char *spanp;
59 register int c, sc; 59 int c, sc;
60 char *tok; 60 char *tok;
61 61
62 if ((s = *stringp) == NULL) 62 if ((s = *stringp) == NULL)
diff --git a/src/lib/libc/string/strsignal.3 b/src/lib/libc/string/strsignal.3
index 3287fef53e..b1082c2dd0 100644
--- a/src/lib/libc/string/strsignal.3
+++ b/src/lib/libc/string/strsignal.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,12 +29,11 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)strerror.3 6.9 (Berkeley) 6/29/91 32.\" $OpenBSD: strsignal.3,v 1.4 2003/06/02 20:18:38 millert Exp $
37.\" $Id: strsignal.3,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd June 29, 1991
40.Dt STRSIGNAL 3 35.Dt STRSIGNAL 3
41.Os BSD 4 36.Os
42.Sh NAME 37.Sh NAME
43.Nm strsignal 38.Nm strsignal
44.Nd get signal description string 39.Nd get signal description string
diff --git a/src/lib/libc/string/strsignal.c b/src/lib/libc/string/strsignal.c
index ec4a267edf..afe0deb272 100644
--- a/src/lib/libc/string/strsignal.c
+++ b/src/lib/libc/string/strsignal.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,19 +28,18 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)strerror.c 5.6 (Berkeley) 5/4/91";*/ 31static char *rcsid = "$OpenBSD: strsignal.c,v 1.5 2003/06/11 21:08:16 deraadt Exp $";
36static char *rcsid = "$Id: strsignal.c,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
39#include <string.h> 34#include <string.h>
40#include <limits.h> 35#include <limits.h>
41 36
42extern char *__strsignal __P((int, char *)); 37extern char *__strsignal(int, char *);
43 38
44char * 39char *
45strsignal(sig) 40strsignal(int sig)
46 int sig;
47{ 41{
48 static char buf[NL_TEXTMAX]; 42 static char buf[NL_TEXTMAX];
43
49 return __strsignal(sig, buf); 44 return __strsignal(sig, buf);
50} 45}
diff --git a/src/lib/libc/string/strspn.3 b/src/lib/libc/string/strspn.3
index 4de03aa58b..54077b810c 100644
--- a/src/lib/libc/string/strspn.3
+++ b/src/lib/libc/string/strspn.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,8 +29,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)strspn.3 5.3 (Berkeley) 6/29/91 32.\" $OpenBSD: strspn.3,v 1.7 2003/06/02 20:18:38 millert Exp $
37.\" $Id: strspn.3,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd June 29, 1991
40.Dt STRSPN 3 35.Dt STRSPN 3
@@ -48,9 +43,8 @@
48.Fn strspn "const char *s" "const char *charset" 43.Fn strspn "const char *s" "const char *charset"
49.Sh DESCRIPTION 44.Sh DESCRIPTION
50The 45The
51.Xr strcspn 46.Fn strspn
52function 47function spans the initial part of the null-terminated string
53spans the initial part of the null-terminated string
54.Fa s 48.Fa s
55as long as the characters from 49as long as the characters from
56.Fa s 50.Fa s
@@ -59,12 +53,23 @@ occur in string
59.Sh RETURN VALUES 53.Sh RETURN VALUES
60The 54The
61.Fn strspn 55.Fn strspn
62function 56function returns the number of characters spanned.
63returns the number of characters spanned. 57.Sh EXAMPLES
58The following call to
59.Fn strspn
60will return 3, since the first three characters of string
61.Fa s
62are part of string
63.Fa charset :
64.Bd -literal -offset indent
65char *s = "foobar";
66char *charset = "of";
67size_t span;
68
69span = strspn(s, charset);
70.Ed
64.Sh SEE ALSO 71.Sh SEE ALSO
65.Xr index 3 ,
66.Xr memchr 3 , 72.Xr memchr 3 ,
67.Xr rindex 3 ,
68.Xr strchr 3 , 73.Xr strchr 3 ,
69.Xr strcspn 3 , 74.Xr strcspn 3 ,
70.Xr strpbrk 3 , 75.Xr strpbrk 3 ,
@@ -75,6 +80,5 @@ returns the number of characters spanned.
75.Sh STANDARDS 80.Sh STANDARDS
76The 81The
77.Fn strspn 82.Fn strspn
78function 83function conforms to
79conforms to
80.St -ansiC . 84.St -ansiC .
diff --git a/src/lib/libc/string/strspn.c b/src/lib/libc/string/strspn.c
index 6224b25c2a..d51a8cd3e6 100644
--- a/src/lib/libc/string/strspn.c
+++ b/src/lib/libc/string/strspn.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,8 +28,7 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)strspn.c 5.8 (Berkeley) 1/26/91";*/ 31static char *rcsid = "$OpenBSD: strspn.c,v 1.4 2003/06/11 21:08:29 deraadt Exp $";
36static char *rcsid = "$Id: strspn.c,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
39#include <string.h> 34#include <string.h>
@@ -42,12 +37,10 @@ static char *rcsid = "$Id: strspn.c,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $"
42 * Span the string s2 (skip characters that are in s2). 37 * Span the string s2 (skip characters that are in s2).
43 */ 38 */
44size_t 39size_t
45strspn(s1, s2) 40strspn(const char *s1, const char *s2)
46 const char *s1;
47 register const char *s2;
48{ 41{
49 register const char *p = s1, *spanp; 42 const char *p = s1, *spanp;
50 register char c, sc; 43 char c, sc;
51 44
52 /* 45 /*
53 * Skip any characters in s2, excluding the terminating \0. 46 * Skip any characters in s2, excluding the terminating \0.
diff --git a/src/lib/libc/string/strstr.3 b/src/lib/libc/string/strstr.3
index 24fdf540ed..47777dd89f 100644
--- a/src/lib/libc/string/strstr.3
+++ b/src/lib/libc/string/strstr.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,8 +29,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)strstr.3 5.3 (Berkeley) 6/29/91 32.\" $OpenBSD: strstr.3,v 1.6 2003/06/02 20:18:38 millert Exp $
37.\" $Id: strstr.3,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd June 29, 1991
40.Dt STRSTR 3 35.Dt STRSTR 3
@@ -49,8 +44,7 @@
49.Sh DESCRIPTION 44.Sh DESCRIPTION
50The 45The
51.Fn strstr 46.Fn strstr
52function 47function locates the first occurrence of the null-terminated string
53locates the first occurrence of the null-terminated string
54.Fa little 48.Fa little
55in the null-terminated string 49in the null-terminated string
56.Fa big . 50.Fa big .
@@ -65,15 +59,14 @@ if
65occurs nowhere in 59occurs nowhere in
66.Fa big , 60.Fa big ,
67.Fn strstr 61.Fn strstr
68returns NULL; 62returns
63.Dv NULL ;
69otherwise 64otherwise
70.Fn strstr 65.Fn strstr
71returns a pointer to the first character of the first occurrence of 66returns a pointer to the first character of the first occurrence of
72.Fa little . 67.Fa little .
73.Sh SEE ALSO 68.Sh SEE ALSO
74.Xr index 3 ,
75.Xr memchr 3 , 69.Xr memchr 3 ,
76.Xr rindex 3 ,
77.Xr strchr 3 , 70.Xr strchr 3 ,
78.Xr strcspn 3 , 71.Xr strcspn 3 ,
79.Xr strpbrk 3 , 72.Xr strpbrk 3 ,
@@ -84,6 +77,5 @@ returns a pointer to the first character of the first occurrence of
84.Sh STANDARDS 77.Sh STANDARDS
85The 78The
86.Fn strstr 79.Fn strstr
87function 80function conforms to
88conforms to
89.St -ansiC . 81.St -ansiC .
diff --git a/src/lib/libc/string/strstr.c b/src/lib/libc/string/strstr.c
index 1ed59e357b..e6a94c5ce6 100644
--- a/src/lib/libc/string/strstr.c
+++ b/src/lib/libc/string/strstr.c
@@ -13,11 +13,7 @@
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software 16 * 3. Neither the name of the University nor the names of its contributors
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 17 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission. 18 * without specific prior written permission.
23 * 19 *
@@ -35,8 +31,7 @@
35 */ 31 */
36 32
37#if defined(LIBC_SCCS) && !defined(lint) 33#if defined(LIBC_SCCS) && !defined(lint)
38/*static char *sccsid = "from: @(#)strstr.c 5.2 (Berkeley) 1/26/91";*/ 34static char *rcsid = "$OpenBSD: strstr.c,v 1.4 2003/06/11 21:08:16 deraadt Exp $";
39static char *rcsid = "$Id: strstr.c,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */ 35#endif /* LIBC_SCCS and not lint */
41 36
42#include <string.h> 37#include <string.h>
@@ -45,11 +40,10 @@ static char *rcsid = "$Id: strstr.c,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $"
45 * Find the first occurrence of find in s. 40 * Find the first occurrence of find in s.
46 */ 41 */
47char * 42char *
48strstr(s, find) 43strstr(const char *s, const char *find)
49 register const char *s, *find;
50{ 44{
51 register char c, sc; 45 char c, sc;
52 register size_t len; 46 size_t len;
53 47
54 if ((c = *find++) != 0) { 48 if ((c = *find++) != 0) {
55 len = strlen(find); 49 len = strlen(find);
diff --git a/src/lib/libc/string/strtok.3 b/src/lib/libc/string/strtok.3
index 644bd10aed..29eea4847e 100644
--- a/src/lib/libc/string/strtok.3
+++ b/src/lib/libc/string/strtok.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,29 +29,30 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)strtok.3 5.8 (Berkeley) 6/29/91 32.\" $OpenBSD: strtok.3,v 1.17 2004/01/20 06:06:48 millert Exp $
37.\" $Id: strtok.3,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd June 29, 1991
40.Dt STRTOK 3 35.Dt STRTOK 3
41.Os BSD 3 36.Os
42.Sh NAME 37.Sh NAME
43.Nm strtok , 38.Nm strtok ,
44.Nm strsep 39.Nm strtok_r
45.Nd string token operations 40.Nd string token operations
46.Sh SYNOPSIS 41.Sh SYNOPSIS
47.Fd #include <string.h> 42.Fd #include <string.h>
48.Ft char * 43.Ft char *
49.Fn strtok "char *str" "const char *sep" 44.Fn strtok "char *str" "const char *sep"
45.Ft char *
46.Fn strtok_r "char *str" "const char *sep" "char **last"
50.Sh DESCRIPTION 47.Sh DESCRIPTION
51.Bf -symbolic 48.Bf -symbolic
52This interface is obsoleted by strsep(3). 49This interface is obsoleted by
50.Xr strsep 3 .
53.Ef 51.Ef
54.Pp 52.Pp
55The 53The
56.Fn strtok 54.Fn strtok
57function 55function is used to isolate sequential tokens in a null-terminated string,
58is used to isolate sequential tokens in a null-terminated string,
59.Fa str . 56.Fa str .
60These tokens are separated in the string by at least one of the 57These tokens are separated in the string by at least one of the
61characters in 58characters in
@@ -71,17 +68,65 @@ The separator string,
71must be supplied each time, and may change between calls. 68must be supplied each time, and may change between calls.
72.Pp 69.Pp
73The 70The
71.Fn strtok_r
72function is a version of
74.Fn strtok 73.Fn strtok
75function 74that takes an explicit context argument and is reentrant.
76returns a pointer to the beginning of each subsequent token in the string, 75.Pp
77after replacing the separator character itself with a 76The
78.Dv NUL 77.Fn strtok
78and
79.Fn strtok_r
80functions return a pointer to the beginning of each subsequent token
81in the string, after replacing the separator character itself with an
82.Tn ASCII NUL
79character. 83character.
80When no more tokens remain, a null pointer is returned. 84When no more tokens remain, a null pointer is returned.
85.Pp
86Since
87.Fn strtok
88and
89.Fn strtok_r
90modify the string,
91.Fa str
92should not point to an area in the initialized data segment.
93.Sh EXAMPLES
94The following will construct an array of pointers to each individual word in
95the string
96.Va s :
97.Bd -literal -offset indent
98#define MAXTOKENS 128
99
100char s[512], *p, *tokens[MAXTOKENS];
101char *last;
102int i = 0;
103
104snprintf(s, sizeof(s), "cat dog horse cow");
105
106for ((p = strtok_r(s, " ", &last)); p;
107 (p = strtok_r(NULL, " ", &last))) {
108 if (i < MAXTOKENS - 1)
109 tokens[i++] = p;
110}
111tokens[i] = NULL;
112.Ed
113.Pp
114That is,
115.Li tokens[0]
116will point to
117.Qq cat ,
118.Li tokens[1]
119will point to
120.Qq dog ,
121.Li tokens[2]
122will point to
123.Qq horse ,
124and
125.Li tokens[3]
126will point to
127.Qq cow .
81.Sh SEE ALSO 128.Sh SEE ALSO
82.Xr index 3 ,
83.Xr memchr 3 , 129.Xr memchr 3 ,
84.Xr rindex 3 ,
85.Xr strchr 3 , 130.Xr strchr 3 ,
86.Xr strcspn 3 , 131.Xr strcspn 3 ,
87.Xr strpbrk 3 , 132.Xr strpbrk 3 ,
@@ -92,21 +137,16 @@ When no more tokens remain, a null pointer is returned.
92.Sh STANDARDS 137.Sh STANDARDS
93The 138The
94.Fn strtok 139.Fn strtok
95function 140function conforms to
96conforms to
97.St -ansiC . 141.St -ansiC .
98.Sh BUGS 142.Sh BUGS
99There is no way to get tokens from multiple strings simultaneously.
100.Pp
101The System V 143The System V
102.Fn strtok , 144.Fn strtok ,
103if handed a string containing only delimiter characters, 145if handed a string containing only delimiter characters,
104will not alter the next starting point, so that a call to 146will not alter the next starting point, so that a call to
105.Fn strtok 147.Fn strtok
106with a different (or empty) delimiter string 148with a different (or empty) delimiter string
107may return a 149may return a non-null value.
108.Pf non- Dv NULL
109value.
110Since this implementation always alters the next starting point, 150Since this implementation always alters the next starting point,
111such a sequence of calls would always return 151such a sequence of calls would always return
112.Dv NULL . 152.Dv NULL .
diff --git a/src/lib/libc/string/strtok.c b/src/lib/libc/string/strtok.c
index 9f712579bf..6498eac8cc 100644
--- a/src/lib/libc/string/strtok.c
+++ b/src/lib/libc/string/strtok.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,24 +28,28 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)strtok.c 5.8 (Berkeley) 2/24/91";*/ 31static char *rcsid = "$OpenBSD: strtok.c,v 1.5 2003/06/11 21:08:16 deraadt Exp $";
36static char *rcsid = "$Id: strtok.c,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
39#include <string.h> 34#include <string.h>
40 35
41char * 36char *
42strtok(s, delim) 37strtok(char *s, const char *delim)
43 register char *s;
44 register const char *delim;
45{ 38{
46 register char *spanp;
47 register int c, sc;
48 char *tok;
49 static char *last; 39 static char *last;
50 40
41 return strtok_r(s, delim, &last);
42}
43
44char *
45strtok_r(char *s, const char *delim, char **last)
46{
47 char *spanp;
48 int c, sc;
49 char *tok;
50
51 51
52 if (s == NULL && (s = last) == NULL) 52 if (s == NULL && (s = *last) == NULL)
53 return (NULL); 53 return (NULL);
54 54
55 /* 55 /*
@@ -63,7 +63,7 @@ cont:
63 } 63 }
64 64
65 if (c == 0) { /* no non-delimiter characters */ 65 if (c == 0) { /* no non-delimiter characters */
66 last = NULL; 66 *last = NULL;
67 return (NULL); 67 return (NULL);
68 } 68 }
69 tok = s - 1; 69 tok = s - 1;
@@ -81,7 +81,7 @@ cont:
81 s = NULL; 81 s = NULL;
82 else 82 else
83 s[-1] = 0; 83 s[-1] = 0;
84 last = s; 84 *last = s;
85 return (tok); 85 return (tok);
86 } 86 }
87 } while (sc != 0); 87 } while (sc != 0);
diff --git a/src/lib/libc/string/strxfrm.3 b/src/lib/libc/string/strxfrm.3
index 84fd945472..edf2bfb8a0 100644
--- a/src/lib/libc/string/strxfrm.3
+++ b/src/lib/libc/string/strxfrm.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,8 +29,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)strxfrm.3 5.4 (Berkeley) 6/29/91 32.\" $OpenBSD: strxfrm.3,v 1.4 2003/06/02 20:18:38 millert Exp $
37.\" $Id: strxfrm.3,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd June 29, 1991
40.Dt STRXFRM 3 35.Dt STRXFRM 3
@@ -49,8 +44,7 @@
49.Sh DESCRIPTION 44.Sh DESCRIPTION
50The 45The
51.Fn strxfrm 46.Fn strxfrm
52function 47function does something horrible (see
53does something horrible (see
54.Tn ANSI 48.Tn ANSI
55standard). 49standard).
56In this implementation it just copies. 50In this implementation it just copies.
@@ -64,6 +58,5 @@ In this implementation it just copies.
64.Sh STANDARDS 58.Sh STANDARDS
65The 59The
66.Fn strxfrm 60.Fn strxfrm
67function 61function conforms to
68conforms to
69.St -ansiC . 62.St -ansiC .
diff --git a/src/lib/libc/string/strxfrm.c b/src/lib/libc/string/strxfrm.c
index d9df77b957..a2e2dbc440 100644
--- a/src/lib/libc/string/strxfrm.c
+++ b/src/lib/libc/string/strxfrm.c
@@ -13,11 +13,7 @@
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software 16 * 3. Neither the name of the University nor the names of its contributors
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 17 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission. 18 * without specific prior written permission.
23 * 19 *
@@ -35,8 +31,7 @@
35 */ 31 */
36 32
37#if defined(LIBC_SCCS) && !defined(lint) 33#if defined(LIBC_SCCS) && !defined(lint)
38/*static char *sccsid = "from: @(#)strxfrm.c 5.2 (Berkeley) 1/26/91";*/ 34static char *rcsid = "$OpenBSD: strxfrm.c,v 1.5 2003/09/06 22:43:12 tedu Exp $";
39static char *rcsid = "$Id: strxfrm.c,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */ 35#endif /* LIBC_SCCS and not lint */
41 36
42#include <string.h> 37#include <string.h>
@@ -47,28 +42,13 @@ static char *rcsid = "$Id: strxfrm.c,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $
47 * on the original untransformed strings would return. 42 * on the original untransformed strings would return.
48 */ 43 */
49size_t 44size_t
50strxfrm(dst, src, n) 45strxfrm(char *dst, const char *src, size_t n)
51 register char *dst;
52 register const char *src;
53 register size_t n;
54{ 46{
55 register size_t r = 0;
56 register int c;
57 47
58 /* 48 /*
59 * Since locales are unimplemented, this is just a copy. 49 * Since locales are unimplemented, this is just a copy.
60 */ 50 */
61 if (n != 0) { 51 if (n == 0)
62 while ((c = *src++) != 0) { 52 return (strlen(src));
63 r++; 53 return (strlcpy(dst, src, n));
64 if (--n == 0) {
65 while (*src++ != 0)
66 r++;
67 break;
68 }
69 *dst++ = c;
70 }
71 *dst = 0;
72 }
73 return (r);
74} 54}
diff --git a/src/lib/libc/string/swab.3 b/src/lib/libc/string/swab.3
index 133c487bbd..abeff903de 100644
--- a/src/lib/libc/string/swab.3
+++ b/src/lib/libc/string/swab.3
@@ -9,11 +9,7 @@
9.\" 2. Redistributions in binary form must reproduce the above copyright 9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\" notice, this list of conditions and the following disclaimer in the 10.\" notice, this list of conditions and the following disclaimer in the
11.\" documentation and/or other materials provided with the distribution. 11.\" documentation and/or other materials provided with the distribution.
12.\" 3. All advertising materials mentioning features or use of this software 12.\" 3. Neither the name of the University nor the names of its contributors
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 13.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission. 14.\" without specific prior written permission.
19.\" 15.\"
@@ -29,8 +25,7 @@
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE. 26.\" SUCH DAMAGE.
31.\" 27.\"
32.\" from: @(#)swab.3 6.6 (Berkeley) 5/1/91 28.\" $OpenBSD: swab.3,v 1.5 2003/06/02 20:18:38 millert Exp $
33.\" $Id: swab.3,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $
34.\" 29.\"
35.Dd May 1, 1991 30.Dd May 1, 1991
36.Dt SWAB 3 31.Dt SWAB 3
@@ -39,7 +34,7 @@
39.Nm swab 34.Nm swab
40.Nd swap adjacent bytes 35.Nd swap adjacent bytes
41.Sh SYNOPSIS 36.Sh SYNOPSIS
42.Fd #include <string.h> 37.Fd #include <unistd.h>
43.Ft void 38.Ft void
44.Fn swab "const void *src" "void *dst" "size_t len" 39.Fn swab "const void *src" "void *dst" "size_t len"
45.Sh DESCRIPTION 40.Sh DESCRIPTION
@@ -55,7 +50,7 @@ swapping adjacent bytes.
55.Pp 50.Pp
56The argument 51The argument
57.Fa len 52.Fa len
58must be even number. 53must be an even number.
59.Sh SEE ALSO 54.Sh SEE ALSO
60.Xr bzero 3 , 55.Xr bzero 3 ,
61.Xr memset 3 56.Xr memset 3
diff --git a/src/lib/libc/string/swab.c b/src/lib/libc/string/swab.c
index f33fc53bd6..b928f21aa7 100644
--- a/src/lib/libc/string/swab.c
+++ b/src/lib/libc/string/swab.c
@@ -13,11 +13,7 @@
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software 16 * 3. Neither the name of the University nor the names of its contributors
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 17 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission. 18 * without specific prior written permission.
23 * 19 *
@@ -35,17 +31,13 @@
35 */ 31 */
36 32
37#if defined(LIBC_SCCS) && !defined(lint) 33#if defined(LIBC_SCCS) && !defined(lint)
38/*static char *sccsid = "from: @(#)swab.c 5.10 (Berkeley) 3/6/91";*/ 34static char *rcsid = "$OpenBSD: swab.c,v 1.5 2003/06/11 21:08:16 deraadt Exp $";
39static char *rcsid = "$Id: swab.c,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */ 35#endif /* LIBC_SCCS and not lint */
41 36
42#include <string.h> 37#include <unistd.h>
43 38
44void 39void
45swab(from, to, len) 40swab(const void *from, void *to, size_t len)
46 const void *from;
47 void *to;
48 size_t len;
49{ 41{
50 register unsigned long temp; 42 register unsigned long temp;
51 register int n; 43 register int n;