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.inc12
-rw-r--r--src/lib/libc/crypt/arc4random.383
-rw-r--r--src/lib/libc/crypt/arc4random.c176
-rw-r--r--src/lib/libc/crypt/bcrypt.c362
-rw-r--r--src/lib/libc/crypt/blowfish.3104
-rw-r--r--src/lib/libc/crypt/blowfish.c774
-rw-r--r--src/lib/libc/crypt/cast.c779
-rw-r--r--src/lib/libc/crypt/crypt.3298
-rw-r--r--src/lib/libc/crypt/crypt.c714
-rw-r--r--src/lib/libc/crypt/md5crypt.c157
-rw-r--r--src/lib/libc/crypt/morecrypt.c628
-rw-r--r--src/lib/libc/include/namespace.h18
-rw-r--r--src/lib/libc/net/Makefile.inc56
-rw-r--r--src/lib/libc/net/base64.c317
-rw-r--r--src/lib/libc/net/byteorder.3155
-rw-r--r--src/lib/libc/net/ethers.3109
-rw-r--r--src/lib/libc/net/ethers.c270
-rw-r--r--src/lib/libc/net/gethostbyname.3266
-rw-r--r--src/lib/libc/net/gethostnamadr.c1079
-rw-r--r--src/lib/libc/net/getnetbyaddr.c56
-rw-r--r--src/lib/libc/net/getnetbyname.c62
-rw-r--r--src/lib/libc/net/getnetent.3148
-rw-r--r--src/lib/libc/net/getnetent.c129
-rw-r--r--src/lib/libc/net/getnetnamadr.c382
-rw-r--r--src/lib/libc/net/getproto.c55
-rw-r--r--src/lib/libc/net/getprotoent.3144
-rw-r--r--src/lib/libc/net/getprotoent.c123
-rw-r--r--src/lib/libc/net/getprotoname.c62
-rw-r--r--src/lib/libc/net/getservbyname.c65
-rw-r--r--src/lib/libc/net/getservbyport.c60
-rw-r--r--src/lib/libc/net/getservent.3155
-rw-r--r--src/lib/libc/net/getservent.c125
-rw-r--r--src/lib/libc/net/herror.c121
-rw-r--r--src/lib/libc/net/htonl.c25
-rw-r--r--src/lib/libc/net/htons.c29
-rw-r--r--src/lib/libc/net/inet.3319
-rw-r--r--src/lib/libc/net/inet_addr.c187
-rw-r--r--src/lib/libc/net/inet_lnaof.c59
-rw-r--r--src/lib/libc/net/inet_makeaddr.c62
-rw-r--r--src/lib/libc/net/inet_net.3149
-rw-r--r--src/lib/libc/net/inet_net_ntop.c139
-rw-r--r--src/lib/libc/net/inet_net_pton.c207
-rw-r--r--src/lib/libc/net/inet_neta.c83
-rw-r--r--src/lib/libc/net/inet_netof.c58
-rw-r--r--src/lib/libc/net/inet_network.c92
-rw-r--r--src/lib/libc/net/inet_ntoa.c59
-rw-r--r--src/lib/libc/net/inet_ntop.c194
-rw-r--r--src/lib/libc/net/inet_pton.c220
-rw-r--r--src/lib/libc/net/ipx.3126
-rw-r--r--src/lib/libc/net/ipx_addr.c229
-rw-r--r--src/lib/libc/net/ipx_ntoa.c58
-rw-r--r--src/lib/libc/net/iso_addr.3110
-rw-r--r--src/lib/libc/net/iso_addr.c119
-rw-r--r--src/lib/libc/net/link_addr.3131
-rw-r--r--src/lib/libc/net/linkaddr.c158
-rw-r--r--src/lib/libc/net/ns.3130
-rw-r--r--src/lib/libc/net/ns_addr.c228
-rw-r--r--src/lib/libc/net/ns_ntoa.c101
-rw-r--r--src/lib/libc/net/nsap_addr.c109
-rw-r--r--src/lib/libc/net/ntohl.c25
-rw-r--r--src/lib/libc/net/ntohs.c29
-rw-r--r--src/lib/libc/net/rcmd.3227
-rw-r--r--src/lib/libc/net/rcmd.c607
-rw-r--r--src/lib/libc/net/rcmdsh.3108
-rw-r--r--src/lib/libc/net/rcmdsh.c124
-rw-r--r--src/lib/libc/net/recv.c50
-rw-r--r--src/lib/libc/net/res_comp.c510
-rw-r--r--src/lib/libc/net/res_data.c117
-rw-r--r--src/lib/libc/net/res_debug.c1518
-rw-r--r--src/lib/libc/net/res_init.c518
-rw-r--r--src/lib/libc/net/res_mkquery.c195
-rw-r--r--src/lib/libc/net/res_query.c398
-rw-r--r--src/lib/libc/net/res_random.c233
-rw-r--r--src/lib/libc/net/res_send.c780
-rw-r--r--src/lib/libc/net/resolver.3345
-rw-r--r--src/lib/libc/net/send.c50
-rw-r--r--src/lib/libc/net/sethostent.c60
-rw-r--r--src/lib/libc/stdlib/Makefile.inc54
-rw-r--r--src/lib/libc/stdlib/_rand48.c50
-rw-r--r--src/lib/libc/stdlib/a64l.3122
-rw-r--r--src/lib/libc/stdlib/a64l.c46
-rw-r--r--src/lib/libc/stdlib/abort.370
-rw-r--r--src/lib/libc/stdlib/abort.c77
-rw-r--r--src/lib/libc/stdlib/abs.373
-rw-r--r--src/lib/libc/stdlib/abs.c45
-rw-r--r--src/lib/libc/stdlib/alloca.375
-rw-r--r--src/lib/libc/stdlib/atexit.377
-rw-r--r--src/lib/libc/stdlib/atexit.c67
-rw-r--r--src/lib/libc/stdlib/atexit.h45
-rw-r--r--src/lib/libc/stdlib/atof.373
-rw-r--r--src/lib/libc/stdlib/atof.c45
-rw-r--r--src/lib/libc/stdlib/atoi.373
-rw-r--r--src/lib/libc/stdlib/atoi.c45
-rw-r--r--src/lib/libc/stdlib/atol.374
-rw-r--r--src/lib/libc/stdlib/atol.c45
-rw-r--r--src/lib/libc/stdlib/bsearch.390
-rw-r--r--src/lib/libc/stdlib/bsearch.c79
-rw-r--r--src/lib/libc/stdlib/calloc.370
-rw-r--r--src/lib/libc/stdlib/calloc.c53
-rw-r--r--src/lib/libc/stdlib/cfree.c49
-rw-r--r--src/lib/libc/stdlib/div.369
-rw-r--r--src/lib/libc/stdlib/div.c79
-rw-r--r--src/lib/libc/stdlib/drand48.c26
-rw-r--r--src/lib/libc/stdlib/erand48.c27
-rw-r--r--src/lib/libc/stdlib/exit.383
-rw-r--r--src/lib/libc/stdlib/exit.c60
-rw-r--r--src/lib/libc/stdlib/getenv.3151
-rw-r--r--src/lib/libc/stdlib/getenv.c89
-rw-r--r--src/lib/libc/stdlib/getopt.3261
-rw-r--r--src/lib/libc/stdlib/getopt.c117
-rw-r--r--src/lib/libc/stdlib/getsubopt.3148
-rw-r--r--src/lib/libc/stdlib/getsubopt.c106
-rw-r--r--src/lib/libc/stdlib/heapsort.c183
-rw-r--r--src/lib/libc/stdlib/jrand48.c25
-rw-r--r--src/lib/libc/stdlib/l64a.c46
-rw-r--r--src/lib/libc/stdlib/labs.366
-rw-r--r--src/lib/libc/stdlib/labs.c45
-rw-r--r--src/lib/libc/stdlib/lcong48.c34
-rw-r--r--src/lib/libc/stdlib/ldiv.371
-rw-r--r--src/lib/libc/stdlib/ldiv.c58
-rw-r--r--src/lib/libc/stdlib/lrand48.c27
-rw-r--r--src/lib/libc/stdlib/malloc.3350
-rw-r--r--src/lib/libc/stdlib/malloc.c1242
-rw-r--r--src/lib/libc/stdlib/memory.370
-rw-r--r--src/lib/libc/stdlib/merge.c347
-rw-r--r--src/lib/libc/stdlib/mrand48.c27
-rw-r--r--src/lib/libc/stdlib/multibyte.c130
-rw-r--r--src/lib/libc/stdlib/nrand48.c25
-rw-r--r--src/lib/libc/stdlib/putenv.c58
-rw-r--r--src/lib/libc/stdlib/qabs.361
-rw-r--r--src/lib/libc/stdlib/qabs.c45
-rw-r--r--src/lib/libc/stdlib/qdiv.365
-rw-r--r--src/lib/libc/stdlib/qdiv.c58
-rw-r--r--src/lib/libc/stdlib/qsort.3233
-rw-r--r--src/lib/libc/stdlib/qsort.c175
-rw-r--r--src/lib/libc/stdlib/radixsort.3161
-rw-r--r--src/lib/libc/stdlib/radixsort.c317
-rw-r--r--src/lib/libc/stdlib/rand.387
-rw-r--r--src/lib/libc/stdlib/rand.c54
-rw-r--r--src/lib/libc/stdlib/rand48.3161
-rw-r--r--src/lib/libc/stdlib/rand48.h32
-rw-r--r--src/lib/libc/stdlib/random.3183
-rw-r--r--src/lib/libc/stdlib/random.c370
-rw-r--r--src/lib/libc/stdlib/realpath.3125
-rw-r--r--src/lib/libc/stdlib/realpath.c163
-rw-r--r--src/lib/libc/stdlib/seed48.c40
-rw-r--r--src/lib/libc/stdlib/setenv.c120
-rw-r--r--src/lib/libc/stdlib/srand48.c34
-rw-r--r--src/lib/libc/stdlib/strtod.3113
-rw-r--r--src/lib/libc/stdlib/strtod.c2529
-rw-r--r--src/lib/libc/stdlib/strtol.3168
-rw-r--r--src/lib/libc/stdlib/strtol.c150
-rw-r--r--src/lib/libc/stdlib/strtoq.c152
-rw-r--r--src/lib/libc/stdlib/strtoul.3163
-rw-r--r--src/lib/libc/stdlib/strtoul.c112
-rw-r--r--src/lib/libc/stdlib/strtouq.c114
-rw-r--r--src/lib/libc/stdlib/system.398
-rw-r--r--src/lib/libc/stdlib/system.c80
-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.inc128
-rw-r--r--src/lib/libc/string/__strerror.c111
-rw-r--r--src/lib/libc/string/__strsignal.c104
-rw-r--r--src/lib/libc/string/bcmp.371
-rw-r--r--src/lib/libc/string/bcmp.c63
-rw-r--r--src/lib/libc/string/bcopy.371
-rw-r--r--src/lib/libc/string/bcopy.c138
-rw-r--r--src/lib/libc/string/bm.3113
-rw-r--r--src/lib/libc/string/bm.c219
-rw-r--r--src/lib/libc/string/bstring.3109
-rw-r--r--src/lib/libc/string/bzero.367
-rw-r--r--src/lib/libc/string/bzero.c56
-rw-r--r--src/lib/libc/string/ffs.362
-rw-r--r--src/lib/libc/string/ffs.c58
-rw-r--r--src/lib/libc/string/index.382
-rw-r--r--src/lib/libc/string/index.c55
-rw-r--r--src/lib/libc/string/memccpy.375
-rw-r--r--src/lib/libc/string/memccpy.c64
-rw-r--r--src/lib/libc/string/memchr.381
-rw-r--r--src/lib/libc/string/memchr.c58
-rw-r--r--src/lib/libc/string/memcmp.382
-rw-r--r--src/lib/libc/string/memcmp.c60
-rw-r--r--src/lib/libc/string/memcpy.383
-rw-r--r--src/lib/libc/string/memmove.375
-rw-r--r--src/lib/libc/string/memset.372
-rw-r--r--src/lib/libc/string/memset.c58
-rw-r--r--src/lib/libc/string/rindex.380
-rw-r--r--src/lib/libc/string/rindex.c57
-rw-r--r--src/lib/libc/string/strcasecmp.389
-rw-r--r--src/lib/libc/string/strcasecmp.c120
-rw-r--r--src/lib/libc/string/strcat.396
-rw-r--r--src/lib/libc/string/strcat.c54
-rw-r--r--src/lib/libc/string/strchr.387
-rw-r--r--src/lib/libc/string/strcmp.393
-rw-r--r--src/lib/libc/string/strcmp.c58
-rw-r--r--src/lib/libc/string/strcoll.374
-rw-r--r--src/lib/libc/string/strcoll.c52
-rw-r--r--src/lib/libc/string/strcpy.3121
-rw-r--r--src/lib/libc/string/strcpy.c53
-rw-r--r--src/lib/libc/string/strcspn.384
-rw-r--r--src/lib/libc/string/strcspn.c67
-rw-r--r--src/lib/libc/string/strdup.368
-rw-r--r--src/lib/libc/string/strdup.c62
-rw-r--r--src/lib/libc/string/strerror.365
-rw-r--r--src/lib/libc/string/strerror.c55
-rw-r--r--src/lib/libc/string/string.3155
-rw-r--r--src/lib/libc/string/strlcat.c71
-rw-r--r--src/lib/libc/string/strlcpy.3140
-rw-r--r--src/lib/libc/string/strlcpy.c63
-rw-r--r--src/lib/libc/string/strlen.370
-rw-r--r--src/lib/libc/string/strlen.c53
-rw-r--r--src/lib/libc/string/strmode.3152
-rw-r--r--src/lib/libc/string/strmode.c152
-rw-r--r--src/lib/libc/string/strncat.c67
-rw-r--r--src/lib/libc/string/strncmp.c59
-rw-r--r--src/lib/libc/string/strncpy.c67
-rw-r--r--src/lib/libc/string/strpbrk.379
-rw-r--r--src/lib/libc/string/strpbrk.c56
-rw-r--r--src/lib/libc/string/strrchr.390
-rw-r--r--src/lib/libc/string/strsep.3110
-rw-r--r--src/lib/libc/string/strsep.c85
-rw-r--r--src/lib/libc/string/strsignal.360
-rw-r--r--src/lib/libc/string/strsignal.c49
-rw-r--r--src/lib/libc/string/strspn.379
-rw-r--r--src/lib/libc/string/strspn.c60
-rw-r--r--src/lib/libc/string/strstr.388
-rw-r--r--src/lib/libc/string/strstr.c64
-rw-r--r--src/lib/libc/string/strtok.3112
-rw-r--r--src/lib/libc/string/strtok.c89
-rw-r--r--src/lib/libc/string/strxfrm.368
-rw-r--r--src/lib/libc/string/strxfrm.c73
-rw-r--r--src/lib/libc/string/swab.365
-rw-r--r--src/lib/libc/string/swab.c65
234 files changed, 35273 insertions, 0 deletions
diff --git a/src/lib/libc/crypt/Makefile.inc b/src/lib/libc/crypt/Makefile.inc
new file mode 100644
index 0000000000..9d96d657db
--- /dev/null
+++ b/src/lib/libc/crypt/Makefile.inc
@@ -0,0 +1,12 @@
1# $OpenBSD: Makefile.inc,v 1.10 1998/07/21 22:23:20 provos Exp $
2
3.PATH: ${.CURDIR}/arch/${MACHINE_ARCH}/crypt ${.CURDIR}/crypt
4
5SRCS+= cast.c crypt.c morecrypt.c md5crypt.c arc4random.c blowfish.c
6SRCS+= bcrypt.c
7
8MAN+= crypt.3 blowfish.3 arc4random.3
9MLINKS+=crypt.3 encrypt.3 crypt.3 setkey.3 crypt.3 des_cipher.3
10MLINKS+=crypt.3 des_setkey.3 blowfish.3 blf_key.3 blowfish.3 blf_enc.3
11MLINKS+=blowfish.3 blf_dec.3
12MLINKS+=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..741965c5ac
--- /dev/null
+++ b/src/lib/libc/crypt/arc4random.3
@@ -0,0 +1,83 @@
1.\" $OpenBSD: arc4random.3,v 1.4 1998/09/07 16:44:34 aaron Exp $
2.\" Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
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 Niels Provos.
16.\" 4. The name of the author may not be used to endorse or promote products
17.\" derived from this software without specific prior written permission.
18.\"
19.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29.\"
30.\" Manual page, using -mandoc macros
31.\"
32.Dd April 15, 1997
33.Dt ARC4RANDOM 3
34.Os "OpenBSD 2.0"
35.Sh NAME
36.Nm arc4random,
37.Nm arc4random_stir,
38.Nm arc4random_addrandom
39.Nd arc4 random number generator.
40.Sh SYNOPSIS
41.Fd #include <stdlib.h>
42.Ft u_int32_t
43.Fn arc4random "void"
44.Ft void
45.Fn arc4random_stir "void"
46.Ft void
47.Fn arc4random_addrandom "u_char *dat" "int datlen"
48.Sh DESCRIPTION
49The
50.Fn arc4random
51function uses the key stream generator employed by the
52arc4 cipher, which uses 8*8 8 bit S-Boxes. The S-Boxes
53can be in about
54.if t 2\u\s71700\s10\d
55.if n (2**1700)
56states.
57.Pp
58The
59.Fn arc4random_stir
60function reads data from
61.Pa /dev/arandom
62and uses it to permutate the S-Boxes via
63.Fn arc4random_addrandom .
64.Pp
65There is no need to call
66.Fn arc4random_stir
67before using
68.Fn arc4random ,
69since
70.Fn arc4random
71automatically initalizes itself.
72.Sh SEE ALSO
73.Xr rand48 3 ,
74.Xr rand 3 ,
75.Xr random 3
76.Sh HISTORY
77.Pa RC4
78has been designed by RSA Data Security, Inc. It was posted anonymously
79to the USENET and was confirmed to be equivalent by several sources who
80had access to the original cipher. Since
81.Pa RC4
82used to be a trade secret, the cipher is now referred to as
83.Pa ARC4 .
diff --git a/src/lib/libc/crypt/arc4random.c b/src/lib/libc/crypt/arc4random.c
new file mode 100644
index 0000000000..5279c21518
--- /dev/null
+++ b/src/lib/libc/crypt/arc4random.c
@@ -0,0 +1,176 @@
1/* $OpenBSD: arc4random.c,v 1.3 1998/03/22 19:01:16 niklas 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 (for instance by leaving this copyright notice
10 * intact).
11 */
12
13/*
14 * This code is derived from section 17.1 of Applied Cryptography,
15 * second edition, which describes a stream cipher allegedly
16 * compatible with RSA Labs "RC4" cipher (the actual description of
17 * which is a trade secret). The same algorithm is used as a stream
18 * cipher called "arcfour" in Tatu Ylonen's ssh package.
19 *
20 * Here the stream cipher has been modified always to include the time
21 * when initializing the state. That makes it impossible to
22 * regenerate the same random sequence twice, so this can't be used
23 * for encryption, but will generate good random numbers.
24 *
25 * RC4 is a registered trademark of RSA Laboratories.
26 */
27
28#include <fcntl.h>
29#include <stdlib.h>
30#include <unistd.h>
31#include <sys/types.h>
32#include <sys/time.h>
33
34#ifdef __GNUC__
35#define inline __inline
36#else /* !__GNUC__ */
37#define inline
38#endif /* !__GNUC__ */
39
40struct arc4_stream {
41 u_int8_t i;
42 u_int8_t j;
43 u_int8_t s[256];
44};
45
46int rs_initialized;
47static struct arc4_stream rs;
48
49static inline void
50arc4_init(as)
51 struct arc4_stream *as;
52{
53 int n;
54
55 for (n = 0; n < 256; n++)
56 as->s[n] = n;
57 as->i = 0;
58 as->j = 0;
59}
60
61static inline void
62arc4_addrandom(as, dat, datlen)
63 struct arc4_stream *as;
64 u_char *dat;
65 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}
79
80static void
81arc4_stir(as)
82 struct arc4_stream *as;
83{
84 int fd;
85 struct {
86 struct timeval tv;
87 u_int8_t rnd[128 - sizeof(struct timeval)];
88 } rdat;
89
90 gettimeofday(&rdat.tv, NULL);
91 fd = open("/dev/arandom", O_RDONLY);
92 if (fd >= 0) {
93 read(fd, rdat.rnd, sizeof(rdat.rnd));
94 close(fd);
95 }
96 /* fd < 0? Ah, what the heck. We'll just take whatever was on the
97 * stack... */
98
99 arc4_addrandom(as, (void *) &rdat, sizeof(rdat));
100}
101
102static inline u_int8_t
103arc4_getbyte(as)
104 struct arc4_stream *as;
105{
106 u_int8_t si, sj;
107
108 as->i = (as->i + 1);
109 si = as->s[as->i];
110 as->j = (as->j + si);
111 sj = as->s[as->j];
112 as->s[as->i] = sj;
113 as->s[as->j] = si;
114 return (as->s[(si + sj) & 0xff]);
115}
116
117static inline u_int32_t
118arc4_getword(as)
119 struct arc4_stream *as;
120{
121 u_int32_t val;
122 val = arc4_getbyte(as) << 24;
123 val |= arc4_getbyte(as) << 16;
124 val |= arc4_getbyte(as) << 8;
125 val |= arc4_getbyte(as);
126 return val;
127}
128
129void
130arc4random_stir()
131{
132 if (!rs_initialized) {
133 arc4_init(&rs);
134 rs_initialized = 1;
135 }
136 arc4_stir(&rs);
137}
138
139void
140arc4random_addrandom(dat, datlen)
141 u_char *dat;
142 int datlen;
143{
144 if (!rs_initialized)
145 arc4random_stir();
146 arc4_addrandom(&rs, dat, datlen);
147}
148
149u_int32_t
150arc4random()
151{
152 if (!rs_initialized)
153 arc4random_stir();
154 return arc4_getword(&rs);
155}
156
157#if 0
158/*-------- Test code for i386 --------*/
159#include <stdio.h>
160#include <machine/pctr.h>
161int
162main(int argc, char **argv)
163{
164 const int iter = 1000000;
165 int i;
166 pctrval v;
167
168 v = rdtsc();
169 for (i = 0; i < iter; i++)
170 arc4random();
171 v = rdtsc() - v;
172 v /= iter;
173
174 printf("%qd cycles\n", v);
175}
176#endif
diff --git a/src/lib/libc/crypt/bcrypt.c b/src/lib/libc/crypt/bcrypt.c
new file mode 100644
index 0000000000..1b121fb28f
--- /dev/null
+++ b/src/lib/libc/crypt/bcrypt.c
@@ -0,0 +1,362 @@
1/* $OpenBSD: bcrypt.c,v 1.12 1998/08/10 18:33:07 provos 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 __P((u_int8_t));
70
71static void encode_salt __P((char *, u_int8_t *, u_int16_t, u_int8_t));
72static void encode_base64 __P((u_int8_t *, u_int8_t *, u_int16_t));
73static void decode_base64 __P((u_int8_t *, u_int16_t, u_int8_t *));
74
75static char encrypted[_PASSWORD_LEN];
76static char gsalt[BCRYPT_MAXSALT * 4 / 3 + 1];
77static char error[] = ":";
78
79const static u_int8_t Base64Code[] =
80"./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
81
82const static u_int8_t index_64[128] =
83{
84 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
85 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
86 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
87 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
88 255, 255, 255, 255, 255, 255, 0, 1, 54, 55,
89 56, 57, 58, 59, 60, 61, 62, 63, 255, 255,
90 255, 255, 255, 255, 255, 2, 3, 4, 5, 6,
91 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
92 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
93 255, 255, 255, 255, 255, 255, 28, 29, 30,
94 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
95 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
96 51, 52, 53, 255, 255, 255, 255, 255
97};
98#define CHAR64(c) ( (c) > 127 ? 255 : index_64[(c)])
99
100#ifdef __STDC__
101static void
102decode_base64(u_int8_t *buffer, u_int16_t len, u_int8_t *data)
103#else
104static void
105decode_base64(buffer, len, data)
106 u_int8_t *buffer;
107 u_int16_t len;
108 u_int8_t *data;
109#endif
110{
111 u_int8_t *bp = buffer;
112 u_int8_t *p = data;
113 u_int8_t c1, c2, c3, c4;
114 while (bp < buffer + len) {
115 c1 = CHAR64(*p);
116 c2 = CHAR64(*(p + 1));
117
118 /* Invalid data */
119 if (c1 == 255 || c2 == 255)
120 break;
121
122 *bp++ = (c1 << 2) | ((c2 & 0x30) >> 4);
123 if (bp >= buffer + len)
124 break;
125
126 c3 = CHAR64(*(p + 2));
127 if (c3 == 255)
128 break;
129
130 *bp++ = ((c2 & 0x0f) << 4) | ((c3 & 0x3c) >> 2);
131 if (bp >= buffer + len)
132 break;
133
134 c4 = CHAR64(*(p + 3));
135 if (c4 == 255)
136 break;
137 *bp++ = ((c3 & 0x03) << 6) | c4;
138
139 p += 4;
140 }
141}
142
143#ifdef __STDC__
144static void
145encode_salt(char *salt, u_int8_t *csalt, u_int16_t clen, u_int8_t logr)
146#else
147static void
148encode_salt(salt, csalt, clen, logr)
149 char *salt;
150 u_int8_t *csalt;
151 u_int16_t clen;
152 u_int8_t logr;
153#endif
154{
155 salt[0] = '$';
156 salt[1] = BCRYPT_VERSION;
157 salt[2] = 'a';
158 salt[3] = '$';
159
160 snprintf(salt + 4, 4, "%2.2u$", logr);
161
162 encode_base64((u_int8_t *) salt + 7, csalt, clen);
163}
164/* Generates a salt for this version of crypt.
165 Since versions may change. Keeping this here
166 seems sensible.
167 */
168
169#ifdef __STDC__
170char *
171bcrypt_gensalt(u_int8_t log_rounds)
172#else
173char *
174bcrypt_gensalt(log_rounds)
175 u_int8_t log_rounds;
176#endif
177{
178 u_int8_t csalt[BCRYPT_MAXSALT];
179 u_int16_t i;
180 u_int32_t seed = 0;
181
182 for (i = 0; i < BCRYPT_MAXSALT; i++) {
183 if (i % 4 == 0)
184 seed = arc4random();
185 csalt[i] = seed & 0xff;
186 seed = seed >> 8;
187 }
188
189 if (log_rounds < 4)
190 log_rounds = 4;
191
192 encode_salt(gsalt, csalt, BCRYPT_MAXSALT, log_rounds);
193 return gsalt;
194}
195/* We handle $Vers$log2(NumRounds)$salt+passwd$
196 i.e. $2$04$iwouldntknowwhattosayetKdJ6iFtacBqJdKe6aW7ou */
197
198char *
199bcrypt(key, salt)
200 const char *key;
201 const char *salt;
202{
203 blf_ctx state;
204 u_int32_t rounds, i, k;
205 u_int16_t j;
206 u_int8_t key_len, salt_len, logr, minor;
207 u_int8_t ciphertext[4 * BCRYPT_BLOCKS] = "OrpheanBeholderScryDoubt";
208 u_int8_t csalt[BCRYPT_MAXSALT];
209 u_int32_t cdata[BCRYPT_BLOCKS];
210
211 /* Discard "$" identifier */
212 salt++;
213
214 if (*salt > BCRYPT_VERSION) {
215 /* How do I handle errors ? Return ':' */
216 return error;
217 }
218
219 /* Check for minor versions */
220 if (salt[1] != '$') {
221 switch (salt[1]) {
222 case 'a':
223 /* 'ab' should not yield the same as 'abab' */
224 minor = salt[1];
225 salt++;
226 break;
227 default:
228 return error;
229 }
230 } else
231 minor = 0;
232
233 /* Discard version + "$" identifier */
234 salt += 2;
235
236 if (salt[2] != '$')
237 /* Out of sync with passwd entry */
238 return error;
239
240 /* Computer power doesnt increase linear, 2^x should be fine */
241 if ((rounds = (u_int32_t) 1 << (logr = atoi(salt))) < BCRYPT_MINROUNDS)
242 return error;
243
244 /* Discard num rounds + "$" identifier */
245 salt += 3;
246
247 /* We dont want the base64 salt but the raw data */
248 decode_base64(csalt, BCRYPT_MAXSALT, (u_int8_t *) salt);
249 salt_len = BCRYPT_MAXSALT;
250 key_len = strlen(key) + (minor >= 'a' ? 1 : 0);
251
252 /* Setting up S-Boxes and Subkeys */
253 Blowfish_initstate(&state);
254 Blowfish_expandstate(&state, csalt, salt_len,
255 (u_int8_t *) key, key_len);
256 for (k = 0; k < rounds; k++) {
257 Blowfish_expand0state(&state, (u_int8_t *) key, key_len);
258 Blowfish_expand0state(&state, csalt, salt_len);
259 }
260
261 /* This can be precomputed later */
262 j = 0;
263 for (i = 0; i < BCRYPT_BLOCKS; i++)
264 cdata[i] = Blowfish_stream2word(ciphertext, 4 * BCRYPT_BLOCKS, &j);
265
266 /* Now do the encryption */
267 for (k = 0; k < 64; k++)
268 blf_enc(&state, cdata, BCRYPT_BLOCKS / 2);
269
270 for (i = 0; i < BCRYPT_BLOCKS; i++) {
271 ciphertext[4 * i + 3] = cdata[i] & 0xff;
272 cdata[i] = cdata[i] >> 8;
273 ciphertext[4 * i + 2] = cdata[i] & 0xff;
274 cdata[i] = cdata[i] >> 8;
275 ciphertext[4 * i + 1] = cdata[i] & 0xff;
276 cdata[i] = cdata[i] >> 8;
277 ciphertext[4 * i + 0] = cdata[i] & 0xff;
278 }
279
280
281 i = 0;
282 encrypted[i++] = '$';
283 encrypted[i++] = BCRYPT_VERSION;
284 if (minor)
285 encrypted[i++] = minor;
286 encrypted[i++] = '$';
287
288 snprintf(encrypted + i, 4, "%2.2u$", logr);
289
290 encode_base64((u_int8_t *) encrypted + i + 3, csalt, BCRYPT_MAXSALT);
291 encode_base64((u_int8_t *) encrypted + strlen(encrypted), ciphertext,
292 4 * BCRYPT_BLOCKS - 1);
293 return encrypted;
294}
295
296#ifdef __STDC__
297static void
298encode_base64(u_int8_t *buffer, u_int8_t *data, u_int16_t len)
299#else
300static void
301encode_base64(buffer, data, len)
302 u_int8_t *buffer;
303 u_int8_t *data;
304 u_int16_t len;
305#endif
306{
307 u_int8_t *bp = buffer;
308 u_int8_t *p = data;
309 u_int8_t c1, c2;
310 while (p < data + len) {
311 c1 = *p++;
312 *bp++ = Base64Code[(c1 >> 2)];
313 c1 = (c1 & 0x03) << 4;
314 if (p >= data + len) {
315 *bp++ = Base64Code[c1];
316 break;
317 }
318 c2 = *p++;
319 c1 |= (c2 >> 4) & 0x0f;
320 *bp++ = Base64Code[c1];
321 c1 = (c2 & 0x0f) << 2;
322 if (p >= data + len) {
323 *bp++ = Base64Code[c1];
324 break;
325 }
326 c2 = *p++;
327 c1 |= (c2 >> 6) & 0x03;
328 *bp++ = Base64Code[c1];
329 *bp++ = Base64Code[c2 & 0x3f];
330 }
331 *bp = '\0';
332}
333#if 0
334void
335main()
336{
337 char blubber[73];
338 char salt[100];
339 char *p;
340 salt[0] = '$';
341 salt[1] = BCRYPT_VERSION;
342 salt[2] = '$';
343
344 snprintf(salt + 3, 4, "%2.2u$", 5);
345
346 printf("24 bytes of salt: ");
347 fgets(salt + 6, 94, stdin);
348 salt[99] = 0;
349 printf("72 bytes of password: ");
350 fpurge(stdin);
351 fgets(blubber, 73, stdin);
352 blubber[72] = 0;
353
354 p = crypt(blubber, salt);
355 printf("Passwd entry: %s\n\n", p);
356
357 p = bcrypt_gensalt(5);
358 printf("Generated salt: %s\n", p);
359 p = crypt(blubber, p);
360 printf("Passwd entry: %s\n", p);
361}
362#endif
diff --git a/src/lib/libc/crypt/blowfish.3 b/src/lib/libc/crypt/blowfish.3
new file mode 100644
index 0000000000..02a1ef8738
--- /dev/null
+++ b/src/lib/libc/crypt/blowfish.3
@@ -0,0 +1,104 @@
1.\" $OpenBSD: blowfish.3,v 1.2 1998/08/10 18:40:58 provos Exp $
2.\" Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
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 Niels Provos.
16.\" 4. The name of the author may not be used to endorse or promote products
17.\" derived from this software without specific prior written permission.
18.\"
19.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29.\"
30.\" Manual page, using -mandoc macros
31.\"
32.Dd February 13, 1997
33.Dt BLOWFISH 3
34.Os "OpenBSD 2.0"
35.Sh NAME
36.Nm blf_key,
37.Nm blf_enc,
38.Nm blf_dec
39.Nd Blowfish encryption
40.Sh SYNOPSIS
41.Fd #include <blf.h>
42.Ft void
43.Fn blf_key "blf_ctx *state" "const u_int8_t *key" "u_int16_t keylen"
44.Ft void
45.Fn blf_enc "blf_ctx *state" "u_int32_t *data" "u_int16_t datalen"
46.Ft void
47.Fn blf_dec "blf_ctx *state" "u_int32_t *data" "u_int16_t datalen"
48.Ft void
49.Fn blf_ecb_encrypt "blf_ctx *state" "u_int8_t *data" "u_int32_t datalen"
50.Ft void
51.Fn blf_ecb_decrypt "blf_ctx *state" "u_int8_t *data" "u_int32_t datalen"
52.Ft void
53.Fn blf_cbc_encrypt "blf_ctx *state" "u_int8_t *iv" "u_int8_t *data" "u_int32_t datalen"
54.Ft void
55.Fn blf_cbc_decrypt "blf_ctx *state" "u_int8_t *iv" "u_int8_t *data" "u_int32_t datalen"
56.Sh DESCRIPTION
57.Pa Blowfish
58is a fast unpatented block cipher designed by Bruce Schneier.
59It basically consists of a 16 times iterated Feistel network.
60The block size is 64 bit and the key size is maximal 448 bit.
61.Pp
62The
63.Fn blf_key
64function initializes the 4 8bit S-boxes and the 18 Subkeys with
65the hexadecimal digits of Pi. The key is used for further randomization.
66The first argument to
67.Fn blf_enc
68is the initalized state derived from
69.Fn blf_key .
70The stream of 32-bit words is encrypted in Electronic Codebook
71Mode (ECB) and
72.Pa datalen
73must be even.
74.Fn blf_dec
75is used for decrypting Blowfish encrypted blocks.
76.Pp
77The functions
78.Fn blf_ecb_encrypt
79and
80.Fn blf_ecb_decrypt
81are used for encrypting and decrypting octet streams in ECB mode.
82The functions
83.Fn blf_cbc_encrypt
84and
85.Fn blf_cbc_decrypt
86are used for encrypting and decrypting octet streams in
87Cipherblock Chaining Mode (CBC).
88.Pp
89The functions
90.Fn Blowfish_initstate ,
91.Fn Blowfish_expand0state ,
92.Fn Blowfish_expandstate ,
93.Fn Blowfish_encipher
94and
95.Fn Blowfish_decipher
96are used for customization of the
97.Pa Blowfish
98cipher, e.g. for the blowfish password hashing function.
99.Sh SEE ALSO
100.Xr crypt 3 ,
101.Xr passwd 1 ,
102.Xr passwd 5
103.Sh AUTHOR
104Niels Provos <provos@physnet.uni-hamburg.de>
diff --git a/src/lib/libc/crypt/blowfish.c b/src/lib/libc/crypt/blowfish.c
new file mode 100644
index 0000000000..6cddbc64b3
--- /dev/null
+++ b/src/lib/libc/crypt/blowfish.c
@@ -0,0 +1,774 @@
1/* $OpenBSD: blowfish.c,v 1.12 1998/08/30 22:35:39 niklas 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(bc, x) ((((bc)->S[0][((x) & 0xFF000000) >> 24] \
60 + (bc)->S[1][((x) &0xFF0000 ) >> 16]) \
61 ^ (bc)->S[2][((x) & 0xFF00) >> 8]) \
62 + (bc)->S[3][(x) & 0x00FF])
63
64#define BLFRND(bc,i,j,n) (i ^= F(bc,j) ^ (bc)->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
75 Xl = *xl;
76 Xr = *xr;
77
78 Xl ^= c->P[0];
79 BLFRND(c, Xr, Xl, 1); BLFRND(c, Xl, Xr, 2);
80 BLFRND(c, Xr, Xl, 3); BLFRND(c, Xl, Xr, 4);
81 BLFRND(c, Xr, Xl, 5); BLFRND(c, Xl, Xr, 6);
82 BLFRND(c, Xr, Xl, 7); BLFRND(c, Xl, Xr, 8);
83 BLFRND(c, Xr, Xl, 9); BLFRND(c, Xl, Xr, 10);
84 BLFRND(c, Xr, Xl, 11); BLFRND(c, Xl, Xr, 12);
85 BLFRND(c, Xr, Xl, 13); BLFRND(c, Xl, Xr, 14);
86 BLFRND(c, Xr, Xl, 15); BLFRND(c, Xl, Xr, 16);
87
88 *xl = Xr ^ c->P[17];
89 *xr = Xl;
90}
91
92void
93Blowfish_decipher(c, xl, xr)
94 blf_ctx *c;
95 u_int32_t *xl;
96 u_int32_t *xr;
97{
98 u_int32_t Xl;
99 u_int32_t Xr;
100
101 Xl = *xl;
102 Xr = *xr;
103
104 Xl ^= c->P[17];
105 BLFRND(c, Xr, Xl, 16); BLFRND(c, Xl, Xr, 15);
106 BLFRND(c, Xr, Xl, 14); BLFRND(c, Xl, Xr, 13);
107 BLFRND(c, Xr, Xl, 12); BLFRND(c, Xl, Xr, 11);
108 BLFRND(c, Xr, Xl, 10); BLFRND(c, Xl, Xr, 9);
109 BLFRND(c, Xr, Xl, 8); BLFRND(c, Xl, Xr, 7);
110 BLFRND(c, Xr, Xl, 6); BLFRND(c, Xl, Xr, 5);
111 BLFRND(c, Xr, Xl, 4); BLFRND(c, Xl, Xr, 3);
112 BLFRND(c, Xr, Xl, 2); BLFRND(c, Xl, Xr, 1);
113
114 *xl = Xr ^ c->P[0];
115 *xr = Xl;
116}
117
118void
119Blowfish_initstate(c)
120 blf_ctx *c;
121{
122
123/* P-box and S-box tables initialized with digits of Pi */
124
125 const blf_ctx initstate =
126
127 { {
128 {
129 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
130 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
131 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
132 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
133 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
134 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
135 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
136 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
137 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
138 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
139 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
140 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
141 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
142 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
143 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
144 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
145 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
146 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
147 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
148 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
149 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
150 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
151 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
152 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
153 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
154 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
155 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
156 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
157 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
158 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
159 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
160 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
161 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
162 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
163 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
164 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
165 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
166 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
167 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
168 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
169 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
170 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
171 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
172 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
173 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
174 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
175 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
176 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
177 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
178 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
179 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
180 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
181 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
182 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
183 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
184 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
185 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
186 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
187 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
188 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
189 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
190 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
191 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
192 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a},
193 {
194 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
195 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
196 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
197 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
198 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
199 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
200 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
201 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
202 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
203 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
204 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
205 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
206 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
207 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
208 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
209 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
210 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
211 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
212 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
213 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
214 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
215 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
216 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
217 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
218 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
219 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
220 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
221 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
222 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
223 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
224 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
225 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
226 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
227 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
228 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
229 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
230 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
231 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
232 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
233 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
234 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
235 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
236 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
237 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
238 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
239 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
240 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
241 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
242 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
243 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
244 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
245 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
246 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
247 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
248 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
249 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
250 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
251 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
252 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
253 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
254 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
255 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
256 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
257 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7},
258 {
259 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
260 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
261 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
262 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
263 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
264 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
265 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
266 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
267 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
268 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
269 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
270 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
271 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
272 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
273 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
274 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
275 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
276 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
277 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
278 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
279 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
280 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
281 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
282 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
283 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
284 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
285 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
286 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
287 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
288 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
289 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
290 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
291 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
292 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
293 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
294 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
295 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
296 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
297 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
298 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
299 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
300 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
301 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
302 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
303 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
304 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
305 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
306 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
307 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
308 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
309 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
310 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
311 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
312 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
313 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
314 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
315 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
316 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
317 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
318 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
319 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
320 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
321 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
322 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0},
323 {
324 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
325 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
326 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
327 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
328 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
329 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
330 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
331 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
332 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
333 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
334 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
335 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
336 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
337 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
338 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
339 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
340 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
341 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
342 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
343 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
344 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
345 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
346 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
347 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
348 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
349 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
350 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
351 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
352 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
353 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
354 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
355 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
356 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
357 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
358 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
359 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
360 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
361 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
362 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
363 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
364 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
365 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
366 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
367 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
368 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
369 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
370 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
371 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
372 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
373 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
374 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
375 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
376 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
377 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
378 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
379 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
380 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
381 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
382 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
383 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
384 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
385 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
386 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
387 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6}
388 },
389 {
390 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
391 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
392 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
393 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
394 0x9216d5d9, 0x8979fb1b
395 } };
396
397 *c = initstate;
398
399}
400
401#ifdef __STDC__
402u_int32_t
403Blowfish_stream2word(const u_int8_t *data, u_int16_t databytes, u_int16_t *current)
404#else
405u_int32_t
406Blowfish_stream2word(data, databytes, current)
407 const u_int8_t *data;
408 u_int16_t databytes;
409 u_int16_t *current;
410#endif
411{
412 u_int8_t i;
413 u_int16_t j;
414 u_int32_t temp;
415
416 temp = 0x00000000;
417 j = *current;
418
419 for (i = 0; i < 4; i++, j++) {
420 if (j >= databytes)
421 j = 0;
422 temp = (temp << 8) | data[j];
423 }
424
425 *current = j;
426 return temp;
427}
428
429#if __STDC__
430void
431Blowfish_expand0state(blf_ctx *c, const u_int8_t *key, u_int16_t keybytes)
432#else
433void
434Blowfish_expand0state(c, key, keybytes)
435 blf_ctx *c;
436 const u_int8_t *key;
437 u_int16_t keybytes;
438#endif
439{
440 u_int16_t i;
441 u_int16_t j;
442 u_int16_t k;
443 u_int32_t temp;
444 u_int32_t datal;
445 u_int32_t datar;
446
447 j = 0;
448 for (i = 0; i < BLF_N + 2; i++) {
449 /* Extract 4 int8 to 1 int32 from keystream */
450 temp = Blowfish_stream2word(key, keybytes, &j);
451 c->P[i] = c->P[i] ^ temp;
452 }
453
454 j = 0;
455 datal = 0x00000000;
456 datar = 0x00000000;
457 for (i = 0; i < BLF_N + 2; i += 2) {
458 Blowfish_encipher(c, &datal, &datar);
459
460 c->P[i] = datal;
461 c->P[i + 1] = datar;
462 }
463
464 for (i = 0; i < 4; i++) {
465 for (k = 0; k < 256; k += 2) {
466 Blowfish_encipher(c, &datal, &datar);
467
468 c->S[i][k] = datal;
469 c->S[i][k + 1] = datar;
470 }
471 }
472}
473
474
475#if __STDC__
476void
477Blowfish_expandstate(blf_ctx *c, const u_int8_t *data, u_int16_t databytes,
478 const u_int8_t *key, u_int16_t keybytes)
479#else
480void
481Blowfish_expandstate(c, data, databytes, key, keybytes)
482 blf_ctx *c;
483 const u_int8_t *data;
484 u_int16_t databytes;
485 const u_int8_t *key;
486 u_int16_t keybytes;
487#endif
488{
489 u_int16_t i;
490 u_int16_t j;
491 u_int16_t k;
492 u_int32_t temp;
493 u_int32_t datal;
494 u_int32_t datar;
495
496 j = 0;
497 for (i = 0; i < BLF_N + 2; i++) {
498 /* Extract 4 int8 to 1 int32 from keystream */
499 temp = Blowfish_stream2word(key, keybytes, &j);
500 c->P[i] = c->P[i] ^ temp;
501 }
502
503 j = 0;
504 datal = 0x00000000;
505 datar = 0x00000000;
506 for (i = 0; i < BLF_N + 2; i += 2) {
507 datal ^= Blowfish_stream2word(data, databytes, &j);
508 datar ^= Blowfish_stream2word(data, databytes, &j);
509 Blowfish_encipher(c, &datal, &datar);
510
511 c->P[i] = datal;
512 c->P[i + 1] = datar;
513 }
514
515 for (i = 0; i < 4; i++) {
516 for (k = 0; k < 256; k += 2) {
517 datal ^= Blowfish_stream2word(data, databytes, &j);
518 datar ^= Blowfish_stream2word(data, databytes, &j);
519 Blowfish_encipher(c, &datal, &datar);
520
521 c->S[i][k] = datal;
522 c->S[i][k + 1] = datar;
523 }
524 }
525
526}
527
528#if __STDC__
529void
530blf_key(blf_ctx *c, const u_int8_t *k, u_int16_t len)
531#else
532void
533blf_key(c, k, len)
534 blf_ctx *c;
535 const u_int8_t *k;
536 u_int16_t len;
537#endif
538{
539 /* Initalize S-boxes and subkeys with Pi */
540 Blowfish_initstate(c);
541
542 /* Transform S-boxes and subkeys with key */
543 Blowfish_expand0state(c, k, len);
544}
545
546#if __STDC__
547void
548blf_enc(blf_ctx *c, u_int32_t *data, u_int16_t blocks)
549#else
550void
551blf_enc(c, data, blocks)
552 blf_ctx *c;
553 u_int32_t *data;
554 u_int16_t blocks;
555#endif
556{
557 u_int32_t *d;
558 u_int16_t i;
559
560 d = data;
561 for (i = 0; i < blocks; i++) {
562 Blowfish_encipher(c, d, d + 1);
563 d += 2;
564 }
565}
566
567#if __STDC__
568void
569blf_dec(blf_ctx *c, u_int32_t *data, u_int16_t blocks)
570#else
571void
572blf_dec(c, data, blocks)
573 blf_ctx *c;
574 u_int32_t *data;
575 u_int16_t blocks;
576#endif
577{
578 u_int32_t *d;
579 u_int16_t i;
580
581 d = data;
582 for (i = 0; i < blocks; i++) {
583 Blowfish_decipher(c, d, d + 1);
584 d += 2;
585 }
586}
587
588#if __STDC__
589void
590blf_ecb_encrypt(blf_ctx *c, u_int8_t *data, u_int32_t len)
591#else
592void
593blf_ecb_encrypt(c, data, len)
594 blf_ctx *c;
595 u_int8_t *data;
596 u_int32_t len;
597#endif
598{
599 u_int32_t l, r;
600 u_int32_t i;
601
602 for (i = 0; i < len; i += 8) {
603 l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
604 r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
605 Blowfish_encipher(c, &l, &r);
606 data[0] = l >> 24 & 0xff;
607 data[1] = l >> 16 & 0xff;
608 data[2] = l >> 8 & 0xff;
609 data[3] = l & 0xff;
610 data[4] = r >> 24 & 0xff;
611 data[5] = r >> 16 & 0xff;
612 data[6] = r >> 8 & 0xff;
613 data[7] = r & 0xff;
614 data += 8;
615 }
616}
617
618#if __STDC__
619void
620blf_ecb_decrypt(blf_ctx *c, u_int8_t *data, u_int32_t len)
621#else
622void
623blf_ecb_decrypt(c, data, len)
624 blf_ctx *c;
625 u_int8_t *data;
626 u_int32_t len;
627#endif
628{
629 u_int32_t l, r;
630 u_int32_t i;
631
632 for (i = 0; i < len; i += 8) {
633 l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
634 r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
635 Blowfish_decipher(c, &l, &r);
636 data[0] = l >> 24 & 0xff;
637 data[1] = l >> 16 & 0xff;
638 data[2] = l >> 8 & 0xff;
639 data[3] = l & 0xff;
640 data[4] = r >> 24 & 0xff;
641 data[5] = r >> 16 & 0xff;
642 data[6] = r >> 8 & 0xff;
643 data[7] = r & 0xff;
644 data += 8;
645 }
646}
647
648#if __STDC__
649void
650blf_cbc_encrypt(blf_ctx *c, u_int8_t *iv, u_int8_t *data, u_int32_t len)
651#else
652void
653blf_cbc_encrypt(c, iv, data, len)
654 blf_ctx *c;
655 u_int8_t *iv;
656 u_int8_t *data;
657 u_int32_t len;
658#endif
659{
660 u_int32_t l, r;
661 u_int32_t i, j;
662
663 for (i = 0; i < len; i += 8) {
664 for (j = 0; j < 8; j++)
665 data[j] ^= iv[j];
666 l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
667 r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
668 Blowfish_encipher(c, &l, &r);
669 data[0] = l >> 24 & 0xff;
670 data[1] = l >> 16 & 0xff;
671 data[2] = l >> 8 & 0xff;
672 data[3] = l & 0xff;
673 data[4] = r >> 24 & 0xff;
674 data[5] = r >> 16 & 0xff;
675 data[6] = r >> 8 & 0xff;
676 data[7] = r & 0xff;
677 iv = data;
678 data += 8;
679 }
680}
681
682#if __STDC__
683void
684blf_cbc_decrypt(blf_ctx *c, u_int8_t *iva, u_int8_t *data, u_int32_t len)
685#else
686void
687blf_cbc_decrypt(c, iva, data, len)
688 blf_ctx *c;
689 u_int8_t *iva;
690 u_int8_t *data;
691 u_int32_t len;
692#endif
693{
694 u_int32_t l, r;
695 u_int8_t *iv;
696 u_int32_t i, j;
697
698 iv = data + len - 16;
699 data = data + len - 8;
700 for (i = len - 8; i >= 8; i -= 8) {
701 l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
702 r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
703 Blowfish_decipher(c, &l, &r);
704 data[0] = l >> 24 & 0xff;
705 data[1] = l >> 16 & 0xff;
706 data[2] = l >> 8 & 0xff;
707 data[3] = l & 0xff;
708 data[4] = r >> 24 & 0xff;
709 data[5] = r >> 16 & 0xff;
710 data[6] = r >> 8 & 0xff;
711 data[7] = r & 0xff;
712 for (j = 0; j < 8; j++)
713 data[j] ^= iv[j];
714 iv = data;
715 data -= 8;
716 }
717 l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
718 r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
719 Blowfish_decipher(c, &l, &r);
720 data[0] = l >> 24 & 0xff;
721 data[1] = l >> 16 & 0xff;
722 data[2] = l >> 8 & 0xff;
723 data[3] = l & 0xff;
724 data[4] = r >> 24 & 0xff;
725 data[5] = r >> 16 & 0xff;
726 data[6] = r >> 8 & 0xff;
727 data[7] = r & 0xff;
728 for (j = 0; j < 8; j++)
729 data[j] ^= iva[j];
730}
731
732#if 0
733void
734report(u_int32_t data[], u_int16_t len)
735{
736 u_int16_t i;
737 for (i = 0; i < len; i += 2)
738 printf("Block %0hd: %08lx %08lx.\n",
739 i / 2, data[i], data[i + 1]);
740}
741void
742main(void)
743{
744
745 blf_ctx c;
746 char key[] = "AAAAA";
747 char key2[] = "abcdefghijklmnopqrstuvwxyz";
748
749 u_int32_t data[10];
750 u_int32_t data2[] =
751 {0x424c4f57l, 0x46495348l};
752
753 u_int16_t i;
754
755 /* First test */
756 for (i = 0; i < 10; i++)
757 data[i] = i;
758
759 blf_key(&c, (u_int8_t *) key, 5);
760 blf_enc(&c, data, 5);
761 blf_dec(&c, data, 1);
762 blf_dec(&c, data + 2, 4);
763 printf("Should read as 0 - 9.\n");
764 report(data, 10);
765
766 /* Second test */
767 blf_key(&c, (u_int8_t *) key2, strlen(key2));
768 blf_enc(&c, data2, 1);
769 printf("\nShould read as: 0x324ed0fe 0xf413a203.\n");
770 report(data2, 2);
771 blf_dec(&c, data2, 1);
772 report(data2, 2);
773}
774#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..524645de55
--- /dev/null
+++ b/src/lib/libc/crypt/crypt.3
@@ -0,0 +1,298 @@
1.\" $OpenBSD: crypt.3,v 1.11 1998/02/27 12:17:45 deraadt Exp $
2.\"
3.\" FreeSec: libcrypt
4.\"
5.\" Copyright (c) 1994 David Burren
6.\" All rights reserved.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 4. Neither the name of the author nor the names of other contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" Manual page, using -mandoc macros
33.\"
34.Dd March 9, 1994
35.Dt CRYPT 3
36.Os
37.Sh NAME
38.Nm crypt ,
39.Nm setkey ,
40.Nm encrypt ,
41.Nm des_setkey ,
42.Nm des_cipher
43.Nd DES encryption
44.Sh SYNOPSIS
45.Fd #include <unistd.h>
46.Ft char
47.Fn *crypt "const char *key" "const char *setting"
48.Ft int
49.Fn setkey "char *key"
50.Ft int
51.Fn encrypt "char *block" "int flag"
52.Ft int
53.Fn des_setkey "const char *key"
54.Ft int
55.Fn des_cipher "const char *in" "char *out" "int32_t salt" "int count"
56.Sh DESCRIPTION
57The
58.Fn crypt
59function performs password encryption, based on the
60.Tn NBS
61Data Encryption Standard (DES).
62Additional code has been added to deter key search attempts and to use
63stronger hashing algorithms.
64The first argument to
65.Fn crypt
66is a
67.Dv null Ns -terminated
68string, typically a user's typed password.
69The second is in one of three forms:
70if it begins with an underscore (``_'') then an extended format is used
71in interpreting both the key and the setting, as outlined below. If it begins
72with an string character (``$'') and a number then a different algorithm
73is used depending on the number. At the moment a ``$1'' chooses MD5 hashing
74and a ``$2'' chooses Blowfish hashing, see below for more information.
75.Ss Extended crypt:
76.Pp
77The
78.Ar key
79is divided into groups of 8 characters (the last group is null-padded)
80and the low-order 7 bits of each each character (56 bits per group) are
81used to form the DES key as follows:
82the first group of 56 bits becomes the initial DES key.
83For each additional group, the XOR of the encryption of the current DES
84key with itself and the group bits becomes the next DES key.
85.Pp
86The setting is a 9-character array consisting of an underscore followed
87by 4 bytes of iteration count and 4 bytes of salt.
88These are encoded as printable characters, 6 bits per character,
89least significant character first.
90The values 0 to 63 are encoded as ``./0-9A-Za-z''.
91This allows 24 bits for both
92.Fa count
93and
94.Fa salt .
95.Ss "MD5" crypt:
96.Pp
97For
98.Tn MD5
99crypt the version number,
100.Fa salt
101and the hashed password are separated
102by the ``$'' character. The maximum length of a password is limited by
103the length counter of the MD5 context, which is about
1042**64. A valid MD5 password entry looks like this:
105.Pp
106``$1$caeiHQwX$hsKqOjrFRRN6K32OWkCBf1''.
107.Pp
108The whole MD5 password string is passed as
109.Fa setting
110for interpretation.
111.Ss "Blowfish" crypt:
112.Pp
113The
114.Tn Blowfish
115version of crypt has 128 bits of
116.Fa salt
117in order to make building
118dictionaries of common passwords space consuming. The initial state
119of the
120.Tn Blowfish
121cipher is expanded using the
122.Fa salt
123and the
124.Fa password
125repeating the process a variable number of rounds, which is encoded in
126the password string. The maximum password length is 72. The final Blowfish
127password entry is created by encrypting
128the string ``OrpheanBeholderScryDoubt'' with the
129.Tn Blowfish
130state 64 times.
131.Pp
132The version number, the logarithm of the number of rounds and
133the concatenation of salt and
134hashed password are separated by the ``$'' character. An encoded ``8''
135would specify 256 rounds.
136A valid Blowfish password looks like this:
137.Pp
138``$2a$12$eIAq8PR8sIUnJ1HaohxX2O9x9Qlm2vK97LJ5dsXdmB.eXF42qjchC''.
139.Pp
140The whole Blowfish password string is passed as
141.Fa setting
142for interpretation.
143.Ss "Traditional" crypt:
144.Pp
145The first 8 bytes of the key are null-padded, and the low-order 7 bits of
146each character is used to form the 56-bit
147.Tn DES
148key.
149.Pp
150The setting is a 2-character array of the ASCII-encoded salt.
151Thus only 12 bits of
152.Fa salt
153are used.
154.Fa count
155is set to 25.
156.Ss DES Algorithm:
157.Pp
158The
159.Fa salt
160introduces disorder in the
161.Tn DES
162algorithm in one of 16777216 or 4096 possible ways
163(ie. with 24 or 12 bits: if bit
164.Em i
165of the
166.Ar salt
167is set, then bits
168.Em i
169and
170.Em i+24
171are swapped in the
172.Tn DES
173E-box output).
174.Pp
175The DES key is used to encrypt a 64-bit constant using
176.Ar count
177iterations of
178.Tn DES .
179The value returned is a
180.Dv null Ns -terminated
181string, 20 or 13 bytes (plus null) in length, consisting of the
182.Ar setting
183followed by the encoded 64-bit encryption.
184.Pp
185The functions,
186.Fn encrypt ,
187.Fn setkey ,
188.Fn des_setkey
189and
190.Fn des_cipher
191provide access to the
192.Tn DES
193algorithm itself.
194.Fn setkey
195is passed a 64-byte array of binary values (numeric 0 or 1).
196A 56-bit key is extracted from this array by dividing the
197array into groups of 8, and ignoring the last bit in each group.
198That bit is reserved for a byte parity check by DES, but is ignored
199by these functions.
200.Pp
201The
202.Fa block
203argument to
204.Fn encrypt
205is also a 64-byte array of binary values.
206If the value of
207.Fa flag
208is 0,
209.Fa block
210is encrypted otherwise it is decrypted.
211The result is returned in the original array
212.Fa block
213after using the key specified by
214.Fn setkey
215to process it.
216.Pp
217The argument to
218.Fn des_setkey
219is a character array of length 8.
220The least significant bit (the parity bit) in each character is ignored,
221and the remaining bits are concatenated to form a 56-bit key.
222The function
223.Fn des_cipher
224encrypts (or decrypts if
225.Fa count
226is negative) the 64-bits stored in the 8 characters at
227.Fa in
228using
229.Xr abs 3
230of
231.Fa count
232iterations of
233.Tn DES
234and stores the 64-bit result in the 8 characters at
235.Fa out
236(which may be the same as
237.Fa in
238).
239The
240.Fa salt
241specifies perturbations to the
242.Tn DES
243E-box output as described above.
244.Pp
245The function
246.Fn crypt
247returns a pointer to the encrypted value on success, and NULL on failure.
248The functions
249.Fn setkey ,
250.Fn encrypt ,
251.Fn des_setkey ,
252and
253.Fn des_cipher
254return 0 on success and 1 on failure.
255.Pp
256The
257.Fn crypt ,
258.Fn setkey
259and
260.Fn des_setkey
261functions all manipulate the same key space.
262.Sh SEE ALSO
263.Xr login 1 ,
264.Xr passwd 1 ,
265.Xr blowfish 3 ,
266.Xr getpass 3 ,
267.Xr md5 3 ,
268.Xr passwd 5
269.Sh BUGS
270The
271.Fn crypt
272function returns a pointer to static data, and subsequent calls to
273.Fn crypt
274will modify the same object.
275.Sh HISTORY
276A rotor-based
277.Fn crypt
278function appeared in
279.At v6 .
280The current style
281.Fn crypt
282first appeared in
283.At v7 .
284.Pp
285This library (FreeSec 1.0) was developed outside the United States of America
286as an unencumbered replacement for the U.S.-only libcrypt encryption
287library.
288Programs linked against the
289.Fn crypt
290interface may be exported from the U.S.A. only if they use
291.Fn crypt
292solely for authentication purposes and avoid use of
293the other programmer interfaces listed above. Special care has been taken
294in the library so that programs which only use the
295.Fn crypt
296interface do not pull in the other components.
297.Sh AUTHOR
298David Burren <davidb@werj.com.au>
diff --git a/src/lib/libc/crypt/crypt.c b/src/lib/libc/crypt/crypt.c
new file mode 100644
index 0000000000..8fd319a4f3
--- /dev/null
+++ b/src/lib/libc/crypt/crypt.c
@@ -0,0 +1,714 @@
1/* $OpenBSD: crypt.c,v 1.13 1998/03/22 19:01:18 niklas Exp $ */
2
3/*
4 * FreeSec: libcrypt
5 *
6 * Copyright (c) 1994 David Burren
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 4. Neither the name of the author nor the names of other contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 *
34 * This is an original implementation of the DES and the crypt(3) interfaces
35 * by David Burren <davidb@werj.com.au>.
36 *
37 * An excellent reference on the underlying algorithm (and related
38 * algorithms) is:
39 *
40 * B. Schneier, Applied Cryptography: protocols, algorithms,
41 * and source code in C, John Wiley & Sons, 1994.
42 *
43 * Note that in that book's description of DES the lookups for the initial,
44 * pbox, and final permutations are inverted (this has been brought to the
45 * attention of the author). A list of errata for this book has been
46 * posted to the sci.crypt newsgroup by the author and is available for FTP.
47 *
48 * NOTE:
49 * This file has a static version of des_setkey() so that crypt.o exports
50 * only the crypt() interface. This is required to make binaries linked
51 * against crypt.o exportable or re-exportable from the USA.
52 */
53
54#if defined(LIBC_SCCS) && !defined(lint)
55static char rcsid[] = "$OpenBSD: crypt.c,v 1.13 1998/03/22 19:01:18 niklas Exp $";
56#endif /* LIBC_SCCS and not lint */
57
58#include <sys/types.h>
59#include <sys/param.h>
60#include <pwd.h>
61#include <string.h>
62
63#ifdef DEBUG
64# include <stdio.h>
65#endif
66
67static u_char IP[64] = {
68 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,
69 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,
70 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3,
71 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7
72};
73
74static u_char inv_key_perm[64];
75static u_char u_key_perm[56];
76static u_char key_perm[56] = {
77 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18,
78 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36,
79 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22,
80 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4
81};
82
83static u_char key_shifts[16] = {
84 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
85};
86
87static u_char inv_comp_perm[56];
88static u_char comp_perm[48] = {
89 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10,
90 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2,
91 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,
92 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32
93};
94
95/*
96 * No E box is used, as it's replaced by some ANDs, shifts, and ORs.
97 */
98
99static u_char u_sbox[8][64];
100static u_char sbox[8][64] = {
101 {
102 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
103 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
104 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
105 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13
106 },
107 {
108 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
109 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
110 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
111 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9
112 },
113 {
114 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
115 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
116 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
117 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12
118 },
119 {
120 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
121 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
122 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
123 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14
124 },
125 {
126 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
127 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
128 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
129 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3
130 },
131 {
132 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
133 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
134 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
135 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13
136 },
137 {
138 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
139 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
140 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
141 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12
142 },
143 {
144 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
145 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
146 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
147 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
148 }
149};
150
151static u_char un_pbox[32];
152static u_char pbox[32] = {
153 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,
154 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25
155};
156
157static u_int32_t bits32[32] =
158{
159 0x80000000, 0x40000000, 0x20000000, 0x10000000,
160 0x08000000, 0x04000000, 0x02000000, 0x01000000,
161 0x00800000, 0x00400000, 0x00200000, 0x00100000,
162 0x00080000, 0x00040000, 0x00020000, 0x00010000,
163 0x00008000, 0x00004000, 0x00002000, 0x00001000,
164 0x00000800, 0x00000400, 0x00000200, 0x00000100,
165 0x00000080, 0x00000040, 0x00000020, 0x00000010,
166 0x00000008, 0x00000004, 0x00000002, 0x00000001
167};
168
169static u_char bits8[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
170
171static u_int32_t saltbits;
172static int32_t old_salt;
173static u_int32_t *bits28, *bits24;
174static u_char init_perm[64], final_perm[64];
175static u_int32_t en_keysl[16], en_keysr[16];
176static u_int32_t de_keysl[16], de_keysr[16];
177static int des_initialised = 0;
178static u_char m_sbox[4][4096];
179static u_int32_t psbox[4][256];
180static u_int32_t ip_maskl[8][256], ip_maskr[8][256];
181static u_int32_t fp_maskl[8][256], fp_maskr[8][256];
182static u_int32_t key_perm_maskl[8][128], key_perm_maskr[8][128];
183static u_int32_t comp_maskl[8][128], comp_maskr[8][128];
184static u_int32_t old_rawkey0, old_rawkey1;
185
186static u_char ascii64[] =
187 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
188/* 0000000000111111111122222222223333333333444444444455555555556666 */
189/* 0123456789012345678901234567890123456789012345678901234567890123 */
190
191static __inline int
192ascii_to_bin(ch)
193 char ch;
194{
195 if (ch > 'z')
196 return(0);
197 if (ch >= 'a')
198 return(ch - 'a' + 38);
199 if (ch > 'Z')
200 return(0);
201 if (ch >= 'A')
202 return(ch - 'A' + 12);
203 if (ch > '9')
204 return(0);
205 if (ch >= '.')
206 return(ch - '.');
207 return(0);
208}
209
210static void
211des_init()
212{
213 int i, j, b, k, inbit, obit;
214 u_int32_t *p, *il, *ir, *fl, *fr;
215
216 old_rawkey0 = old_rawkey1 = 0;
217 saltbits = 0;
218 old_salt = 0;
219 bits24 = (bits28 = bits32 + 4) + 4;
220
221 /*
222 * Invert the S-boxes, reordering the input bits.
223 */
224 for (i = 0; i < 8; i++)
225 for (j = 0; j < 64; j++) {
226 b = (j & 0x20) | ((j & 1) << 4) | ((j >> 1) & 0xf);
227 u_sbox[i][j] = sbox[i][b];
228 }
229
230 /*
231 * Convert the inverted S-boxes into 4 arrays of 8 bits.
232 * Each will handle 12 bits of the S-box input.
233 */
234 for (b = 0; b < 4; b++)
235 for (i = 0; i < 64; i++)
236 for (j = 0; j < 64; j++)
237 m_sbox[b][(i << 6) | j] =
238 (u_sbox[(b << 1)][i] << 4) |
239 u_sbox[(b << 1) + 1][j];
240
241 /*
242 * Set up the initial & final permutations into a useful form, and
243 * initialise the inverted key permutation.
244 */
245 for (i = 0; i < 64; i++) {
246 init_perm[final_perm[i] = IP[i] - 1] = i;
247 inv_key_perm[i] = 255;
248 }
249
250 /*
251 * Invert the key permutation and initialise the inverted key
252 * compression permutation.
253 */
254 for (i = 0; i < 56; i++) {
255 u_key_perm[i] = key_perm[i] - 1;
256 inv_key_perm[key_perm[i] - 1] = i;
257 inv_comp_perm[i] = 255;
258 }
259
260 /*
261 * Invert the key compression permutation.
262 */
263 for (i = 0; i < 48; i++) {
264 inv_comp_perm[comp_perm[i] - 1] = i;
265 }
266
267 /*
268 * Set up the OR-mask arrays for the initial and final permutations,
269 * and for the key initial and compression permutations.
270 */
271 for (k = 0; k < 8; k++) {
272 for (i = 0; i < 256; i++) {
273 *(il = &ip_maskl[k][i]) = 0;
274 *(ir = &ip_maskr[k][i]) = 0;
275 *(fl = &fp_maskl[k][i]) = 0;
276 *(fr = &fp_maskr[k][i]) = 0;
277 for (j = 0; j < 8; j++) {
278 inbit = 8 * k + j;
279 if (i & bits8[j]) {
280 if ((obit = init_perm[inbit]) < 32)
281 *il |= bits32[obit];
282 else
283 *ir |= bits32[obit-32];
284 if ((obit = final_perm[inbit]) < 32)
285 *fl |= bits32[obit];
286 else
287 *fr |= bits32[obit - 32];
288 }
289 }
290 }
291 for (i = 0; i < 128; i++) {
292 *(il = &key_perm_maskl[k][i]) = 0;
293 *(ir = &key_perm_maskr[k][i]) = 0;
294 for (j = 0; j < 7; j++) {
295 inbit = 8 * k + j;
296 if (i & bits8[j + 1]) {
297 if ((obit = inv_key_perm[inbit]) == 255)
298 continue;
299 if (obit < 28)
300 *il |= bits28[obit];
301 else
302 *ir |= bits28[obit - 28];
303 }
304 }
305 *(il = &comp_maskl[k][i]) = 0;
306 *(ir = &comp_maskr[k][i]) = 0;
307 for (j = 0; j < 7; j++) {
308 inbit = 7 * k + j;
309 if (i & bits8[j + 1]) {
310 if ((obit=inv_comp_perm[inbit]) == 255)
311 continue;
312 if (obit < 24)
313 *il |= bits24[obit];
314 else
315 *ir |= bits24[obit - 24];
316 }
317 }
318 }
319 }
320
321 /*
322 * Invert the P-box permutation, and convert into OR-masks for
323 * handling the output of the S-box arrays setup above.
324 */
325 for (i = 0; i < 32; i++)
326 un_pbox[pbox[i] - 1] = i;
327
328 for (b = 0; b < 4; b++)
329 for (i = 0; i < 256; i++) {
330 *(p = &psbox[b][i]) = 0;
331 for (j = 0; j < 8; j++) {
332 if (i & bits8[j])
333 *p |= bits32[un_pbox[8 * b + j]];
334 }
335 }
336
337 des_initialised = 1;
338}
339
340static void
341setup_salt(salt)
342 int32_t salt;
343{
344 u_int32_t obit, saltbit;
345 int i;
346
347 if (salt == old_salt)
348 return;
349 old_salt = salt;
350
351 saltbits = 0;
352 saltbit = 1;
353 obit = 0x800000;
354 for (i = 0; i < 24; i++) {
355 if (salt & saltbit)
356 saltbits |= obit;
357 saltbit <<= 1;
358 obit >>= 1;
359 }
360}
361
362static int
363des_setkey(key)
364 const char *key;
365{
366 u_int32_t k0, k1, rawkey0, rawkey1;
367 int shifts, round;
368
369 if (!des_initialised)
370 des_init();
371
372 rawkey0 = ntohl(*(u_int32_t *) key);
373 rawkey1 = ntohl(*(u_int32_t *) (key + 4));
374
375 if ((rawkey0 | rawkey1)
376 && rawkey0 == old_rawkey0
377 && rawkey1 == old_rawkey1) {
378 /*
379 * Already setup for this key.
380 * This optimisation fails on a zero key (which is weak and
381 * has bad parity anyway) in order to simplify the starting
382 * conditions.
383 */
384 return(0);
385 }
386 old_rawkey0 = rawkey0;
387 old_rawkey1 = rawkey1;
388
389 /*
390 * Do key permutation and split into two 28-bit subkeys.
391 */
392 k0 = key_perm_maskl[0][rawkey0 >> 25]
393 | key_perm_maskl[1][(rawkey0 >> 17) & 0x7f]
394 | key_perm_maskl[2][(rawkey0 >> 9) & 0x7f]
395 | key_perm_maskl[3][(rawkey0 >> 1) & 0x7f]
396 | key_perm_maskl[4][rawkey1 >> 25]
397 | key_perm_maskl[5][(rawkey1 >> 17) & 0x7f]
398 | key_perm_maskl[6][(rawkey1 >> 9) & 0x7f]
399 | key_perm_maskl[7][(rawkey1 >> 1) & 0x7f];
400 k1 = key_perm_maskr[0][rawkey0 >> 25]
401 | key_perm_maskr[1][(rawkey0 >> 17) & 0x7f]
402 | key_perm_maskr[2][(rawkey0 >> 9) & 0x7f]
403 | key_perm_maskr[3][(rawkey0 >> 1) & 0x7f]
404 | key_perm_maskr[4][rawkey1 >> 25]
405 | key_perm_maskr[5][(rawkey1 >> 17) & 0x7f]
406 | key_perm_maskr[6][(rawkey1 >> 9) & 0x7f]
407 | key_perm_maskr[7][(rawkey1 >> 1) & 0x7f];
408 /*
409 * Rotate subkeys and do compression permutation.
410 */
411 shifts = 0;
412 for (round = 0; round < 16; round++) {
413 u_int32_t t0, t1;
414
415 shifts += key_shifts[round];
416
417 t0 = (k0 << shifts) | (k0 >> (28 - shifts));
418 t1 = (k1 << shifts) | (k1 >> (28 - shifts));
419
420 de_keysl[15 - round] =
421 en_keysl[round] = comp_maskl[0][(t0 >> 21) & 0x7f]
422 | comp_maskl[1][(t0 >> 14) & 0x7f]
423 | comp_maskl[2][(t0 >> 7) & 0x7f]
424 | comp_maskl[3][t0 & 0x7f]
425 | comp_maskl[4][(t1 >> 21) & 0x7f]
426 | comp_maskl[5][(t1 >> 14) & 0x7f]
427 | comp_maskl[6][(t1 >> 7) & 0x7f]
428 | comp_maskl[7][t1 & 0x7f];
429
430 de_keysr[15 - round] =
431 en_keysr[round] = comp_maskr[0][(t0 >> 21) & 0x7f]
432 | comp_maskr[1][(t0 >> 14) & 0x7f]
433 | comp_maskr[2][(t0 >> 7) & 0x7f]
434 | comp_maskr[3][t0 & 0x7f]
435 | comp_maskr[4][(t1 >> 21) & 0x7f]
436 | comp_maskr[5][(t1 >> 14) & 0x7f]
437 | comp_maskr[6][(t1 >> 7) & 0x7f]
438 | comp_maskr[7][t1 & 0x7f];
439 }
440 return(0);
441}
442
443static int
444do_des(l_in, r_in, l_out, r_out, count)
445 u_int32_t l_in, r_in, *l_out, *r_out;
446 int count;
447{
448 /*
449 * l_in, r_in, l_out, and r_out are in pseudo-"big-endian" format.
450 */
451 u_int32_t l, r, *kl, *kr, *kl1, *kr1;
452 u_int32_t f, r48l, r48r;
453 int round;
454
455 if (count == 0) {
456 return(1);
457 } else if (count > 0) {
458 /*
459 * Encrypting
460 */
461 kl1 = en_keysl;
462 kr1 = en_keysr;
463 } else {
464 /*
465 * Decrypting
466 */
467 count = -count;
468 kl1 = de_keysl;
469 kr1 = de_keysr;
470 }
471
472 /*
473 * Do initial permutation (IP).
474 */
475 l = ip_maskl[0][l_in >> 24]
476 | ip_maskl[1][(l_in >> 16) & 0xff]
477 | ip_maskl[2][(l_in >> 8) & 0xff]
478 | ip_maskl[3][l_in & 0xff]
479 | ip_maskl[4][r_in >> 24]
480 | ip_maskl[5][(r_in >> 16) & 0xff]
481 | ip_maskl[6][(r_in >> 8) & 0xff]
482 | ip_maskl[7][r_in & 0xff];
483 r = ip_maskr[0][l_in >> 24]
484 | ip_maskr[1][(l_in >> 16) & 0xff]
485 | ip_maskr[2][(l_in >> 8) & 0xff]
486 | ip_maskr[3][l_in & 0xff]
487 | ip_maskr[4][r_in >> 24]
488 | ip_maskr[5][(r_in >> 16) & 0xff]
489 | ip_maskr[6][(r_in >> 8) & 0xff]
490 | ip_maskr[7][r_in & 0xff];
491
492 while (count--) {
493 /*
494 * Do each round.
495 */
496 kl = kl1;
497 kr = kr1;
498 round = 16;
499 while (round--) {
500 /*
501 * Expand R to 48 bits (simulate the E-box).
502 */
503 r48l = ((r & 0x00000001) << 23)
504 | ((r & 0xf8000000) >> 9)
505 | ((r & 0x1f800000) >> 11)
506 | ((r & 0x01f80000) >> 13)
507 | ((r & 0x001f8000) >> 15);
508
509 r48r = ((r & 0x0001f800) << 7)
510 | ((r & 0x00001f80) << 5)
511 | ((r & 0x000001f8) << 3)
512 | ((r & 0x0000001f) << 1)
513 | ((r & 0x80000000) >> 31);
514 /*
515 * Do salting for crypt() and friends, and
516 * XOR with the permuted key.
517 */
518 f = (r48l ^ r48r) & saltbits;
519 r48l ^= f ^ *kl++;
520 r48r ^= f ^ *kr++;
521 /*
522 * Do sbox lookups (which shrink it back to 32 bits)
523 * and do the pbox permutation at the same time.
524 */
525 f = psbox[0][m_sbox[0][r48l >> 12]]
526 | psbox[1][m_sbox[1][r48l & 0xfff]]
527 | psbox[2][m_sbox[2][r48r >> 12]]
528 | psbox[3][m_sbox[3][r48r & 0xfff]];
529 /*
530 * Now that we've permuted things, complete f().
531 */
532 f ^= l;
533 l = r;
534 r = f;
535 }
536 r = l;
537 l = f;
538 }
539 /*
540 * Do final permutation (inverse of IP).
541 */
542 *l_out = fp_maskl[0][l >> 24]
543 | fp_maskl[1][(l >> 16) & 0xff]
544 | fp_maskl[2][(l >> 8) & 0xff]
545 | fp_maskl[3][l & 0xff]
546 | fp_maskl[4][r >> 24]
547 | fp_maskl[5][(r >> 16) & 0xff]
548 | fp_maskl[6][(r >> 8) & 0xff]
549 | fp_maskl[7][r & 0xff];
550 *r_out = fp_maskr[0][l >> 24]
551 | fp_maskr[1][(l >> 16) & 0xff]
552 | fp_maskr[2][(l >> 8) & 0xff]
553 | fp_maskr[3][l & 0xff]
554 | fp_maskr[4][r >> 24]
555 | fp_maskr[5][(r >> 16) & 0xff]
556 | fp_maskr[6][(r >> 8) & 0xff]
557 | fp_maskr[7][r & 0xff];
558 return(0);
559}
560
561static int
562des_cipher(in, out, salt, count)
563 const char *in;
564 char *out;
565 int32_t salt;
566 int count;
567{
568 u_int32_t l_out, r_out, rawl, rawr;
569 u_int32_t x[2];
570 int retval;
571
572 if (!des_initialised)
573 des_init();
574
575 setup_salt(salt);
576
577 memcpy(x, in, sizeof x);
578 rawl = ntohl(x[0]);
579 rawr = ntohl(x[1]);
580 retval = do_des(rawl, rawr, &l_out, &r_out, count);
581
582 x[0] = htonl(l_out);
583 x[1] = htonl(r_out);
584 memcpy(out, x, sizeof x);
585 return(retval);
586}
587
588char *
589crypt(key, setting)
590 const char *key;
591 const char *setting;
592{
593 int i;
594 u_int32_t count, salt, l, r0, r1, keybuf[2];
595 u_char *p, *q;
596 static u_char output[21];
597 extern char *md5crypt __P((const char *, const char *));
598 extern char *bcrypt __P((const char *, const char *));
599
600 if (setting[0] == '$') {
601 switch (setting[1]) {
602 case '1':
603 return (md5crypt(key, setting));
604 default:
605 return bcrypt(key, setting);
606 }
607 }
608
609 if (!des_initialised)
610 des_init();
611
612 /*
613 * Copy the key, shifting each character up by one bit
614 * and padding with zeros.
615 */
616 q = (u_char *) keybuf;
617 while ((q - (u_char *) keybuf) < sizeof(keybuf)) {
618 if ((*q++ = *key << 1))
619 key++;
620 }
621 if (des_setkey((u_char *) keybuf))
622 return(NULL);
623
624 if (*setting == _PASSWORD_EFMT1) {
625 /*
626 * "new"-style:
627 * setting - underscore, 4 bytes of count, 4 bytes of salt
628 * key - unlimited characters
629 */
630 for (i = 1, count = 0; i < 5; i++)
631 count |= ascii_to_bin(setting[i]) << (i - 1) * 6;
632
633 for (i = 5, salt = 0; i < 9; i++)
634 salt |= ascii_to_bin(setting[i]) << (i - 5) * 6;
635
636 while (*key) {
637 /*
638 * Encrypt the key with itself.
639 */
640 if (des_cipher((u_char*)keybuf, (u_char*)keybuf, 0, 1))
641 return(NULL);
642 /*
643 * And XOR with the next 8 characters of the key.
644 */
645 q = (u_char *) keybuf;
646 while (((q - (u_char *) keybuf) < sizeof(keybuf)) &&
647 *key)
648 *q++ ^= *key++ << 1;
649
650 if (des_setkey((u_char *) keybuf))
651 return(NULL);
652 }
653 strncpy((char *)output, setting, 9);
654
655 /*
656 * Double check that we weren't given a short setting.
657 * If we were, the above code will probably have created
658 * wierd values for count and salt, but we don't really care.
659 * Just make sure the output string doesn't have an extra
660 * NUL in it.
661 */
662 output[9] = '\0';
663 p = output + strlen((const char *)output);
664 } else {
665 /*
666 * "old"-style:
667 * setting - 2 bytes of salt
668 * key - up to 8 characters
669 */
670 count = 25;
671
672 salt = (ascii_to_bin(setting[1]) << 6)
673 | ascii_to_bin(setting[0]);
674
675 output[0] = setting[0];
676 /*
677 * If the encrypted password that the salt was extracted from
678 * is only 1 character long, the salt will be corrupted. We
679 * need to ensure that the output string doesn't have an extra
680 * NUL in it!
681 */
682 output[1] = setting[1] ? setting[1] : output[0];
683
684 p = output + 2;
685 }
686 setup_salt(salt);
687 /*
688 * Do it.
689 */
690 if (do_des(0, 0, &r0, &r1, count))
691 return(NULL);
692 /*
693 * Now encode the result...
694 */
695 l = (r0 >> 8);
696 *p++ = ascii64[(l >> 18) & 0x3f];
697 *p++ = ascii64[(l >> 12) & 0x3f];
698 *p++ = ascii64[(l >> 6) & 0x3f];
699 *p++ = ascii64[l & 0x3f];
700
701 l = (r0 << 16) | ((r1 >> 16) & 0xffff);
702 *p++ = ascii64[(l >> 18) & 0x3f];
703 *p++ = ascii64[(l >> 12) & 0x3f];
704 *p++ = ascii64[(l >> 6) & 0x3f];
705 *p++ = ascii64[l & 0x3f];
706
707 l = r1 << 2;
708 *p++ = ascii64[(l >> 12) & 0x3f];
709 *p++ = ascii64[(l >> 6) & 0x3f];
710 *p++ = ascii64[l & 0x3f];
711 *p = 0;
712
713 return((char *)output);
714}
diff --git a/src/lib/libc/crypt/md5crypt.c b/src/lib/libc/crypt/md5crypt.c
new file mode 100644
index 0000000000..7ec60f38e0
--- /dev/null
+++ b/src/lib/libc/crypt/md5crypt.c
@@ -0,0 +1,157 @@
1/* $OpenBSD: md5crypt.c,v 1.9 1997/07/23 20:58:27 kstailey 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.9 1997/07/23 20:58:27 kstailey 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 __P((char *, u_int32_t, int));
29
30static void
31to64(s, v, n)
32 char *s;
33 u_int32_t v;
34 int n;
35{
36 while (--n >= 0) {
37 *s++ = itoa64[v&0x3f];
38 v >>= 6;
39 }
40}
41
42/*
43 * UNIX password
44 *
45 * Use MD5 for what it is best at...
46 */
47
48char *
49md5crypt(pw, salt)
50 register const char *pw;
51 register const char *salt;
52{
53 /*
54 * This string is magic for this algorithm. Having
55 * it this way, we can get get better later on
56 */
57 static unsigned char *magic = (unsigned char *)"$1$";
58
59 static char passwd[120], *p;
60 static const unsigned char *sp,*ep;
61 unsigned char final[16];
62 int sl,pl,i;
63 MD5_CTX ctx,ctx1;
64 u_int32_t l;
65
66 /* Refine the Salt first */
67 sp = (const unsigned char *)salt;
68
69 /* If it starts with the magic string, then skip that */
70 if(!strncmp((const char *)sp,(const char *)magic,strlen((const char *)magic)))
71 sp += strlen((const char *)magic);
72
73 /* It stops at the first '$', max 8 chars */
74 for(ep=sp;*ep && *ep != '$' && ep < (sp+8);ep++)
75 continue;
76
77 /* get the length of the true salt */
78 sl = ep - sp;
79
80 MD5Init(&ctx);
81
82 /* The password first, since that is what is most unknown */
83 MD5Update(&ctx,(const unsigned char *)pw,strlen(pw));
84
85 /* Then our magic string */
86 MD5Update(&ctx,magic,strlen((const char *)magic));
87
88 /* Then the raw salt */
89 MD5Update(&ctx,sp,sl);
90
91 /* Then just as many characters of the MD5(pw,salt,pw) */
92 MD5Init(&ctx1);
93 MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw));
94 MD5Update(&ctx1,sp,sl);
95 MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw));
96 MD5Final(final,&ctx1);
97 for(pl = strlen(pw); pl > 0; pl -= 16)
98 MD5Update(&ctx,final,pl>16 ? 16 : pl);
99
100 /* Don't leave anything around in vm they could use. */
101 memset(final,0,sizeof final);
102
103 /* Then something really weird... */
104 for (i = strlen(pw); i ; i >>= 1)
105 if(i&1)
106 MD5Update(&ctx, final, 1);
107 else
108 MD5Update(&ctx, (const unsigned char *)pw, 1);
109
110 /* Now make the output string */
111 strcpy(passwd,(const char *)magic);
112 strncat(passwd,(const char *)sp,sl);
113 strcat(passwd,"$");
114
115 MD5Final(final,&ctx);
116
117 /*
118 * and now, just to make sure things don't run too fast
119 * On a 60 Mhz Pentium this takes 34 msec, so you would
120 * need 30 seconds to build a 1000 entry dictionary...
121 */
122 for(i=0;i<1000;i++) {
123 MD5Init(&ctx1);
124 if(i & 1)
125 MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw));
126 else
127 MD5Update(&ctx1,final,16);
128
129 if(i % 3)
130 MD5Update(&ctx1,sp,sl);
131
132 if(i % 7)
133 MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw));
134
135 if(i & 1)
136 MD5Update(&ctx1,final,16);
137 else
138 MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw));
139 MD5Final(final,&ctx1);
140 }
141
142 p = passwd + strlen(passwd);
143
144 l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; to64(p,l,4); p += 4;
145 l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; to64(p,l,4); p += 4;
146 l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; to64(p,l,4); p += 4;
147 l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; to64(p,l,4); p += 4;
148 l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; to64(p,l,4); p += 4;
149 l = final[11] ; to64(p,l,2); p += 2;
150 *p = '\0';
151
152 /* Don't leave anything around in vm they could use. */
153 memset(final,0,sizeof final);
154
155 return passwd;
156}
157
diff --git a/src/lib/libc/crypt/morecrypt.c b/src/lib/libc/crypt/morecrypt.c
new file mode 100644
index 0000000000..e9e0ced4c1
--- /dev/null
+++ b/src/lib/libc/crypt/morecrypt.c
@@ -0,0 +1,628 @@
1/* $OpenBSD: morecrypt.c,v 1.9 1998/03/22 19:01:20 niklas Exp $ */
2
3/*
4 * FreeSec: libcrypt
5 *
6 * Copyright (c) 1994 David Burren
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 4. Neither the name of the author nor the names of other contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 *
34 * This is an original implementation of the DES and the crypt(3) interfaces
35 * by David Burren <davidb@werj.com.au>.
36 *
37 * An excellent reference on the underlying algorithm (and related
38 * algorithms) is:
39 *
40 * B. Schneier, Applied Cryptography: protocols, algorithms,
41 * and source code in C, John Wiley & Sons, 1994.
42 *
43 * Note that in that book's description of DES the lookups for the initial,
44 * pbox, and final permutations are inverted (this has been brought to the
45 * attention of the author). A list of errata for this book has been
46 * posted to the sci.crypt newsgroup by the author and is available for FTP.
47 *
48 * NOTE:
49 * This file must copy certain chunks of crypt.c for legal reasons.
50 * crypt.c can only export the interface crypt(), to make binaries
51 * exportable from the USA. Hence, to also have the other crypto interfaces
52 * available we have to copy pieces...
53 */
54
55#if defined(LIBC_SCCS) && !defined(lint)
56static char rcsid[] = "$OpenBSD: morecrypt.c,v 1.9 1998/03/22 19:01:20 niklas Exp $";
57#endif /* LIBC_SCCS and not lint */
58
59#include <sys/types.h>
60#include <sys/param.h>
61#include <pwd.h>
62#include <string.h>
63
64#ifdef DEBUG
65# include <stdio.h>
66#endif
67
68static u_char IP[64] = {
69 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,
70 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,
71 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3,
72 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7
73};
74
75static u_char inv_key_perm[64];
76static u_char u_key_perm[56];
77static u_char key_perm[56] = {
78 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18,
79 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36,
80 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22,
81 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4
82};
83
84static u_char key_shifts[16] = {
85 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
86};
87
88static u_char inv_comp_perm[56];
89static u_char comp_perm[48] = {
90 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10,
91 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2,
92 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,
93 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32
94};
95
96/*
97 * No E box is used, as it's replaced by some ANDs, shifts, and ORs.
98 */
99
100static u_char u_sbox[8][64];
101static u_char sbox[8][64] = {
102 {
103 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
104 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
105 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
106 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13
107 },
108 {
109 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
110 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
111 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
112 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9
113 },
114 {
115 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
116 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
117 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
118 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12
119 },
120 {
121 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
122 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
123 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
124 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14
125 },
126 {
127 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
128 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
129 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
130 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3
131 },
132 {
133 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
134 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
135 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
136 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13
137 },
138 {
139 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
140 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
141 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
142 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12
143 },
144 {
145 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
146 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
147 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
148 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
149 }
150};
151
152static u_char un_pbox[32];
153static u_char pbox[32] = {
154 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,
155 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25
156};
157
158static u_int32_t bits32[32] =
159{
160 0x80000000, 0x40000000, 0x20000000, 0x10000000,
161 0x08000000, 0x04000000, 0x02000000, 0x01000000,
162 0x00800000, 0x00400000, 0x00200000, 0x00100000,
163 0x00080000, 0x00040000, 0x00020000, 0x00010000,
164 0x00008000, 0x00004000, 0x00002000, 0x00001000,
165 0x00000800, 0x00000400, 0x00000200, 0x00000100,
166 0x00000080, 0x00000040, 0x00000020, 0x00000010,
167 0x00000008, 0x00000004, 0x00000002, 0x00000001
168};
169
170static u_char bits8[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
171
172static u_int32_t saltbits;
173static int32_t old_salt;
174static u_int32_t *bits28, *bits24;
175static u_char init_perm[64], final_perm[64];
176static u_int32_t en_keysl[16], en_keysr[16];
177static u_int32_t de_keysl[16], de_keysr[16];
178static int des_initialised = 0;
179static u_char m_sbox[4][4096];
180static u_int32_t psbox[4][256];
181static u_int32_t ip_maskl[8][256], ip_maskr[8][256];
182static u_int32_t fp_maskl[8][256], fp_maskr[8][256];
183static u_int32_t key_perm_maskl[8][128], key_perm_maskr[8][128];
184static u_int32_t comp_maskl[8][128], comp_maskr[8][128];
185static u_int32_t old_rawkey0, old_rawkey1;
186
187static __inline int
188ascii_to_bin(ch)
189 char ch;
190{
191 if (ch > 'z')
192 return(0);
193 if (ch >= 'a')
194 return(ch - 'a' + 38);
195 if (ch > 'Z')
196 return(0);
197 if (ch >= 'A')
198 return(ch - 'A' + 12);
199 if (ch > '9')
200 return(0);
201 if (ch >= '.')
202 return(ch - '.');
203 return(0);
204}
205
206void
207des_init()
208{
209 int i, j, b, k, inbit, obit;
210 u_int32_t *p, *il, *ir, *fl, *fr;
211
212 old_rawkey0 = old_rawkey1 = 0;
213 saltbits = 0;
214 old_salt = 0;
215 bits24 = (bits28 = bits32 + 4) + 4;
216
217 /*
218 * Invert the S-boxes, reordering the input bits.
219 */
220 for (i = 0; i < 8; i++)
221 for (j = 0; j < 64; j++) {
222 b = (j & 0x20) | ((j & 1) << 4) | ((j >> 1) & 0xf);
223 u_sbox[i][j] = sbox[i][b];
224 }
225
226 /*
227 * Convert the inverted S-boxes into 4 arrays of 8 bits.
228 * Each will handle 12 bits of the S-box input.
229 */
230 for (b = 0; b < 4; b++)
231 for (i = 0; i < 64; i++)
232 for (j = 0; j < 64; j++)
233 m_sbox[b][(i << 6) | j] =
234 (u_sbox[(b << 1)][i] << 4) |
235 u_sbox[(b << 1) + 1][j];
236
237 /*
238 * Set up the initial & final permutations into a useful form, and
239 * initialise the inverted key permutation.
240 */
241 for (i = 0; i < 64; i++) {
242 init_perm[final_perm[i] = IP[i] - 1] = i;
243 inv_key_perm[i] = 255;
244 }
245
246 /*
247 * Invert the key permutation and initialise the inverted key
248 * compression permutation.
249 */
250 for (i = 0; i < 56; i++) {
251 u_key_perm[i] = key_perm[i] - 1;
252 inv_key_perm[key_perm[i] - 1] = i;
253 inv_comp_perm[i] = 255;
254 }
255
256 /*
257 * Invert the key compression permutation.
258 */
259 for (i = 0; i < 48; i++) {
260 inv_comp_perm[comp_perm[i] - 1] = i;
261 }
262
263 /*
264 * Set up the OR-mask arrays for the initial and final permutations,
265 * and for the key initial and compression permutations.
266 */
267 for (k = 0; k < 8; k++) {
268 for (i = 0; i < 256; i++) {
269 *(il = &ip_maskl[k][i]) = 0;
270 *(ir = &ip_maskr[k][i]) = 0;
271 *(fl = &fp_maskl[k][i]) = 0;
272 *(fr = &fp_maskr[k][i]) = 0;
273 for (j = 0; j < 8; j++) {
274 inbit = 8 * k + j;
275 if (i & bits8[j]) {
276 if ((obit = init_perm[inbit]) < 32)
277 *il |= bits32[obit];
278 else
279 *ir |= bits32[obit-32];
280 if ((obit = final_perm[inbit]) < 32)
281 *fl |= bits32[obit];
282 else
283 *fr |= bits32[obit - 32];
284 }
285 }
286 }
287 for (i = 0; i < 128; i++) {
288 *(il = &key_perm_maskl[k][i]) = 0;
289 *(ir = &key_perm_maskr[k][i]) = 0;
290 for (j = 0; j < 7; j++) {
291 inbit = 8 * k + j;
292 if (i & bits8[j + 1]) {
293 if ((obit = inv_key_perm[inbit]) == 255)
294 continue;
295 if (obit < 28)
296 *il |= bits28[obit];
297 else
298 *ir |= bits28[obit - 28];
299 }
300 }
301 *(il = &comp_maskl[k][i]) = 0;
302 *(ir = &comp_maskr[k][i]) = 0;
303 for (j = 0; j < 7; j++) {
304 inbit = 7 * k + j;
305 if (i & bits8[j + 1]) {
306 if ((obit=inv_comp_perm[inbit]) == 255)
307 continue;
308 if (obit < 24)
309 *il |= bits24[obit];
310 else
311 *ir |= bits24[obit - 24];
312 }
313 }
314 }
315 }
316
317 /*
318 * Invert the P-box permutation, and convert into OR-masks for
319 * handling the output of the S-box arrays setup above.
320 */
321 for (i = 0; i < 32; i++)
322 un_pbox[pbox[i] - 1] = i;
323
324 for (b = 0; b < 4; b++)
325 for (i = 0; i < 256; i++) {
326 *(p = &psbox[b][i]) = 0;
327 for (j = 0; j < 8; j++) {
328 if (i & bits8[j])
329 *p |= bits32[un_pbox[8 * b + j]];
330 }
331 }
332
333 des_initialised = 1;
334}
335
336void
337setup_salt(salt)
338 int32_t salt;
339{
340 u_int32_t obit, saltbit;
341 int i;
342
343 if (salt == old_salt)
344 return;
345 old_salt = salt;
346
347 saltbits = 0;
348 saltbit = 1;
349 obit = 0x800000;
350 for (i = 0; i < 24; i++) {
351 if (salt & saltbit)
352 saltbits |= obit;
353 saltbit <<= 1;
354 obit >>= 1;
355 }
356}
357
358int
359do_des(l_in, r_in, l_out, r_out, count)
360 u_int32_t l_in, r_in, *l_out, *r_out;
361 int count;
362{
363 /*
364 * l_in, r_in, l_out, and r_out are in pseudo-"big-endian" format.
365 */
366 u_int32_t l, r, *kl, *kr, *kl1, *kr1;
367 u_int32_t f, r48l, r48r;
368 int round;
369
370 if (count == 0) {
371 return(1);
372 } else if (count > 0) {
373 /*
374 * Encrypting
375 */
376 kl1 = en_keysl;
377 kr1 = en_keysr;
378 } else {
379 /*
380 * Decrypting
381 */
382 count = -count;
383 kl1 = de_keysl;
384 kr1 = de_keysr;
385 }
386
387 /*
388 * Do initial permutation (IP).
389 */
390 l = ip_maskl[0][l_in >> 24]
391 | ip_maskl[1][(l_in >> 16) & 0xff]
392 | ip_maskl[2][(l_in >> 8) & 0xff]
393 | ip_maskl[3][l_in & 0xff]
394 | ip_maskl[4][r_in >> 24]
395 | ip_maskl[5][(r_in >> 16) & 0xff]
396 | ip_maskl[6][(r_in >> 8) & 0xff]
397 | ip_maskl[7][r_in & 0xff];
398 r = ip_maskr[0][l_in >> 24]
399 | ip_maskr[1][(l_in >> 16) & 0xff]
400 | ip_maskr[2][(l_in >> 8) & 0xff]
401 | ip_maskr[3][l_in & 0xff]
402 | ip_maskr[4][r_in >> 24]
403 | ip_maskr[5][(r_in >> 16) & 0xff]
404 | ip_maskr[6][(r_in >> 8) & 0xff]
405 | ip_maskr[7][r_in & 0xff];
406
407 while (count--) {
408 /*
409 * Do each round.
410 */
411 kl = kl1;
412 kr = kr1;
413 round = 16;
414 while (round--) {
415 /*
416 * Expand R to 48 bits (simulate the E-box).
417 */
418 r48l = ((r & 0x00000001) << 23)
419 | ((r & 0xf8000000) >> 9)
420 | ((r & 0x1f800000) >> 11)
421 | ((r & 0x01f80000) >> 13)
422 | ((r & 0x001f8000) >> 15);
423
424 r48r = ((r & 0x0001f800) << 7)
425 | ((r & 0x00001f80) << 5)
426 | ((r & 0x000001f8) << 3)
427 | ((r & 0x0000001f) << 1)
428 | ((r & 0x80000000) >> 31);
429 /*
430 * Do salting for crypt() and friends, and
431 * XOR with the permuted key.
432 */
433 f = (r48l ^ r48r) & saltbits;
434 r48l ^= f ^ *kl++;
435 r48r ^= f ^ *kr++;
436 /*
437 * Do sbox lookups (which shrink it back to 32 bits)
438 * and do the pbox permutation at the same time.
439 */
440 f = psbox[0][m_sbox[0][r48l >> 12]]
441 | psbox[1][m_sbox[1][r48l & 0xfff]]
442 | psbox[2][m_sbox[2][r48r >> 12]]
443 | psbox[3][m_sbox[3][r48r & 0xfff]];
444 /*
445 * Now that we've permuted things, complete f().
446 */
447 f ^= l;
448 l = r;
449 r = f;
450 }
451 r = l;
452 l = f;
453 }
454 /*
455 * Do final permutation (inverse of IP).
456 */
457 *l_out = fp_maskl[0][l >> 24]
458 | fp_maskl[1][(l >> 16) & 0xff]
459 | fp_maskl[2][(l >> 8) & 0xff]
460 | fp_maskl[3][l & 0xff]
461 | fp_maskl[4][r >> 24]
462 | fp_maskl[5][(r >> 16) & 0xff]
463 | fp_maskl[6][(r >> 8) & 0xff]
464 | fp_maskl[7][r & 0xff];
465 *r_out = fp_maskr[0][l >> 24]
466 | fp_maskr[1][(l >> 16) & 0xff]
467 | fp_maskr[2][(l >> 8) & 0xff]
468 | fp_maskr[3][l & 0xff]
469 | fp_maskr[4][r >> 24]
470 | fp_maskr[5][(r >> 16) & 0xff]
471 | fp_maskr[6][(r >> 8) & 0xff]
472 | fp_maskr[7][r & 0xff];
473 return(0);
474}
475
476int
477des_cipher(in, out, salt, count)
478 const char *in;
479 char *out;
480 long salt;
481 int count;
482{
483 u_int32_t l_out, r_out, rawl, rawr;
484 u_int32_t x[2];
485 int retval;
486
487 if (!des_initialised)
488 des_init();
489
490 setup_salt((int32_t)salt);
491
492 memcpy(x, in, sizeof x);
493 rawl = ntohl(x[0]);
494 rawr = ntohl(x[1]);
495 retval = do_des(rawl, rawr, &l_out, &r_out, count);
496
497 x[0] = htonl(l_out);
498 x[1] = htonl(r_out);
499 memcpy(out, x, sizeof x);
500 return(retval);
501}
502
503int
504des_setkey(key)
505 const char *key;
506{
507 u_int32_t k0, k1, rawkey0, rawkey1;
508 int shifts, round;
509
510 if (!des_initialised)
511 des_init();
512
513 rawkey0 = ntohl(*(u_int32_t *) key);
514 rawkey1 = ntohl(*(u_int32_t *) (key + 4));
515
516 if ((rawkey0 | rawkey1)
517 && rawkey0 == old_rawkey0
518 && rawkey1 == old_rawkey1) {
519 /*
520 * Already setup for this key.
521 * This optimisation fails on a zero key (which is weak and
522 * has bad parity anyway) in order to simplify the starting
523 * conditions.
524 */
525 return(0);
526 }
527 old_rawkey0 = rawkey0;
528 old_rawkey1 = rawkey1;
529
530 /*
531 * Do key permutation and split into two 28-bit subkeys.
532 */
533 k0 = key_perm_maskl[0][rawkey0 >> 25]
534 | key_perm_maskl[1][(rawkey0 >> 17) & 0x7f]
535 | key_perm_maskl[2][(rawkey0 >> 9) & 0x7f]
536 | key_perm_maskl[3][(rawkey0 >> 1) & 0x7f]
537 | key_perm_maskl[4][rawkey1 >> 25]
538 | key_perm_maskl[5][(rawkey1 >> 17) & 0x7f]
539 | key_perm_maskl[6][(rawkey1 >> 9) & 0x7f]
540 | key_perm_maskl[7][(rawkey1 >> 1) & 0x7f];
541 k1 = key_perm_maskr[0][rawkey0 >> 25]
542 | key_perm_maskr[1][(rawkey0 >> 17) & 0x7f]
543 | key_perm_maskr[2][(rawkey0 >> 9) & 0x7f]
544 | key_perm_maskr[3][(rawkey0 >> 1) & 0x7f]
545 | key_perm_maskr[4][rawkey1 >> 25]
546 | key_perm_maskr[5][(rawkey1 >> 17) & 0x7f]
547 | key_perm_maskr[6][(rawkey1 >> 9) & 0x7f]
548 | key_perm_maskr[7][(rawkey1 >> 1) & 0x7f];
549 /*
550 * Rotate subkeys and do compression permutation.
551 */
552 shifts = 0;
553 for (round = 0; round < 16; round++) {
554 u_int32_t t0, t1;
555
556 shifts += key_shifts[round];
557
558 t0 = (k0 << shifts) | (k0 >> (28 - shifts));
559 t1 = (k1 << shifts) | (k1 >> (28 - shifts));
560
561 de_keysl[15 - round] =
562 en_keysl[round] = comp_maskl[0][(t0 >> 21) & 0x7f]
563 | comp_maskl[1][(t0 >> 14) & 0x7f]
564 | comp_maskl[2][(t0 >> 7) & 0x7f]
565 | comp_maskl[3][t0 & 0x7f]
566 | comp_maskl[4][(t1 >> 21) & 0x7f]
567 | comp_maskl[5][(t1 >> 14) & 0x7f]
568 | comp_maskl[6][(t1 >> 7) & 0x7f]
569 | comp_maskl[7][t1 & 0x7f];
570
571 de_keysr[15 - round] =
572 en_keysr[round] = comp_maskr[0][(t0 >> 21) & 0x7f]
573 | comp_maskr[1][(t0 >> 14) & 0x7f]
574 | comp_maskr[2][(t0 >> 7) & 0x7f]
575 | comp_maskr[3][t0 & 0x7f]
576 | comp_maskr[4][(t1 >> 21) & 0x7f]
577 | comp_maskr[5][(t1 >> 14) & 0x7f]
578 | comp_maskr[6][(t1 >> 7) & 0x7f]
579 | comp_maskr[7][t1 & 0x7f];
580 }
581 return(0);
582}
583
584int
585setkey(key)
586 const char *key;
587{
588 int i, j;
589 u_int32_t packed_keys[2];
590 u_char *p;
591
592 p = (u_char *) packed_keys;
593
594 for (i = 0; i < 8; i++) {
595 p[i] = 0;
596 for (j = 0; j < 8; j++)
597 if (*key++ & 1)
598 p[i] |= bits8[j];
599 }
600 return(des_setkey(p));
601}
602
603int
604encrypt(block, flag)
605 char *block;
606 int flag;
607{
608 u_int32_t io[2];
609 u_char *p;
610 int i, j, retval;
611
612 if (!des_initialised)
613 des_init();
614
615 setup_salt((int32_t)0);
616 p = (u_char *)block;
617 for (i = 0; i < 2; i++) {
618 io[i] = 0L;
619 for (j = 0; j < 32; j++)
620 if (*p++ & 1)
621 io[i] |= bits32[j];
622 }
623 retval = do_des(io[0], io[1], io, io + 1, flag ? -1 : 1);
624 for (i = 0; i < 2; i++)
625 for (j = 0; j < 32; j++)
626 block[(i << 5) | j] = (io[i] & bits32[j]) ? 1 : 0;
627 return(retval);
628}
diff --git a/src/lib/libc/include/namespace.h b/src/lib/libc/include/namespace.h
new file mode 100644
index 0000000000..4a51f15ddf
--- /dev/null
+++ b/src/lib/libc/include/namespace.h
@@ -0,0 +1,18 @@
1/* $OpenBSD: namespace.h,v 1.2 1996/08/19 08:28:08 tholo Exp $ */
2
3#define catclose _catclose
4#define catgets _catgets
5#define catopen _catopen
6#define err _err
7#define errx _errx
8#define strtoq _strtoq
9#define strtouq _strtouq
10#define sys_errlist _sys_errlist
11#define sys_nerr _sys_nerr
12#define sys_siglist _sys_siglist
13#define verr _verr
14#define verrx _verrx
15#define vwarn _vwarn
16#define vwarnx _vwarnx
17#define warn _warn
18#define warnx _warnx
diff --git a/src/lib/libc/net/Makefile.inc b/src/lib/libc/net/Makefile.inc
new file mode 100644
index 0000000000..935a1904c1
--- /dev/null
+++ b/src/lib/libc/net/Makefile.inc
@@ -0,0 +1,56 @@
1# $OpenBSD: Makefile.inc,v 1.16 1998/08/29 21:11:40 deraadt Exp $
2
3# net sources
4.PATH: ${.CURDIR}/arch/${MACHINE_ARCH}/net ${.CURDIR}/net
5
6CFLAGS+=-DRESOLVSORT
7
8SRCS+= base64.c gethostnamadr.c getnetbyaddr.c getnetbyname.c getnetent.c \
9 getnetnamadr.c getproto.c getprotoent.c getprotoname.c getservbyname.c \
10 getservbyport.c getservent.c herror.c inet_addr.c inet_lnaof.c \
11 inet_makeaddr.c inet_neta.c inet_netof.c inet_network.c \
12 inet_net_ntop.c inet_net_pton.c inet_ntoa.c inet_ntop.c \
13 inet_pton.c ipx_addr.c ipx_ntoa.c \
14 iso_addr.c linkaddr.c ns_addr.c ns_ntoa.c nsap_addr.c rcmd.c recv.c \
15 res_comp.c res_data.c res_debug.c res_init.c res_mkquery.c res_query.c \
16 res_random.c res_send.c send.c sethostent.c ethers.c rcmdsh.c
17
18# machine-dependent net sources
19# m-d Makefile.inc must include sources for:
20# htonl() htons() ntohl() ntohs()
21
22.include "${.CURDIR}/arch/${MACHINE_ARCH}/net/Makefile.inc"
23
24MAN+= byteorder.3 ethers.3 gethostbyname.3 getnetent.3 getprotoent.3 \
25 getservent.3 inet.3 inet_net.3 iso_addr.3 link_addr.3 ns.3 ipx.3 \
26 rcmd.3 rcmdsh.3 resolver.3
27
28MLINKS+=byteorder.3 htonl.3 byteorder.3 htons.3 byteorder.3 ntohl.3 \
29 byteorder.3 ntohs.3 byteorder.3 htobe16.3 byteorder.3 htobe32.3 \
30 byteorder.3 betoh16.3 byteorder.3 betoh32.3 byteorder.3 htole16.3 \
31 byteorder.3 htole32.3 byteorder.3 letoh16.3 byteorder.3 letoh32.3 \
32 byteorder.3 swap16.3 byteorder.3 swap32.3
33MLINKS+=ethers.3 ether_aton.3 ethers.3 ether_hostton.3 ethers.3 ether_line.3 \
34 ethers.3 ether_ntoa.3 ethers.3 ether_ntohost.3 ethers.3 ether_addr.3
35MLINKS+=gethostbyname.3 endhostent.3 gethostbyname.3 gethostbyaddr.3 \
36 gethostbyname.3 sethostent.3 gethostbyname.3 gethostent.3 \
37 gethostbyname.3 herror.3 gethostbyname.3 gethostbyname2.3 \
38 gethostbyname.3 hstrerror.3
39MLINKS+=getnetent.3 endnetent.3 getnetent.3 getnetbyaddr.3 \
40 getnetent.3 getnetbyname.3 getnetent.3 setnetent.3
41MLINKS+=getprotoent.3 endprotoent.3 getprotoent.3 getprotobyname.3 \
42 getprotoent.3 getprotobynumber.3 getprotoent.3 setprotoent.3
43MLINKS+=getservent.3 endservent.3 getservent.3 getservbyname.3 \
44 getservent.3 getservbyport.3 getservent.3 setservent.3
45MLINKS+=inet.3 addr.3 inet.3 inet_addr.3 inet.3 inet_aton.3 \
46 inet.3 inet_lnaof.3 inet.3 inet_makeaddr.3 inet.3 inet_netof.3 \
47 inet.3 inet_network.3 inet.3 inet_ntoa.3 inet.3 network.3 \
48 inet.3 ntoa.3 inet.3 inet_ntop.3 inet.3 inet_pton.3
49MLINKS+=iso_addr.3 iso_ntoa.3
50MLINKS+=link_addr.3 link_ntoa.3
51MLINKS+=ipx.3 ipx_addr.3 ipx.3 ipx_ntoa.3
52MLINKS+=ns.3 ns_addr.3 ns.3 ns_ntoa.3
53MLINKS+=rcmd.3 iruserok.3 rcmd.3 rresvport.3 rcmd.3 ruserok.3
54MLINKS+=resolver.3 dn_comp.3 resolver.3 dn_expand.3 resolver.3 res_init.3 \
55 resolver.3 res_mkquery.3 resolver.3 res_send.3 resolver.3 res_query.3 \
56 resolver.3 res_search.3
diff --git a/src/lib/libc/net/base64.c b/src/lib/libc/net/base64.c
new file mode 100644
index 0000000000..452fe5afcc
--- /dev/null
+++ b/src/lib/libc/net/base64.c
@@ -0,0 +1,317 @@
1/* $OpenBSD: base64.c,v 1.3 1997/11/08 20:46:55 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#define Assert(Cond) if (!(Cond)) abort()
60
61static const char Base64[] =
62 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
63static const char Pad64 = '=';
64
65/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
66 The following encoding technique is taken from RFC 1521 by Borenstein
67 and Freed. It is reproduced here in a slightly edited form for
68 convenience.
69
70 A 65-character subset of US-ASCII is used, enabling 6 bits to be
71 represented per printable character. (The extra 65th character, "=",
72 is used to signify a special processing function.)
73
74 The encoding process represents 24-bit groups of input bits as output
75 strings of 4 encoded characters. Proceeding from left to right, a
76 24-bit input group is formed by concatenating 3 8-bit input groups.
77 These 24 bits are then treated as 4 concatenated 6-bit groups, each
78 of which is translated into a single digit in the base64 alphabet.
79
80 Each 6-bit group is used as an index into an array of 64 printable
81 characters. The character referenced by the index is placed in the
82 output string.
83
84 Table 1: The Base64 Alphabet
85
86 Value Encoding Value Encoding Value Encoding Value Encoding
87 0 A 17 R 34 i 51 z
88 1 B 18 S 35 j 52 0
89 2 C 19 T 36 k 53 1
90 3 D 20 U 37 l 54 2
91 4 E 21 V 38 m 55 3
92 5 F 22 W 39 n 56 4
93 6 G 23 X 40 o 57 5
94 7 H 24 Y 41 p 58 6
95 8 I 25 Z 42 q 59 7
96 9 J 26 a 43 r 60 8
97 10 K 27 b 44 s 61 9
98 11 L 28 c 45 t 62 +
99 12 M 29 d 46 u 63 /
100 13 N 30 e 47 v
101 14 O 31 f 48 w (pad) =
102 15 P 32 g 49 x
103 16 Q 33 h 50 y
104
105 Special processing is performed if fewer than 24 bits are available
106 at the end of the data being encoded. A full encoding quantum is
107 always completed at the end of a quantity. When fewer than 24 input
108 bits are available in an input group, zero bits are added (on the
109 right) to form an integral number of 6-bit groups. Padding at the
110 end of the data is performed using the '=' character.
111
112 Since all base64 input is an integral number of octets, only the
113 -------------------------------------------------
114 following cases can arise:
115
116 (1) the final quantum of encoding input is an integral
117 multiple of 24 bits; here, the final unit of encoded
118 output will be an integral multiple of 4 characters
119 with no "=" padding,
120 (2) the final quantum of encoding input is exactly 8 bits;
121 here, the final unit of encoded output will be two
122 characters followed by two "=" padding characters, or
123 (3) the final quantum of encoding input is exactly 16 bits;
124 here, the final unit of encoded output will be three
125 characters followed by one "=" padding character.
126 */
127
128int
129b64_ntop(src, srclength, target, targsize)
130 u_char const *src;
131 size_t srclength;
132 char *target;
133 size_t targsize;
134{
135 size_t datalength = 0;
136 u_char input[3];
137 u_char output[4];
138 int i;
139
140 while (2 < srclength) {
141 input[0] = *src++;
142 input[1] = *src++;
143 input[2] = *src++;
144 srclength -= 3;
145
146 output[0] = input[0] >> 2;
147 output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
148 output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
149 output[3] = input[2] & 0x3f;
150 Assert(output[0] < 64);
151 Assert(output[1] < 64);
152 Assert(output[2] < 64);
153 Assert(output[3] < 64);
154
155 if (datalength + 4 > targsize)
156 return (-1);
157 target[datalength++] = Base64[output[0]];
158 target[datalength++] = Base64[output[1]];
159 target[datalength++] = Base64[output[2]];
160 target[datalength++] = Base64[output[3]];
161 }
162
163 /* Now we worry about padding. */
164 if (0 != srclength) {
165 /* Get what's left. */
166 input[0] = input[1] = input[2] = '\0';
167 for (i = 0; i < srclength; i++)
168 input[i] = *src++;
169
170 output[0] = input[0] >> 2;
171 output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
172 output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
173 Assert(output[0] < 64);
174 Assert(output[1] < 64);
175 Assert(output[2] < 64);
176
177 if (datalength + 4 > targsize)
178 return (-1);
179 target[datalength++] = Base64[output[0]];
180 target[datalength++] = Base64[output[1]];
181 if (srclength == 1)
182 target[datalength++] = Pad64;
183 else
184 target[datalength++] = Base64[output[2]];
185 target[datalength++] = Pad64;
186 }
187 if (datalength >= targsize)
188 return (-1);
189 target[datalength] = '\0'; /* Returned value doesn't count \0. */
190 return (datalength);
191}
192
193/* skips all whitespace anywhere.
194 converts characters, four at a time, starting at (or after)
195 src from base - 64 numbers into three 8 bit bytes in the target area.
196 it returns the number of data bytes stored at the target, or -1 on error.
197 */
198
199int
200b64_pton(src, target, targsize)
201 char const *src;
202 u_char *target;
203 size_t targsize;
204{
205 int tarindex, state, ch;
206 char *pos;
207
208 state = 0;
209 tarindex = 0;
210
211 while ((ch = *src++) != '\0') {
212 if (isspace(ch)) /* Skip whitespace anywhere. */
213 continue;
214
215 if (ch == Pad64)
216 break;
217
218 pos = strchr(Base64, ch);
219 if (pos == 0) /* A non-base64 character. */
220 return (-1);
221
222 switch (state) {
223 case 0:
224 if (target) {
225 if (tarindex >= targsize)
226 return (-1);
227 target[tarindex] = (pos - Base64) << 2;
228 }
229 state = 1;
230 break;
231 case 1:
232 if (target) {
233 if (tarindex + 1 >= targsize)
234 return (-1);
235 target[tarindex] |= (pos - Base64) >> 4;
236 target[tarindex+1] = ((pos - Base64) & 0x0f)
237 << 4 ;
238 }
239 tarindex++;
240 state = 2;
241 break;
242 case 2:
243 if (target) {
244 if (tarindex + 1 >= targsize)
245 return (-1);
246 target[tarindex] |= (pos - Base64) >> 2;
247 target[tarindex+1] = ((pos - Base64) & 0x03)
248 << 6;
249 }
250 tarindex++;
251 state = 3;
252 break;
253 case 3:
254 if (target) {
255 if (tarindex >= targsize)
256 return (-1);
257 target[tarindex] |= (pos - Base64);
258 }
259 tarindex++;
260 state = 0;
261 break;
262 }
263 }
264
265 /*
266 * We are done decoding Base-64 chars. Let's see if we ended
267 * on a byte boundary, and/or with erroneous trailing characters.
268 */
269
270 if (ch == Pad64) { /* We got a pad char. */
271 ch = *src++; /* Skip it, get next. */
272 switch (state) {
273 case 0: /* Invalid = in first position */
274 case 1: /* Invalid = in second position */
275 return (-1);
276
277 case 2: /* Valid, means one byte of info */
278 /* Skip any number of spaces. */
279 for (; ch != '\0'; ch = *src++)
280 if (!isspace(ch))
281 break;
282 /* Make sure there is another trailing = sign. */
283 if (ch != Pad64)
284 return (-1);
285 ch = *src++; /* Skip the = */
286 /* Fall through to "single trailing =" case. */
287 /* FALLTHROUGH */
288
289 case 3: /* Valid, means two bytes of info */
290 /*
291 * We know this char is an =. Is there anything but
292 * whitespace after it?
293 */
294 for (; ch != '\0'; ch = *src++)
295 if (!isspace(ch))
296 return (-1);
297
298 /*
299 * Now make sure for cases 2 and 3 that the "extra"
300 * bits that slopped past the last full byte were
301 * zeros. If we don't check them, they become a
302 * subliminal channel.
303 */
304 if (target && target[tarindex] != 0)
305 return (-1);
306 }
307 } else {
308 /*
309 * We ended by seeing the end of the string. Make sure we
310 * have no partial bytes lying around.
311 */
312 if (state != 0)
313 return (-1);
314 }
315
316 return (tarindex);
317}
diff --git a/src/lib/libc/net/byteorder.3 b/src/lib/libc/net/byteorder.3
new file mode 100644
index 0000000000..f2788b25dc
--- /dev/null
+++ b/src/lib/libc/net/byteorder.3
@@ -0,0 +1,155 @@
1.\" $OpenBSD: byteorder.3,v 1.5 1997/11/19 23:30:17 niklas Exp $
2.\"
3.\" Copyright (c) 1983, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd June 4, 1993
35.Dt BYTEORDER 3
36.Os BSD 4.2
37.Sh NAME
38.Nm htonl ,
39.Nm htons ,
40.Nm ntohl ,
41.Nm ntohs ,
42.Nm htobe32 ,
43.Nm htobe16 ,
44.Nm betoh32 ,
45.Nm betoh16 ,
46.Nm htole32 ,
47.Nm htole16 ,
48.Nm letoh32 ,
49.Nm letoh16 ,
50.Nm swap32 ,
51.Nm swap16
52.Nd convert values between different byte orderings
53.Sh SYNOPSIS
54.Fd #include <sys/types.h>
55.Fd #include <machine/endian.h>
56.Ft u_int32_t
57.Fn htonl "u_int32_t host32"
58.Ft u_int16_t
59.Fn htons "u_int16_t host16"
60.Ft u_int32_t
61.Fn ntohl "u_int32_t net32"
62.Ft u_int16_t
63.Fn ntohs "u_int16_t net16"
64.Ft u_int32_t
65.Fn htobe32 "u_int32_t host32"
66.Ft u_int16_t
67.Fn htobe16 "u_int16_t host16"
68.Ft u_int32_t
69.Fn betoh32 "u_int32_t big32"
70.Ft u_int16_t
71.Fn betoh16 "u_int16_t big16"
72.Ft u_int32_t
73.Fn htole32 "u_int32_t host32"
74.Ft u_int16_t
75.Fn htole16 "u_int16_t host16"
76.Ft u_int32_t
77.Fn letoh32 "u_int32_t little32"
78.Ft u_int16_t
79.Fn letoh16 "u_int16_t little16"
80.Ft u_int32_t
81.Fn swap32 "u_int32_t val32"
82.Ft u_int16_t
83.Fn swap16 "u_int16_t val16"
84.Sh DESCRIPTION
85These routines convert 16 and 32 bit quantities between different
86byte orderings. The "swap" functions reverse the byte ordering of
87the given quantity, the others converts either from/to the native
88byte order used by the host to/from either little- or big-endian (a.k.a
89network) order.
90.Pp
91Apart from the "swap" functions, the names can be described by this form:
92{src-order}to{dst-order}{size}.
93Both {src-order} and {dst-order} can take the following forms:
94.Bl -tag -width "be "
95.It Em h
96host order
97.It Em n
98network order (big-endian)
99.It Em be
100big-endian (Most significant byte first)
101.It Em le
102little-endian (Least significant byte first)
103.El
104.Pp
105One of the specified orderings must be "h".
106{Size} will take these forms:
107.Bl -tag -width "32 "
108.It Em l
109long (32-bit, used in conjunction with forms involving "n")
110.It Em s
111short (16-bit, used in conjunction with forms involving "n")
112.It Em 16
11316-bit
114.It Em 32
11532-bit
116.El
117.Pp
118The "swap" functions are of the form: swap{size}.
119.Pp
120Names involving "n" convert quantities between network
121byte order and host byte order. The last letter (s/l) is a mnemonic
122for the traditional names for such quantities, short and long,
123respectively. Today, the C concept of "short"/"long" integers
124need not coincide with this traditional misunderstanding.
125On machines which have a byte order which is the same as the network
126order, routines are defined as null macros.
127.Pp
128The functions involving either "be", "le" or "swap" use the numbers
129(16/32) for specifying the bitwidth of the quantities they operate on.
130Currently all supported architectures are either big- or little-endian
131so either the "be" or the "le" variants are implemented as null macros.
132.Pp
133The routines mentioned above which have either {src-order} or {dst-order}
134set to "n" are most often used in
135conjunction with Internet addresses and ports as returned by
136.Xr gethostbyname 3
137and
138.Xr getservent 3 .
139.Sh SEE ALSO
140.Xr gethostbyname 3 ,
141.Xr getservent 3
142.Sh HISTORY
143The
144.Nm byteorder
145functions appeared in
146.Bx 4.2 .
147.Sh BUGS
148On the
149.Tn vax ,
150.Tn alpha ,
151.Tn i386 ,
152and so far
153.Tn mips
154bytes are handled backwards from most everyone else in
155the 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
new file mode 100644
index 0000000000..f5db308115
--- /dev/null
+++ b/src/lib/libc/net/ethers.3
@@ -0,0 +1,109 @@
1.\" $OpenBSD: ethers.3,v 1.9 1998/05/12 09:15:19 deraadt Exp $
2.\"
3.\" Written by roland@frob.com. Public domain.
4.\"
5.Dd December 16, 1993
6.Dt ETHERS 3
7.Os
8.Sh NAME
9.Nm ether_aton ,
10.Nm ether_ntoa ,
11.Nm ether_addr ,
12.Nm ether_ntohost ,
13.Nm ether_hostton ,
14.Nm ether_line
15.Nd get ethers entry
16.Sh SYNOPSIS
17.Fd #include <netinet/if_ether.h>
18.Ft char *
19.Fn ether_ntoa "struct ether_addr *e"
20.Ft struct ether_addr *
21.Fn ether_aton "char *s"
22.Ft int
23.Fn ether_ntohost "char *hostname" "struct ether_addr *e"
24.Ft int
25.Fn ether_hostton "char *hostname" "struct ether_addr *e"
26.Ft int
27.Fn ether_line "char *l" "struct ether_addr *e" "char *hostname"
28.Sh DESCRIPTION
29Ethernet addresses are represented by the
30following structure:
31.Bd -literal -offset indent
32struct ether_addr {
33 u_int8_t ether_addr_octet[6];
34};
35.Ed
36.Pp
37The
38.Fn ether_ntoa
39function converts this structure into an ASCII string of the form
40``xx:xx:xx:xx:xx:xx'', consisting of 6 hexadecimal numbers separated
41by colons. It returns a pointer to a static buffer that is reused for
42each call.
43The
44.Fn ether_aton
45converts an ASCII string of the same form and to a structure
46containing the 6 octets of the address. It returns a pointer to a
47static structure that is reused for each call.
48.Pp
49The
50.Fn ether_ntohost
51and
52.Fn ether_hostton
53functions interrogate the data base mapping host names to Ethernet
54addresses,
55.Pa /etc/ethers .
56The
57.Fn ether_ntohost
58function looks up the given Ethernet address and writes the associated
59host name into the character buffer passed. This buffer should be
60.Ev MAXHOSTNAMELEN
61characters in size.
62The
63.Fn ether_hostton
64function looks up the given host name and writes the associated
65Ethernet address into the structure passed. Both functions return
66zero if they find the requested host name or address, and -1 if not.
67.Pp
68Each call reads
69.Pa /etc/ethers
70from the beginning; if a + appears alone on a line in the file, then
71.Fn ether_hostton
72will consult the
73.Pa ethers.byname
74YP map, and
75.Fn ether_ntohost
76will consult the
77.Pa ethers.byaddr
78YP map.
79.Pp
80The
81.Fn ether_line
82function parses a line from the
83.Pa /etc/ethers
84file and fills in the passed ``struct ether_addr'' and character
85buffer with the Ethernet address and host name on the line. It
86returns zero if the line was successfully parsed and -1 if not.
87The character buffer buffer should be
88.Ev MAXHOSTNAMELEN
89characters in size.
90.Sh FILES
91.Bl -tag -width /etc/ethers -compact
92.It Pa /etc/ethers
93.El
94.Sh SEE ALSO
95.Xr ethers 5
96.Sh HISTORY
97The
98.Fn ether_ntoa ,
99.Fn ether_aton ,
100.Fn ether_ntohost ,
101.Fn ether_hostton ,
102and
103.Fn ether_line
104functions were adopted from SunOS and appeared in
105NetBSD 0.9b.
106.Sh BUGS
107The data space used by these functions is static; if future use
108requires the data, it should be copied before any subsequent calls to
109these functions overwrite it.
diff --git a/src/lib/libc/net/ethers.c b/src/lib/libc/net/ethers.c
new file mode 100644
index 0000000000..9df876b6f4
--- /dev/null
+++ b/src/lib/libc/net/ethers.c
@@ -0,0 +1,270 @@
1/* $OpenBSD: ethers.c,v 1.9 1998/06/21 22:13:44 millert Exp $ */
2
3/*
4 * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
19 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
20 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30/*
31 * ethers(3) a la Sun.
32 * Originally Written by Roland McGrath <roland@frob.com> 10/14/93.
33 * Substantially modified by Todd C. Miller <Todd.Miller@courtesan.com>
34 */
35
36#if defined(LIBC_SCCS) && !defined(lint)
37static char rcsid[] = "$OpenBSD: ethers.c,v 1.9 1998/06/21 22:13:44 millert Exp $";
38#endif /* LIBC_SCCS and not lint */
39
40#include <sys/types.h>
41#include <sys/socket.h>
42#include <net/if.h>
43#include <netinet/in.h>
44#include <netinet/if_ether.h>
45#include <sys/param.h>
46#include <paths.h>
47#include <errno.h>
48#include <stdio.h>
49#include <stdlib.h>
50#include <string.h>
51#include <ctype.h>
52
53#ifndef _PATH_ETHERS
54#define _PATH_ETHERS "/etc/ethers"
55#endif
56
57static char * _ether_aton __P((char *, struct ether_addr *));
58
59char *
60ether_ntoa(e)
61 struct ether_addr *e;
62{
63 static char a[] = "xx:xx:xx:xx:xx:xx";
64
65 if (e->ether_addr_octet[0] > 0xFF || e->ether_addr_octet[1] > 0xFF ||
66 e->ether_addr_octet[2] > 0xFF || e->ether_addr_octet[3] > 0xFF ||
67 e->ether_addr_octet[4] > 0xFF || e->ether_addr_octet[5] > 0xFF) {
68 errno = EINVAL;
69 return (NULL);
70 }
71
72 (void)sprintf(a, "%02x:%02x:%02x:%02x:%02x:%02x",
73 e->ether_addr_octet[0], e->ether_addr_octet[1],
74 e->ether_addr_octet[2], e->ether_addr_octet[3],
75 e->ether_addr_octet[4], e->ether_addr_octet[5]);
76
77 return (a);
78}
79
80static char *
81_ether_aton(s, e)
82 char *s;
83 struct ether_addr *e;
84{
85 int i;
86 long l;
87 char *pp;
88
89 while (isspace(*s))
90 s++;
91
92 /* expect 6 hex octets separated by ':' or space/NUL if last octet */
93 for (i = 0; i < 6; i++) {
94 l = strtol(s, &pp, 16);
95 if (pp == s || l > 0xFF)
96 return (NULL);
97 if (!(*pp == ':' || (i == 5 && (isspace(*pp) || *pp == '\0'))))
98 return (NULL);
99 e->ether_addr_octet[i] = (u_char)l;
100 s = pp + 1;
101 }
102
103 /* return character after the octets ala strtol(3) */
104 return (pp);
105}
106
107struct ether_addr *
108ether_aton(s)
109 char *s;
110{
111 static struct ether_addr n;
112
113 return (_ether_aton(s, &n) ? &n : NULL);
114}
115
116int
117ether_ntohost(hostname, e)
118 char *hostname;
119 struct ether_addr *e;
120{
121 FILE *f;
122 char buf[BUFSIZ+1], *p;
123 size_t len;
124 struct ether_addr try;
125#ifdef YP
126 char trybuf[sizeof("xx:xx:xx:xx:xx:xx")];
127 int trylen;
128#endif
129
130 if (e->ether_addr_octet[0] > 0xFF || e->ether_addr_octet[1] > 0xFF ||
131 e->ether_addr_octet[2] > 0xFF || e->ether_addr_octet[3] > 0xFF ||
132 e->ether_addr_octet[4] > 0xFF || e->ether_addr_octet[5] > 0xFF) {
133 errno = EINVAL;
134 return (-1);
135 }
136
137#ifdef YP
138 sprintf(trybuf, "%x:%x:%x:%x:%x:%x",
139 e->ether_addr_octet[0], e->ether_addr_octet[1],
140 e->ether_addr_octet[2], e->ether_addr_octet[3],
141 e->ether_addr_octet[4], e->ether_addr_octet[5]);
142 trylen = strlen(trybuf);
143#endif
144
145 f = fopen(_PATH_ETHERS, "r");
146 if (f == NULL)
147 return (-1);
148 while ((p = fgetln(f, &len)) != NULL) {
149 if (p[len-1] == '\n')
150 len--;
151 if (len > sizeof(buf) - 2)
152 continue;
153 (void)memcpy(buf, p, len);
154 buf[len] = '\n'; /* code assumes newlines later on */
155 buf[len+1] = '\0';
156#ifdef YP
157 /* A + in the file means try YP now. */
158 if (!strncmp(buf, "+\n", sizeof(buf))) {
159 char *ypbuf, *ypdom;
160 int ypbuflen;
161
162 if (yp_get_default_domain(&ypdom))
163 continue;
164 if (yp_match(ypdom, "ethers.byaddr", trybuf,
165 trylen, &ypbuf, &ypbuflen))
166 continue;
167 if (ether_line(ypbuf, &try, hostname) == 0) {
168 free(ypbuf);
169 (void)fclose(f);
170 return (0);
171 }
172 free(ypbuf);
173 continue;
174 }
175#endif
176 if (ether_line(buf, &try, hostname) == 0 &&
177 memcmp((void *)&try, (void *)e, sizeof(try)) == 0) {
178 (void)fclose(f);
179 return (0);
180 }
181 }
182 (void)fclose(f);
183 errno = ENOENT;
184 return (-1);
185}
186
187int
188ether_hostton(hostname, e)
189 char *hostname;
190 struct ether_addr *e;
191{
192 FILE *f;
193 char buf[BUFSIZ+1], *p;
194 char try[MAXHOSTNAMELEN];
195 size_t len;
196#ifdef YP
197 int hostlen = strlen(hostname);
198#endif
199
200 f = fopen(_PATH_ETHERS, "r");
201 if (f==NULL)
202 return (-1);
203
204 while ((p = fgetln(f, &len)) != NULL) {
205 if (p[len-1] == '\n')
206 len--;
207 if (len > sizeof(buf) - 2)
208 continue;
209 memcpy(buf, p, len);
210 buf[len] = '\n'; /* code assumes newlines later on */
211 buf[len+1] = '\0';
212#ifdef YP
213 /* A + in the file means try YP now. */
214 if (!strncmp(buf, "+\n", sizeof(buf))) {
215 char *ypbuf, *ypdom;
216 int ypbuflen;
217
218 if (yp_get_default_domain(&ypdom))
219 continue;
220 if (yp_match(ypdom, "ethers.byname", hostname, hostlen,
221 &ypbuf, &ypbuflen))
222 continue;
223 if (ether_line(ypbuf, e, try) == 0) {
224 free(ypbuf);
225 (void)fclose(f);
226 return (0);
227 }
228 free(ypbuf);
229 continue;
230 }
231#endif
232 if (ether_line(buf, e, try) == 0 && strcmp(hostname, try) == 0) {
233 (void)fclose(f);
234 return (0);
235 }
236 }
237 (void)fclose(f);
238 errno = ENOENT;
239 return (-1);
240}
241
242int
243ether_line(line, e, hostname)
244 char *line;
245 struct ether_addr *e;
246 char *hostname;
247{
248 char *p;
249 size_t n;
250
251 /* Parse "xx:xx:xx:xx:xx:xx" */
252 if ((p = _ether_aton(line, e)) == NULL || (*p != ' ' && *p != '\t'))
253 goto bad;
254
255 /* Now get the hostname */
256 while (isspace(*p))
257 p++;
258 if (*p == '\0')
259 goto bad;
260 n = strcspn(p, " \t\n");
261 if (n >= MAXHOSTNAMELEN)
262 goto bad;
263 (void)strncpy(hostname, p, n);
264 hostname[n] = '\0';
265 return (0);
266
267bad:
268 errno = EINVAL;
269 return (-1);
270}
diff --git a/src/lib/libc/net/gethostbyname.3 b/src/lib/libc/net/gethostbyname.3
new file mode 100644
index 0000000000..37069c0a59
--- /dev/null
+++ b/src/lib/libc/net/gethostbyname.3
@@ -0,0 +1,266 @@
1.\" $OpenBSD: gethostbyname.3,v 1.9 1998/09/07 16:44:35 aaron Exp $
2.\"
3.\" Copyright (c) 1983, 1987, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd March 13, 1997
35.Dt GETHOSTBYNAME 3
36.Os
37.Sh NAME
38.Nm gethostbyname ,
39.Nm gethostbyname2 ,
40.Nm gethostbyaddr ,
41.Nm gethostent ,
42.Nm sethostent ,
43.Nm endhostent ,
44.Nm hstrerror ,
45.Nm herror
46.Nd get network host entry
47.Sh SYNOPSIS
48.Fd #include <netdb.h>
49.Fd extern int h_errno;
50.Ft struct hostent *
51.Fn gethostbyname "const char *name"
52.Ft struct hostent *
53.Fn gethostbyname2 "const char *name" "int af"
54.Ft struct hostent *
55.Fn gethostbyaddr "const char *addr" "int len" "int type"
56.Ft struct hostent *
57.Fn gethostent void
58.Ft void
59.Fn sethostent "int stayopen"
60.Ft void
61.Fn endhostent void
62.Ft void
63.Fn herror "const char *string"
64.Ft const char *
65.Fn hstrerror "int err"
66.Sh DESCRIPTION
67The
68.Fn gethostbyname
69and
70.Fn gethostbyaddr
71functions
72each return a pointer to an object with the
73following structure describing an internet host
74referenced by name or by address, respectively.
75This structure contains either the information obtained from the name server,
76.Xr named 8 ,
77broken-out fields from a line in
78.Pa /etc/hosts ,
79or database entries supplied by the
80.Xr yp 8
81system .
82If the local name server is not running these routines do a lookup in
83.Pa /etc/hosts .
84.Bd -literal
85struct hostent {
86 char *h_name; /* official name of host */
87 char **h_aliases; /* alias list */
88 int h_addrtype; /* host address type */
89 int h_length; /* length of address */
90 char **h_addr_list; /* list of addresses from name server */
91};
92#define h_addr h_addr_list[0] /* address, for backward compatibility */
93.Ed
94.Pp
95The members of this structure are:
96.Bl -tag -width h_addr_list
97.It Fa h_name
98Official name of the host.
99.It Fa h_aliases
100A zero terminated array of alternate names for the host.
101.It Fa h_addrtype
102The type of address being returned.
103.It Fa h_length
104The length, in bytes, of the address.
105.It Fa h_addr_list
106A zero terminated array of network addresses for the host.
107Host addresses are returned in network byte order.
108.It Fa h_addr
109The first address in
110.Fa h_addr_list ;
111this is for backward compatibility.
112.El
113.Pp
114When using the nameserver,
115.Fn gethostbyname
116will search for the named host in the current domain and its parents
117unless the name ends in a dot.
118If the name contains no dot, and if the environment variable
119.Dq Ev HOSTALIASES
120contains the name of an alias file, the alias file will first be searched
121for an alias matching the input name.
122See
123.Xr hostname 7
124for the domain search procedure and the alias file format.
125.Pp
126.Fn Gethostbyname2
127is an advanced form of
128.Fn gethostbyname
129which allows lookups in address families other than
130.Dv AF_INET ,
131for example
132.Dv AF_INET6 .
133.Pp
134The
135.Fn sethostent
136function
137may be used to request the use of a connected
138.Tn TCP
139socket for queries.
140If the
141.Fa stayopen
142flag is non-zero,
143this sets the option to send all queries to the name server using
144.Tn TCP
145and to retain the connection after each call to
146.Fn gethostbyname
147or
148.Fn gethostbyaddr .
149Otherwise, queries are performed using
150.Tn UDP
151datagrams.
152.Pp
153The
154.Fn endhostent
155function
156closes the
157.Tn TCP
158connection.
159.Pp
160The
161.Fn herror
162function prints an error message describing the failure. If its argument
163.Fa string
164is
165.Pf non Dv -NULL ,
166it is prepended to the message string and separated from it by a colon
167and a space. The error message is printed with a trailing newline.
168The contents of the error message is the same as that returned by
169.Fn hstrerror
170with argument
171.Fa h_errno .
172.Sh FILES
173.Bl -tag -width /etc/hosts -compact
174.It Pa /etc/hosts
175.El
176.Sh DIAGNOSTICS
177Error return status from
178.Fn gethostbyname ,
179.Fn gethostbyname2 ,
180and
181.Fn gethostbyaddr
182is indicated by return of a null pointer.
183The external integer
184.Va h_errno
185may then be checked to see whether this is a temporary failure
186or an invalid or unknown host.
187.Pp
188The variable
189.Va h_errno
190can have the following values:
191.Bl -tag -width HOST_NOT_FOUND
192.It Dv HOST_NOT_FOUND
193No such host is known.
194.It Dv TRY_AGAIN
195This is usually a temporary error
196and means that the local server did not receive
197a response from an authoritative server.
198A retry at some later time may succeed.
199.It Dv NO_RECOVERY
200Some unexpected server failure was encountered.
201This is a non-recoverable error.
202.It Dv NO_DATA
203The requested name is valid but does not have an IP address;
204this is not a temporary error.
205This means that the name is known to the name server but there is no address
206associated with this name.
207Another type of request to the name server using this domain name
208will result in an answer;
209for example, a mail-forwarder may be registered for this domain.
210.El
211.Sh SEE ALSO
212.Xr resolver 3 ,
213.Xr hosts 5 ,
214.Xr hostname 7 ,
215.Xr named 8
216.Sh CAVEAT
217The
218.Fn gethostent
219function
220reads the next line of
221.Pa /etc/hosts ,
222opening the file if necessary.
223.Pp
224The
225.Fn sethostent
226function
227opens and/or rewinds the file
228.Pa /etc/hosts .
229If the
230.Fa stayopen
231argument is non-zero,
232the file will not be closed after each call to
233.Fn gethostbyname ,
234.Fn gethostbyname2 ,
235or
236.Fn gethostbyaddr .
237.Pp
238The
239.Fn endhostent
240function
241closes the file.
242.Sh HISTORY
243The
244.Fn herror
245function appeared in
246.Bx 4.3 .
247The
248.Fn endhostent ,
249.Fn gethostbyaddr ,
250.Fn gethostbyname ,
251.Fn gethostent ,
252and
253.Fn sethostent
254functions appeared in
255.Bx 4.2 .
256.Sh BUGS
257These functions use static data storage;
258if the data is needed for future use, it should be
259copied before any subsequent calls overwrite it.
260Only the Internet
261address formats are currently understood.
262.Pp
263YP does not support any address families other than
264.Dv AF_INET
265and uses
266the traditional database format.
diff --git a/src/lib/libc/net/gethostnamadr.c b/src/lib/libc/net/gethostnamadr.c
new file mode 100644
index 0000000000..7321225863
--- /dev/null
+++ b/src/lib/libc/net/gethostnamadr.c
@@ -0,0 +1,1079 @@
1/*-
2 * Copyright (c) 1985, 1988, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 * -
33 * Portions Copyright (c) 1993 by Digital Equipment Corporation.
34 *
35 * Permission to use, copy, modify, and distribute this software for any
36 * purpose with or without fee is hereby granted, provided that the above
37 * copyright notice and this permission notice appear in all copies, and that
38 * the name of Digital Equipment Corporation not be used in advertising or
39 * publicity pertaining to distribution of the document or software without
40 * specific, written prior permission.
41 *
42 * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
43 * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
44 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
45 * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
46 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
47 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
48 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
49 * SOFTWARE.
50 * -
51 * --Copyright--
52 */
53
54#if defined(LIBC_SCCS) && !defined(lint)
55static char rcsid[] = "$OpenBSD: gethostnamadr.c,v 1.30 1998/03/16 05:06:55 millert Exp $";
56#endif /* LIBC_SCCS and not lint */
57
58#include <sys/param.h>
59#include <sys/socket.h>
60#include <netinet/in.h>
61#include <arpa/inet.h>
62#include <arpa/nameser.h>
63#include <netdb.h>
64#include <resolv.h>
65#include <stdio.h>
66#include <ctype.h>
67#include <errno.h>
68#include <string.h>
69#include <syslog.h>
70#ifdef YP
71#include <rpc/rpc.h>
72#include <rpcsvc/yp.h>
73#include <rpcsvc/ypclnt.h>
74#include "ypinternal.h"
75#endif
76
77#define MULTI_PTRS_ARE_ALIASES 1 /* XXX - experimental */
78
79#define MAXALIASES 35
80#define MAXADDRS 35
81
82static char *h_addr_ptrs[MAXADDRS + 1];
83
84#ifdef YP
85static char *__ypdomain;
86#endif
87
88static struct hostent host;
89static char *host_aliases[MAXALIASES];
90static char hostbuf[BUFSIZ+1];
91static union {
92 struct in_addr _host_in_addr;
93 u_char _host_addr[16]; /* IPv4 or IPv6 */
94} _host_addr_u;
95#define host_addr _host_addr_u._host_addr
96static FILE *hostf = NULL;
97static int stayopen = 0;
98
99static void map_v4v6_address __P((const char *src, char *dst));
100static void map_v4v6_hostent __P((struct hostent *hp, char **bp, int *len));
101
102#ifdef RESOLVSORT
103static void addrsort __P((char **, int));
104#endif
105
106int _hokchar __P((const char *));
107
108static const char AskedForGot[] =
109 "gethostby*.getanswer: asked for \"%s\", got \"%s\"";
110
111#if PACKETSZ > 1024
112#define MAXPACKET PACKETSZ
113#else
114#define MAXPACKET 1024
115#endif
116
117typedef union {
118 HEADER hdr;
119 u_char buf[MAXPACKET];
120} querybuf;
121
122typedef union {
123 int32_t al;
124 char ac;
125} align;
126
127static struct hostent *getanswer __P((const querybuf *, int, const char *,
128 int));
129
130extern int h_errno;
131
132int
133_hokchar(p)
134 const char *p;
135{
136 char c;
137
138 /*
139 * Many people do not obey RFC 822 and 1035. The valid
140 * characters are a-z, A-Z, 0-9, '-' and . But the others
141 * tested for below can happen, and we must be more permissive
142 * than the resolver until those idiots clean up their act.
143 * We let '/' through, but not '..'
144 */
145 while ((c = *p++)) {
146 if (('a' <= c && c <= 'z') ||
147 ('A' <= c && c <= 'Z') ||
148 ('0' <= c && c <= '9'))
149 continue;
150 if (strchr("-_/", c))
151 continue;
152 if (c == '.' && *p != '.')
153 continue;
154 return 0;
155 }
156 return 1;
157}
158
159static struct hostent *
160getanswer(answer, anslen, qname, qtype)
161 const querybuf *answer;
162 int anslen;
163 const char *qname;
164 int qtype;
165{
166 register const HEADER *hp;
167 register const u_char *cp;
168 register int n;
169 const u_char *eom;
170 char *bp, **ap, **hap;
171 int type, class, buflen, ancount, qdcount;
172 int haveanswer, had_error;
173 int toobig = 0;
174 char tbuf[MAXDNAME];
175 const char *tname;
176 int (*name_ok) __P((const char *));
177
178 tname = qname;
179 host.h_name = NULL;
180 eom = answer->buf + anslen;
181 switch (qtype) {
182 case T_A:
183 case T_AAAA:
184#ifdef USE_RESOLV_NAME_OK
185 name_ok = res_hnok;
186 break;
187#endif
188 case T_PTR:
189#ifdef USE_RESOLV_NAME_OK
190 name_ok = res_dnok;
191#else
192 name_ok = _hokchar;
193#endif
194 break;
195 default:
196 return (NULL);
197 }
198 /*
199 * find first satisfactory answer
200 */
201 hp = &answer->hdr;
202 ancount = ntohs(hp->ancount);
203 qdcount = ntohs(hp->qdcount);
204 bp = hostbuf;
205 buflen = sizeof hostbuf;
206 cp = answer->buf + HFIXEDSZ;
207 if (qdcount != 1) {
208 h_errno = NO_RECOVERY;
209 return (NULL);
210 }
211 n = dn_expand(answer->buf, eom, cp, bp, buflen);
212 if ((n < 0) || !(*name_ok)(bp)) {
213 h_errno = NO_RECOVERY;
214 return (NULL);
215 }
216 cp += n + QFIXEDSZ;
217 if (qtype == T_A || qtype == T_AAAA) {
218 /* res_send() has already verified that the query name is the
219 * same as the one we sent; this just gets the expanded name
220 * (i.e., with the succeeding search-domain tacked on).
221 */
222 n = strlen(bp) + 1; /* for the \0 */
223 host.h_name = bp;
224 bp += n;
225 buflen -= n;
226 /* The qname can be abbreviated, but h_name is now absolute. */
227 qname = host.h_name;
228 }
229 ap = host_aliases;
230 *ap = NULL;
231 host.h_aliases = host_aliases;
232 hap = h_addr_ptrs;
233 *hap = NULL;
234 host.h_addr_list = h_addr_ptrs;
235 haveanswer = 0;
236 had_error = 0;
237 while (ancount-- > 0 && cp < eom && !had_error) {
238 n = dn_expand(answer->buf, eom, cp, bp, buflen);
239 if ((n < 0) || !(*name_ok)(bp)) {
240 had_error++;
241 continue;
242 }
243 cp += n; /* name */
244 type = _getshort(cp);
245 cp += INT16SZ; /* type */
246 class = _getshort(cp);
247 cp += INT16SZ + INT32SZ; /* class, TTL */
248 n = _getshort(cp);
249 cp += INT16SZ; /* len */
250 if (class != C_IN) {
251 /* XXX - debug? syslog? */
252 cp += n;
253 continue; /* XXX - had_error++ ? */
254 }
255 if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME) {
256 if (ap >= &host_aliases[MAXALIASES-1])
257 continue;
258 n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
259 if ((n < 0) || !(*name_ok)(tbuf)) {
260 had_error++;
261 continue;
262 }
263 cp += n;
264 /* Store alias. */
265 *ap++ = bp;
266 n = strlen(bp) + 1; /* for the \0 */
267 bp += n;
268 buflen -= n;
269 /* Get canonical name. */
270 n = strlen(tbuf) + 1; /* for the \0 */
271 if (n > buflen) {
272 had_error++;
273 continue;
274 }
275 strcpy(bp, tbuf);
276 host.h_name = bp;
277 bp += n;
278 buflen -= n;
279 continue;
280 }
281 if (qtype == T_PTR && type == T_CNAME) {
282 n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
283 if ((n < 0) || !res_hnok(tbuf)) {
284 had_error++;
285 continue;
286 }
287 cp += n;
288 /* Get canonical name. */
289 n = strlen(tbuf) + 1; /* for the \0 */
290 if (n > buflen) {
291 had_error++;
292 continue;
293 }
294 strcpy(bp, tbuf);
295 tname = bp;
296 bp += n;
297 buflen -= n;
298 continue;
299 }
300 if (type != qtype) {
301 syslog(LOG_NOTICE|LOG_AUTH,
302 "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",
303 qname, p_class(C_IN), p_type(qtype),
304 p_type(type));
305 cp += n;
306 continue; /* XXX - had_error++ ? */
307 }
308 switch (type) {
309 case T_PTR:
310 if (strcasecmp(tname, bp) != 0) {
311 syslog(LOG_NOTICE|LOG_AUTH,
312 AskedForGot, qname, bp);
313 cp += n;
314 continue; /* XXX - had_error++ ? */
315 }
316 n = dn_expand(answer->buf, eom, cp, bp, buflen);
317 if ((n < 0) || !res_hnok(bp)) {
318 had_error++;
319 break;
320 }
321#if MULTI_PTRS_ARE_ALIASES
322 cp += n;
323 if (!haveanswer)
324 host.h_name = bp;
325 else if (ap < &host_aliases[MAXALIASES-1])
326 *ap++ = bp;
327 else
328 n = -1;
329 if (n != -1) {
330 n = strlen(bp) + 1; /* for the \0 */
331 bp += n;
332 buflen -= n;
333 }
334 break;
335#else
336 host.h_name = bp;
337 if (_res.options & RES_USE_INET6) {
338 n = strlen(bp) + 1; /* for the \0 */
339 bp += n;
340 buflen -= n;
341 map_v4v6_hostent(&host, &bp, &buflen);
342 }
343 h_errno = NETDB_SUCCESS;
344 return (&host);
345#endif
346 case T_A:
347 case T_AAAA:
348 if (strcasecmp(host.h_name, bp) != 0) {
349 syslog(LOG_NOTICE|LOG_AUTH,
350 AskedForGot, host.h_name, bp);
351 cp += n;
352 continue; /* XXX - had_error++ ? */
353 }
354 if (n != host.h_length) {
355 cp += n;
356 continue;
357 }
358 if (!haveanswer) {
359 register int nn;
360
361 host.h_name = bp;
362 nn = strlen(bp) + 1; /* for the \0 */
363 bp += nn;
364 buflen -= nn;
365 }
366
367 bp += sizeof(align) - ((u_long)bp % sizeof(align));
368
369 if (bp + n >= &hostbuf[sizeof hostbuf]) {
370#ifdef DEBUG
371 if (_res.options & RES_DEBUG)
372 printf("size (%d) too big\n", n);
373#endif
374 had_error++;
375 continue;
376 }
377 if (hap >= &h_addr_ptrs[MAXADDRS-1]) {
378 if (!toobig++)
379#ifdef DEBUG
380 if (_res.options & RES_DEBUG)
381 printf("Too many addresses (%d)\n", MAXADDRS);
382#endif
383 cp += n;
384 continue;
385 }
386 bcopy(cp, *hap++ = bp, n);
387 bp += n;
388 buflen -= n;
389 cp += n;
390 break;
391 }
392 if (!had_error)
393 haveanswer++;
394 }
395 if (haveanswer) {
396 *ap = NULL;
397 *hap = NULL;
398# if defined(RESOLVSORT)
399 /*
400 * Note: we sort even if host can take only one address
401 * in its return structures - should give it the "best"
402 * address in that case, not some random one
403 */
404 if (_res.nsort && haveanswer > 1 && qtype == T_A)
405 addrsort(h_addr_ptrs, haveanswer);
406# endif /*RESOLVSORT*/
407 if (!host.h_name) {
408 n = strlen(qname) + 1; /* for the \0 */
409 if (n > buflen)
410 goto try_again;
411 strcpy(bp, qname);
412 host.h_name = bp;
413 bp += n;
414 buflen -= n;
415 }
416 if (_res.options & RES_USE_INET6)
417 map_v4v6_hostent(&host, &bp, &buflen);
418 h_errno = NETDB_SUCCESS;
419 return (&host);
420 }
421 try_again:
422 h_errno = TRY_AGAIN;
423 return (NULL);
424}
425
426struct hostent *
427gethostbyname(name)
428 const char *name;
429{
430 struct hostent *hp;
431 extern struct hostent *_gethtbyname2();
432
433 if ((_res.options & RES_INIT) == 0 && res_init() == -1)
434 return (_gethtbyname2(name, AF_INET));
435
436 if (_res.options & RES_USE_INET6) {
437 hp = gethostbyname2(name, AF_INET6);
438 if (hp)
439 return (hp);
440 }
441 return (gethostbyname2(name, AF_INET));
442}
443
444struct hostent *
445gethostbyname2(name, af)
446 const char *name;
447 int af;
448{
449 querybuf buf;
450 register const char *cp;
451 char *bp;
452 int n, size, type, len, i;
453 extern struct hostent *_gethtbyname2(), *_yp_gethtbyname();
454 register struct hostent *hp;
455 char lookups[MAXDNSLUS];
456
457 if ((_res.options & RES_INIT) == 0 && res_init() == -1)
458 return (_gethtbyname2(name, af));
459
460 switch (af) {
461 case AF_INET:
462 size = INADDRSZ;
463 type = T_A;
464 break;
465 case AF_INET6:
466 size = IN6ADDRSZ;
467 type = T_AAAA;
468 break;
469 default:
470 h_errno = NETDB_INTERNAL;
471 errno = EAFNOSUPPORT;
472 return (NULL);
473 }
474
475 host.h_addrtype = af;
476 host.h_length = size;
477
478 /*
479 * if there aren't any dots, it could be a user-level alias.
480 * this is also done in res_query() since we are not the only
481 * function that looks up host names.
482 */
483 if (!strchr(name, '.') && (cp = __hostalias(name)))
484 name = cp;
485
486 /*
487 * disallow names consisting only of digits/dots, unless
488 * they end in a dot.
489 */
490 if (isdigit(name[0]))
491 for (cp = name;; ++cp) {
492 if (!*cp) {
493 if (*--cp == '.')
494 break;
495 /*
496 * All-numeric, no dot at the end.
497 * Fake up a hostent as if we'd actually
498 * done a lookup.
499 */
500 if (inet_pton(af, name, host_addr) <= 0) {
501 h_errno = HOST_NOT_FOUND;
502 return (NULL);
503 }
504 strncpy(hostbuf, name, MAXHOSTNAMELEN-1);
505 hostbuf[MAXHOSTNAMELEN-1] = '\0';
506 bp = hostbuf + MAXHOSTNAMELEN;
507 len = sizeof hostbuf - MAXHOSTNAMELEN;
508 host.h_name = hostbuf;
509 host.h_aliases = host_aliases;
510 host_aliases[0] = NULL;
511 h_addr_ptrs[0] = (char *)host_addr;
512 h_addr_ptrs[1] = NULL;
513 host.h_addr_list = h_addr_ptrs;
514 if (_res.options & RES_USE_INET6)
515 map_v4v6_hostent(&host, &bp, &len);
516 h_errno = NETDB_SUCCESS;
517 return (&host);
518 }
519 if (!isdigit(*cp) && *cp != '.')
520 break;
521 }
522 if ((isxdigit(name[0]) && strchr(name, ':') != NULL) ||
523 name[0] == ':')
524 for (cp = name;; ++cp) {
525 if (!*cp) {
526 if (*--cp == '.')
527 break;
528 /*
529 * All-IPv6-legal, no dot at the end.
530 * Fake up a hostent as if we'd actually
531 * done a lookup.
532 */
533 if (inet_pton(af, name, host_addr) <= 0) {
534 h_errno = HOST_NOT_FOUND;
535 return (NULL);
536 }
537 strncpy(hostbuf, name, MAXHOSTNAMELEN-1);
538 hostbuf[MAXHOSTNAMELEN-1] = '\0';
539 bp = hostbuf + MAXHOSTNAMELEN;
540 len = sizeof hostbuf - MAXHOSTNAMELEN;
541 host.h_name = hostbuf;
542 host.h_aliases = host_aliases;
543 host_aliases[0] = NULL;
544 h_addr_ptrs[0] = (char *)host_addr;
545 h_addr_ptrs[1] = NULL;
546 host.h_addr_list = h_addr_ptrs;
547 h_errno = NETDB_SUCCESS;
548 return (&host);
549 }
550 if (!isxdigit(*cp) && *cp != ':' && *cp != '.')
551 break;
552 }
553
554 bcopy(_res.lookups, lookups, sizeof lookups);
555 if (lookups[0] == '\0')
556 strncpy(lookups, "bf", sizeof lookups);
557
558 hp = (struct hostent *)NULL;
559 for (i = 0; i < MAXDNSLUS && hp == NULL && lookups[i]; i++) {
560 switch (lookups[i]) {
561#ifdef YP
562 case 'y':
563 /* YP only supports AF_INET. */
564 if (af == AF_INET)
565 hp = _yp_gethtbyname(name);
566 break;
567#endif
568 case 'b':
569 if ((n = res_search(name, C_IN, type, buf.buf,
570 sizeof(buf))) < 0) {
571#ifdef DEBUG
572 if (_res.options & RES_DEBUG)
573 printf("res_search failed\n");
574#endif
575 break;
576 }
577 hp = getanswer(&buf, n, name, type);
578 break;
579 case 'f':
580 hp = _gethtbyname2(name, af);
581 break;
582 }
583 }
584 /* XXX h_errno not correct in all cases... */
585 return (hp);
586}
587
588struct hostent *
589gethostbyaddr(addr, len, af)
590 const char *addr; /* XXX should have been def'd as u_char! */
591 int len, af;
592{
593 const u_char *uaddr = (const u_char *)addr;
594 static const u_char mapped[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0xff,0xff };
595 static const u_char tunnelled[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 };
596 int n, size, i;
597 querybuf buf;
598 register struct hostent *hp;
599 char qbuf[MAXDNAME+1], *qp;
600 extern struct hostent *_gethtbyaddr(), *_yp_gethtbyaddr();
601 char lookups[MAXDNSLUS];
602
603 if ((_res.options & RES_INIT) == 0 && res_init() == -1)
604 return (_gethtbyaddr(addr, len, af));
605
606 if (af == AF_INET6 && len == IN6ADDRSZ &&
607 (!bcmp(uaddr, mapped, sizeof mapped) ||
608 !bcmp(uaddr, tunnelled, sizeof tunnelled))) {
609 /* Unmap. */
610 addr += sizeof mapped;
611 uaddr += sizeof mapped;
612 af = AF_INET;
613 len = INADDRSZ;
614 }
615 switch (af) {
616 case AF_INET:
617 size = INADDRSZ;
618 break;
619 case AF_INET6:
620 size = IN6ADDRSZ;
621 break;
622 default:
623 errno = EAFNOSUPPORT;
624 h_errno = NETDB_INTERNAL;
625 return (NULL);
626 }
627 if (size != len) {
628 errno = EINVAL;
629 h_errno = NETDB_INTERNAL;
630 return (NULL);
631 }
632 switch (af) {
633 case AF_INET:
634 (void) sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa",
635 (uaddr[3] & 0xff),
636 (uaddr[2] & 0xff),
637 (uaddr[1] & 0xff),
638 (uaddr[0] & 0xff));
639 break;
640 case AF_INET6:
641 qp = qbuf;
642 for (n = IN6ADDRSZ - 1; n >= 0; n--) {
643 qp += sprintf(qp, "%x.%x.",
644 uaddr[n] & 0xf,
645 (uaddr[n] >> 4) & 0xf);
646 }
647 strcpy(qp, "ip6.int");
648 break;
649 }
650
651 bcopy(_res.lookups, lookups, sizeof lookups);
652 if (lookups[0] == '\0')
653 strncpy(lookups, "bf", sizeof lookups);
654
655 hp = (struct hostent *)NULL;
656 for (i = 0; i < MAXDNSLUS && hp == NULL && lookups[i]; i++) {
657 switch (lookups[i]) {
658#ifdef YP
659 case 'y':
660 /* YP only supports AF_INET. */
661 if (af == AF_INET)
662 hp = _yp_gethtbyaddr(addr);
663 break;
664#endif
665 case 'b':
666 n = res_query(qbuf, C_IN, T_PTR, (u_char *)buf.buf,
667 sizeof buf.buf);
668 if (n < 0) {
669#ifdef DEBUG
670 if (_res.options & RES_DEBUG)
671 printf("res_query failed\n");
672#endif
673 break;
674 }
675 if (!(hp = getanswer(&buf, n, qbuf, T_PTR)))
676 break;
677 hp->h_addrtype = af;
678 hp->h_length = len;
679 bcopy(addr, host_addr, len);
680 h_addr_ptrs[0] = (char *)host_addr;
681 h_addr_ptrs[1] = NULL;
682 if (af == AF_INET && (_res.options & RES_USE_INET6)) {
683 map_v4v6_address((char*)host_addr,
684 (char*)host_addr);
685 hp->h_addrtype = AF_INET6;
686 hp->h_length = IN6ADDRSZ;
687 }
688 h_errno = NETDB_SUCCESS;
689 break;
690 case 'f':
691 hp = _gethtbyaddr(addr, len, af);
692 break;
693 }
694 }
695 /* XXX h_errno not correct in all cases... */
696 return (hp);
697}
698
699void
700_sethtent(f)
701 int f;
702{
703 if (hostf == NULL)
704 hostf = fopen(_PATH_HOSTS, "r" );
705 else
706 rewind(hostf);
707 stayopen = f;
708}
709
710void
711_endhtent()
712{
713 if (hostf && !stayopen) {
714 (void) fclose(hostf);
715 hostf = NULL;
716 }
717}
718
719struct hostent *
720_gethtent()
721{
722 char *p;
723 register char *cp, **q;
724 int af;
725 size_t len;
726
727 if (!hostf && !(hostf = fopen(_PATH_HOSTS, "r" ))) {
728 h_errno = NETDB_INTERNAL;
729 return (NULL);
730 }
731 again:
732 if ((p = fgetln(hostf, &len)) == NULL) {
733 h_errno = HOST_NOT_FOUND;
734 return (NULL);
735 }
736 if (p[len-1] == '\n')
737 len--;
738 if (len >= sizeof(hostbuf) || len == 0)
739 goto again;
740 p = memcpy(hostbuf, p, len);
741 hostbuf[len] = '\0';
742 if (*p == '#')
743 goto again;
744 if ((cp = strchr(p, '#')))
745 *cp = '\0';
746 if (!(cp = strpbrk(p, " \t")))
747 goto again;
748 *cp++ = '\0';
749 if ((_res.options & RES_USE_INET6) &&
750 inet_pton(AF_INET6, p, host_addr) > 0) {
751 af = AF_INET6;
752 len = IN6ADDRSZ;
753 } else if (inet_pton(AF_INET, p, host_addr) > 0) {
754 if (_res.options & RES_USE_INET6) {
755 map_v4v6_address((char*)host_addr, (char*)host_addr);
756 af = AF_INET6;
757 len = IN6ADDRSZ;
758 } else {
759 af = AF_INET;
760 len = INADDRSZ;
761 }
762 } else {
763 goto again;
764 }
765 h_addr_ptrs[0] = (char *)host_addr;
766 h_addr_ptrs[1] = NULL;
767 host.h_addr_list = h_addr_ptrs;
768 host.h_length = len;
769 host.h_addrtype = af;
770 while (*cp == ' ' || *cp == '\t')
771 cp++;
772 host.h_name = cp;
773 q = host.h_aliases = host_aliases;
774 if ((cp = strpbrk(cp, " \t")))
775 *cp++ = '\0';
776 while (cp && *cp) {
777 if (*cp == ' ' || *cp == '\t') {
778 cp++;
779 continue;
780 }
781 if (q < &host_aliases[MAXALIASES - 1])
782 *q++ = cp;
783 if ((cp = strpbrk(cp, " \t")))
784 *cp++ = '\0';
785 }
786 *q = NULL;
787 if (_res.options & RES_USE_INET6) {
788 char *bp = hostbuf;
789 int buflen = sizeof hostbuf;
790
791 map_v4v6_hostent(&host, &bp, &buflen);
792 }
793 h_errno = NETDB_SUCCESS;
794 return (&host);
795}
796
797struct hostent *
798_gethtbyname(name)
799 const char *name;
800{
801 extern struct hostent *_gethtbyname2();
802 struct hostent *hp;
803
804 if (_res.options & RES_USE_INET6) {
805 hp = _gethtbyname2(name, AF_INET6);
806 if (hp)
807 return (hp);
808 }
809 return (_gethtbyname2(name, AF_INET));
810}
811
812struct hostent *
813_gethtbyname2(name, af)
814 const char *name;
815 int af;
816{
817 register struct hostent *p;
818 register char **cp;
819
820 _sethtent(0);
821 while ((p = _gethtent())) {
822 if (p->h_addrtype != af)
823 continue;
824 if (strcasecmp(p->h_name, name) == 0)
825 break;
826 for (cp = p->h_aliases; *cp != 0; cp++)
827 if (strcasecmp(*cp, name) == 0)
828 goto found;
829 }
830 found:
831 _endhtent();
832 return (p);
833}
834
835struct hostent *
836_gethtbyaddr(addr, len, af)
837 const char *addr;
838 int len, af;
839{
840 register struct hostent *p;
841
842 _sethtent(0);
843 while ((p = _gethtent()))
844 if (p->h_addrtype == af && !bcmp(p->h_addr, addr, len))
845 break;
846 _endhtent();
847 return (p);
848}
849
850#ifdef YP
851struct hostent *
852_yphostent(line)
853 char *line;
854{
855 static struct in_addr host_addrs[MAXADDRS];
856 char *p = line;
857 char *cp, **q;
858 char **hap;
859 struct in_addr *buf;
860 int more;
861
862 host.h_name = NULL;
863 host.h_addr_list = h_addr_ptrs;
864 host.h_length = INADDRSZ;
865 host.h_addrtype = AF_INET;
866 hap = h_addr_ptrs;
867 buf = host_addrs;
868 q = host.h_aliases = host_aliases;
869
870nextline:
871 more = 0;
872 cp = strpbrk(p, " \t");
873 if (cp == NULL) {
874 if (host.h_name == NULL)
875 return (NULL);
876 else
877 goto done;
878 }
879 *cp++ = '\0';
880
881 *hap++ = (char *)buf;
882 (void) inet_aton(p, buf++);
883
884 while (*cp == ' ' || *cp == '\t')
885 cp++;
886 p = cp;
887 cp = strpbrk(p, " \t\n");
888 if (cp != NULL) {
889 if (*cp == '\n')
890 more = 1;
891 *cp++ = '\0';
892 }
893 if (!host.h_name)
894 host.h_name = p;
895 else if (strcmp(host.h_name, p)==0)
896 ;
897 else if (q < &host_aliases[MAXALIASES - 1])
898 *q++ = p;
899 p = cp;
900 if (more)
901 goto nextline;
902
903 while (cp && *cp) {
904 if (*cp == ' ' || *cp == '\t') {
905 cp++;
906 continue;
907 }
908 if (*cp == '\n') {
909 cp++;
910 goto nextline;
911 }
912 if (q < &host_aliases[MAXALIASES - 1])
913 *q++ = cp;
914 cp = strpbrk(cp, " \t");
915 if (cp != NULL)
916 *cp++ = '\0';
917 }
918done:
919 *q = NULL;
920 *hap = NULL;
921 return (&host);
922}
923
924struct hostent *
925_yp_gethtbyaddr(addr)
926 const char *addr;
927{
928 struct hostent *hp = (struct hostent *)NULL;
929 static char *__ypcurrent;
930 int __ypcurrentlen, r;
931 char name[sizeof("xxx.xxx.xxx.xxx") + 1];
932
933 if (!__ypdomain) {
934 if (_yp_check(&__ypdomain) == 0)
935 return (hp);
936 }
937 sprintf(name, "%u.%u.%u.%u",
938 ((unsigned)addr[0] & 0xff),
939 ((unsigned)addr[1] & 0xff),
940 ((unsigned)addr[2] & 0xff),
941 ((unsigned)addr[3] & 0xff));
942 if (__ypcurrent)
943 free(__ypcurrent);
944 __ypcurrent = NULL;
945 r = yp_match(__ypdomain, "hosts.byaddr", name,
946 strlen(name), &__ypcurrent, &__ypcurrentlen);
947 if (r==0)
948 hp = _yphostent(__ypcurrent);
949 if (hp==NULL)
950 h_errno = HOST_NOT_FOUND;
951 return (hp);
952}
953
954struct hostent *
955_yp_gethtbyname(name)
956 const char *name;
957{
958 struct hostent *hp = (struct hostent *)NULL;
959 static char *__ypcurrent;
960 int __ypcurrentlen, r;
961
962 if (strlen(name) >= MAXHOSTNAMELEN)
963 return (NULL);
964 if (!__ypdomain) {
965 if (_yp_check(&__ypdomain) == 0)
966 return (hp);
967 }
968 if (__ypcurrent)
969 free(__ypcurrent);
970 __ypcurrent = NULL;
971 r = yp_match(__ypdomain, "hosts.byname", name,
972 strlen(name), &__ypcurrent, &__ypcurrentlen);
973 if (r == 0)
974 hp = _yphostent(__ypcurrent);
975 if (hp == NULL)
976 h_errno = HOST_NOT_FOUND;
977 return (hp);
978}
979#endif
980
981static void
982map_v4v6_address(src, dst)
983 const char *src;
984 char *dst;
985{
986 u_char *p = (u_char *)dst;
987 char tmp[INADDRSZ];
988 int i;
989
990 /* Stash a temporary copy so our caller can update in place. */
991 bcopy(src, tmp, INADDRSZ);
992 /* Mark this ipv6 addr as a mapped ipv4. */
993 for (i = 0; i < 10; i++)
994 *p++ = 0x00;
995 *p++ = 0xff;
996 *p++ = 0xff;
997 /* Retrieve the saved copy and we're done. */
998 bcopy(tmp, (void*)p, INADDRSZ);
999}
1000
1001static void
1002map_v4v6_hostent(hp, bpp, lenp)
1003 struct hostent *hp;
1004 char **bpp;
1005 int *lenp;
1006{
1007 char **ap;
1008
1009 if (hp->h_addrtype != AF_INET || hp->h_length != INADDRSZ)
1010 return;
1011 hp->h_addrtype = AF_INET6;
1012 hp->h_length = IN6ADDRSZ;
1013 for (ap = hp->h_addr_list; *ap; ap++) {
1014 int i = sizeof(align) - ((u_long)*bpp % sizeof(align));
1015
1016 if (*lenp < (i + IN6ADDRSZ)) {
1017 /* Out of memory. Truncate address list here. XXX */
1018 *ap = NULL;
1019 return;
1020 }
1021 *bpp += i;
1022 *lenp -= i;
1023 map_v4v6_address(*ap, *bpp);
1024 *ap = *bpp;
1025 *bpp += IN6ADDRSZ;
1026 *lenp -= IN6ADDRSZ;
1027 }
1028}
1029
1030struct hostent *
1031gethostent()
1032{
1033 return (_gethtent());
1034}
1035
1036#ifdef RESOLVSORT
1037static void
1038addrsort(ap, num)
1039 char **ap;
1040 int num;
1041{
1042 int i, j;
1043 char **p;
1044 short aval[MAXADDRS];
1045 int needsort = 0;
1046
1047 p = ap;
1048 for (i = 0; i < num; i++, p++) {
1049 for (j = 0 ; (unsigned)j < _res.nsort; j++)
1050 if (_res.sort_list[j].addr.s_addr ==
1051 (((struct in_addr *)(*p))->s_addr & _res.sort_list[j].mask))
1052 break;
1053 aval[i] = j;
1054 if (needsort == 0 && i > 0 && j < aval[i-1])
1055 needsort = i;
1056 }
1057 if (!needsort)
1058 return;
1059
1060 while (needsort < num) {
1061 for (j = needsort - 1; j >= 0; j--) {
1062 if (aval[j] > aval[j+1]) {
1063 char *hp;
1064
1065 i = aval[j];
1066 aval[j] = aval[j+1];
1067 aval[j+1] = i;
1068
1069 hp = ap[j];
1070 ap[j] = ap[j+1];
1071 ap[j+1] = hp;
1072
1073 } else
1074 break;
1075 }
1076 needsort++;
1077 }
1078}
1079#endif
diff --git a/src/lib/libc/net/getnetbyaddr.c b/src/lib/libc/net/getnetbyaddr.c
new file mode 100644
index 0000000000..925d1d5895
--- /dev/null
+++ b/src/lib/libc/net/getnetbyaddr.c
@@ -0,0 +1,56 @@
1/*
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: getnetbyaddr.c,v 1.5 1997/07/09 01:08:28 millert Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <netdb.h>
39
40extern int _net_stayopen;
41
42struct netent *
43_getnetbyaddr(net, type)
44 register in_addr_t net;
45 register int type;
46{
47 register struct netent *p;
48
49 setnetent(_net_stayopen);
50 while ((p = getnetent()))
51 if (p->n_addrtype == type && p->n_net == net)
52 break;
53 if (!_net_stayopen)
54 endnetent();
55 return (p);
56}
diff --git a/src/lib/libc/net/getnetbyname.c b/src/lib/libc/net/getnetbyname.c
new file mode 100644
index 0000000000..4e39cf6860
--- /dev/null
+++ b/src/lib/libc/net/getnetbyname.c
@@ -0,0 +1,62 @@
1/*
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: getnetbyname.c,v 1.5 1997/07/09 01:08:29 millert Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <netdb.h>
39#include <string.h>
40
41extern int _net_stayopen;
42
43struct netent *
44_getnetbyname(name)
45 register const char *name;
46{
47 register struct netent *p;
48 register char **cp;
49
50 setnetent(_net_stayopen);
51 while ((p = getnetent())) {
52 if (strcasecmp(p->n_name, name) == 0)
53 break;
54 for (cp = p->n_aliases; *cp != 0; cp++)
55 if (strcasecmp(*cp, name) == 0)
56 goto found;
57 }
58found:
59 if (!_net_stayopen)
60 endnetent();
61 return (p);
62}
diff --git a/src/lib/libc/net/getnetent.3 b/src/lib/libc/net/getnetent.3
new file mode 100644
index 0000000000..5864b75839
--- /dev/null
+++ b/src/lib/libc/net/getnetent.3
@@ -0,0 +1,148 @@
1.\" $OpenBSD: getnetent.3,v 1.5 1998/03/16 05:06:56 millert Exp $
2.\"
3.\" Copyright (c) 1983, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd March 13, 1997
35.Dt GETNETENT 3
36.Os
37.Sh NAME
38.Nm getnetent ,
39.Nm getnetbyaddr ,
40.Nm getnetbyname ,
41.Nm setnetent ,
42.Nm endnetent
43.Nd get network entry
44.Sh SYNOPSIS
45.Fd #include <netdb.h>
46.Ft struct netent *
47.Fn getnetent
48.Ft struct netent *
49.Fn getnetbyname "char *name"
50.Ft struct netent *
51.Fn getnetbyaddr "in_addr_t net" "int type"
52.Fn setnetent "int stayopen"
53.Fn endnetent
54.Sh DESCRIPTION
55The
56.Fn getnetent ,
57.Fn getnetbyname ,
58and
59.Fn getnetbyaddr
60functions
61each return a pointer to an object with the
62following structure
63containing the broken-out
64fields of a line in the network data base,
65.Pa /etc/networks .
66.Bd -literal -offset indent
67struct netent {
68 char *n_name; /* official name of net */
69 char **n_aliases; /* alias list */
70 int n_addrtype; /* net number type */
71 in_addr_t n_net; /* net number */
72};
73.Ed
74.Pp
75The members of this structure are:
76.Bl -tag -width n_addrtype
77.It Fa n_name
78The official name of the network.
79.It Fa n_aliases
80A zero terminated list of alternate names for the network.
81.It Fa n_addrtype
82The type of the network number returned; currently only AF_INET.
83.It Fa n_net
84The network number. Network numbers are returned in machine byte
85order.
86.El
87.Pp
88The
89.Fn getnetent
90function
91reads the next line of the file, opening the file if necessary.
92.Pp
93The
94.Fn setnetent
95function
96opens and rewinds the file. If the
97.Fa stayopen
98flag is non-zero,
99the net data base will not be closed after each call to
100.Fn getnetbyname
101or
102.Fn getnetbyaddr .
103.Pp
104The
105.Fn endnetent
106function
107closes the file.
108.Pp
109The
110.Fn getnetbyname
111function
112and
113.Fn getnetbyaddr
114search the domain name server if the system is configured to use one.
115If the search fails, or no name server is configured, they sequentially
116search from the beginning of the file until a matching net name or
117net address and type is found, or until
118.Dv EOF
119is encountered.
120Network numbers are supplied in host order.
121.Sh FILES
122.Bl -tag -width /etc/networks -compact
123.It Pa /etc/networks
124.El
125.Sh DIAGNOSTICS
126Null pointer
127(0) returned on
128.Dv EOF
129or error.
130.Sh SEE ALSO
131.Xr networks 5 ,
132.Xr resolver 3
133.Sh HISTORY
134The
135.Fn getnetent ,
136.Fn getnetbyaddr ,
137.Fn getnetbyname ,
138.Fn setnetent ,
139and
140.Fn endnetent
141functions appeared in
142.Bx 4.2 .
143.Sh BUGS
144The data space used by these functions is static; if future use
145requires the data, it should be copied before any subsequent calls
146to these functions overwrite it. Only Internet network numbers
147are currently understood. Expecting network numbers to fit in no
148more than 32 bits is naive.
diff --git a/src/lib/libc/net/getnetent.c b/src/lib/libc/net/getnetent.c
new file mode 100644
index 0000000000..8f618a1d5e
--- /dev/null
+++ b/src/lib/libc/net/getnetent.c
@@ -0,0 +1,129 @@
1/*
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: getnetent.c,v 1.8 1998/03/16 05:06:57 millert Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/types.h>
39#include <sys/socket.h>
40#include <netinet/in.h>
41#include <arpa/inet.h>
42#include <netdb.h>
43#include <stdio.h>
44#include <string.h>
45
46#define MAXALIASES 35
47
48static FILE *netf;
49static char line[BUFSIZ+1];
50static struct netent net;
51static char *net_aliases[MAXALIASES];
52int _net_stayopen;
53
54void
55setnetent(f)
56 int f;
57{
58 if (netf == NULL)
59 netf = fopen(_PATH_NETWORKS, "r" );
60 else
61 rewind(netf);
62 _net_stayopen |= f;
63}
64
65void
66endnetent()
67{
68 if (netf) {
69 fclose(netf);
70 netf = NULL;
71 }
72 _net_stayopen = 0;
73}
74
75struct netent *
76getnetent()
77{
78 char *p, *cp, **q;
79 size_t len;
80
81 if (netf == NULL && (netf = fopen(_PATH_NETWORKS, "r" )) == NULL)
82 return (NULL);
83again:
84 if ((p = fgetln(netf, &len)) == NULL)
85 return (NULL);
86 if (p[len-1] == '\n')
87 len--;
88 if (len >= sizeof(line) || len == 0)
89 goto again;
90 p = memcpy(line, p, len);
91 line[len] = '\0';
92 if (*p == '#')
93 goto again;
94 if ((cp = strchr(p, '#')) != NULL)
95 *cp = '\0';
96 net.n_name = p;
97 if (strlen(net.n_name) >= MAXHOSTNAMELEN-1)
98 net.n_name[MAXHOSTNAMELEN-1] = '\0';
99 cp = strpbrk(p, " \t");
100 if (cp == NULL)
101 goto again;
102 *cp++ = '\0';
103 while (*cp == ' ' || *cp == '\t')
104 cp++;
105 p = strpbrk(cp, " \t");
106 if (p != NULL)
107 *p++ = '\0';
108 net.n_net = inet_network(cp);
109 net.n_addrtype = AF_INET;
110 q = net.n_aliases = net_aliases;
111 if (p != NULL)
112 cp = p;
113 while (cp && *cp) {
114 if (*cp == ' ' || *cp == '\t') {
115 cp++;
116 continue;
117 }
118 if (q < &net_aliases[MAXALIASES - 1]) {
119 *q++ = cp;
120 if (strlen(cp) >= MAXHOSTNAMELEN-1)
121 cp[MAXHOSTNAMELEN-1] = '\0';
122 }
123 cp = strpbrk(cp, " \t");
124 if (cp != NULL)
125 *cp++ = '\0';
126 }
127 *q = NULL;
128 return (&net);
129}
diff --git a/src/lib/libc/net/getnetnamadr.c b/src/lib/libc/net/getnetnamadr.c
new file mode 100644
index 0000000000..de208bbac9
--- /dev/null
+++ b/src/lib/libc/net/getnetnamadr.c
@@ -0,0 +1,382 @@
1/* $OpenBSD: getnetnamadr.c,v 1.10 1997/12/02 01:34:05 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 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by Jason Downs for the
17 * OpenBSD system.
18 * 4. Neither the name(s) of the author(s) nor the name OpenBSD
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS
23 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT,
26 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34/* Copyright (c) 1993 Carlos Leandro and Rui Salgueiro
35 * Dep. Matematica Universidade de Coimbra, Portugal, Europe
36 *
37 * Permission to use, copy, modify, and distribute this software for any
38 * purpose with or without fee is hereby granted, provided that the above
39 * copyright notice and this permission notice appear in all copies.
40 */
41/*
42 * Copyright (c) 1983, 1993
43 * The Regents of the University of California. All rights reserved.
44 *
45 * Redistribution and use in source and binary forms, with or without
46 * modification, are permitted provided that the following conditions
47 * are met:
48 * 1. Redistributions of source code must retain the above copyright
49 * notice, this list of conditions and the following disclaimer.
50 * 2. Redistributions in binary form must reproduce the above copyright
51 * notice, this list of conditions and the following disclaimer in the
52 * documentation and/or other materials provided with the distribution.
53 * 3. All advertising materials mentioning features or use of this software
54 * must display the following acknowledgement:
55 * This product includes software developed by the University of
56 * California, Berkeley and its contributors.
57 * 4. Neither the name of the University nor the names of its contributors
58 * may be used to endorse or promote products derived from this software
59 * without specific prior written permission.
60 *
61 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
62 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
63 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
64 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
65 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
66 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
67 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
68 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
69 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
70 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
71 * SUCH DAMAGE.
72 */
73
74#if defined(LIBC_SCCS) && !defined(lint)
75#if 0
76static char sccsid[] = "@(#)getnetbyaddr.c 8.1 (Berkeley) 6/4/93";
77static char sccsid_[] = "from getnetnamadr.c 1.4 (Coimbra) 93/06/03";
78static char rcsid[] = "$From: getnetnamadr.c,v 8.7 1996/08/05 08:31:35 vixie Exp $";
79#else
80static char rcsid[] = "$OpenBSD: getnetnamadr.c,v 1.10 1997/12/02 01:34:05 deraadt Exp $";
81#endif
82#endif /* LIBC_SCCS and not lint */
83
84#include <sys/types.h>
85#include <sys/param.h>
86#include <sys/socket.h>
87#include <netinet/in.h>
88#include <arpa/inet.h>
89#include <arpa/nameser.h>
90
91#include <stdio.h>
92#include <netdb.h>
93#include <resolv.h>
94#include <ctype.h>
95#include <errno.h>
96#include <string.h>
97
98extern int h_errno;
99
100struct netent *_getnetbyaddr __P((in_addr_t net, int type));
101struct netent *_getnetbyname __P((const char *name));
102
103int _hokchar __P((const char *));
104
105#define BYADDR 0
106#define BYNAME 1
107#define MAXALIASES 35
108
109#if PACKETSZ > 1024
110#define MAXPACKET PACKETSZ
111#else
112#define MAXPACKET 1024
113#endif
114
115typedef union {
116 HEADER hdr;
117 u_char buf[MAXPACKET];
118} querybuf;
119
120typedef union {
121 long al;
122 char ac;
123} align;
124
125static struct netent *
126getnetanswer(answer, anslen, net_i)
127 querybuf *answer;
128 int anslen;
129 int net_i;
130{
131
132 register HEADER *hp;
133 register u_char *cp;
134 register int n;
135 u_char *eom;
136 int type, class, buflen, ancount, qdcount, haveanswer, i, nchar;
137 char aux1[MAXHOSTNAMELEN], aux2[MAXHOSTNAMELEN], ans[MAXHOSTNAMELEN];
138 char *in, *st, *pauxt, *bp, **ap;
139 char *paux1 = &aux1[0], *paux2 = &aux2[0], flag = 0;
140 static struct netent net_entry;
141 static char *net_aliases[MAXALIASES], netbuf[BUFSIZ+1];
142
143 /*
144 * find first satisfactory answer
145 *
146 * answer --> +------------+ ( MESSAGE )
147 * | Header |
148 * +------------+
149 * | Question | the question for the name server
150 * +------------+
151 * | Answer | RRs answering the question
152 * +------------+
153 * | Authority | RRs pointing toward an authority
154 * | Additional | RRs holding additional information
155 * +------------+
156 */
157 eom = answer->buf + anslen;
158 hp = &answer->hdr;
159 ancount = ntohs(hp->ancount); /* #/records in the answer section */
160 qdcount = ntohs(hp->qdcount); /* #/entries in the question section */
161 bp = netbuf;
162 buflen = sizeof(netbuf);
163 cp = answer->buf + HFIXEDSZ;
164 if (!qdcount) {
165 if (hp->aa)
166 h_errno = HOST_NOT_FOUND;
167 else
168 h_errno = TRY_AGAIN;
169 return (NULL);
170 }
171 while (qdcount-- > 0)
172 cp += __dn_skipname(cp, eom) + QFIXEDSZ;
173 ap = net_aliases;
174 *ap = NULL;
175 net_entry.n_aliases = net_aliases;
176 haveanswer = 0;
177 while (--ancount >= 0 && cp < eom) {
178 n = dn_expand(answer->buf, eom, cp, bp, buflen);
179#ifdef USE_RESOLV_NAME_OK
180 if ((n < 0) || !res_dnok(bp))
181#else
182 if ((n < 0) || !_hokchar(bp))
183#endif
184 break;
185 cp += n;
186 ans[0] = '\0';
187 (void)strncpy(&ans[0], bp, sizeof ans-1);
188 ans[sizeof ans-1] = '\0';
189 GETSHORT(type, cp);
190 GETSHORT(class, cp);
191 cp += INT32SZ; /* TTL */
192 GETSHORT(n, cp);
193 if (class == C_IN && type == T_PTR) {
194 n = dn_expand(answer->buf, eom, cp, bp, buflen);
195 if ((n < 0) || !res_hnok(bp)) {
196 cp += n;
197 return (NULL);
198 }
199 cp += n;
200 *ap++ = bp;
201 bp += strlen(bp) + 1;
202 net_entry.n_addrtype =
203 (class == C_IN) ? AF_INET : AF_UNSPEC;
204 haveanswer++;
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 in = *net_entry.n_aliases;
216 net_entry.n_name = &ans[0];
217 aux2[0] = '\0';
218 for (i = 0; i < 4; i++) {
219 for (st = in, nchar = 0;
220 *st != '.';
221 st++, nchar++)
222 ;
223 if (nchar != 1 || *in != '0' || flag) {
224 flag = 1;
225 (void)strncpy(paux1,
226 (i==0) ? in : in-1,
227 (i==0) ?nchar : nchar+1);
228 paux1[(i==0) ? nchar : nchar+1] = '\0';
229 pauxt = paux2;
230 paux2 = strcat(paux1, paux2);
231 paux1 = pauxt;
232 }
233 in = ++st;
234 }
235 net_entry.n_net = inet_network(paux2);
236 break;
237 }
238 net_entry.n_aliases++;
239 return (&net_entry);
240 }
241 h_errno = TRY_AGAIN;
242 return (NULL);
243}
244
245struct netent *
246getnetbyaddr(net, net_type)
247 register in_addr_t net;
248 register int net_type;
249{
250 unsigned int netbr[4];
251 int nn, anslen;
252 querybuf buf;
253 char qbuf[MAXDNAME];
254 in_addr_t net2;
255 struct netent *net_entry = NULL;
256 char lookups[MAXDNSLUS];
257 int i;
258
259 if ((_res.options & RES_INIT) == 0 && res_init() == -1)
260 return(_getnetbyaddr(net, net_type));
261
262 bcopy(_res.lookups, lookups, sizeof lookups);
263 if (lookups[0] == '\0')
264 strncpy(lookups, "bf", sizeof lookups);
265
266 for (i = 0; i < MAXDNSLUS && lookups[i]; i++) {
267 switch (lookups[i]) {
268#ifdef YP
269 case 'y':
270 /* There is no YP support. */
271 break;
272#endif /* YP */
273 case 'b':
274 if (net_type != AF_INET)
275 break; /* DNS only supports AF_INET? */
276
277 for (nn = 4, net2 = net; net2; net2 >>= 8)
278 netbr[--nn] = net2 & 0xff;
279 switch (nn) {
280 case 3: /* Class A */
281 snprintf(qbuf, sizeof(qbuf),
282 "0.0.0.%u.in-addr.arpa", netbr[3]);
283 break;
284 case 2: /* Class B */
285 snprintf(qbuf, sizeof(qbuf),
286 "0.0.%u.%u.in-addr.arpa",
287 netbr[3], netbr[2]);
288 break;
289 case 1: /* Class C */
290 snprintf(qbuf, sizeof(qbuf),
291 "0.%u.%u.%u.in-addr.arpa",
292 netbr[3], netbr[2], netbr[1]);
293 break;
294 case 0: /* Class D - E */
295 snprintf(qbuf, sizeof(qbuf),
296 "%u.%u.%u.%u.in-addr.arpa",
297 netbr[3], netbr[2], netbr[1], netbr[0]);
298 break;
299 }
300 anslen = res_query(qbuf, C_IN, T_PTR, (u_char *)&buf,
301 sizeof(buf));
302 if (anslen < 0) {
303#ifdef DEBUG
304 if (_res.options & RES_DEBUG)
305 printf("res_query failed\n");
306#endif
307 break;
308 }
309 net_entry = getnetanswer(&buf, anslen, BYADDR);
310 if (net_entry != NULL) {
311 unsigned u_net = net; /* maybe net should be unsigned ? */
312
313 /* Strip trailing zeros */
314 while ((u_net & 0xff) == 0 && u_net != 0)
315 u_net >>= 8;
316 net_entry->n_net = u_net;
317 return (net_entry);
318 }
319 break;
320 case 'f':
321 net_entry = _getnetbyaddr(net, net_type);
322 if (net_entry != NULL)
323 return (net_entry);
324 }
325 }
326
327 /* Nothing matched. */
328 return (NULL);
329}
330
331struct netent *
332getnetbyname(net)
333 register const char *net;
334{
335 int anslen;
336 querybuf buf;
337 char qbuf[MAXDNAME];
338 struct netent *net_entry = NULL;
339 char lookups[MAXDNSLUS];
340 int i;
341
342 if ((_res.options & RES_INIT) == 0 && res_init() == -1)
343 return (_getnetbyname(net));
344
345 bcopy(_res.lookups, lookups, sizeof lookups);
346 if (lookups[0] == '\0')
347 strncpy(lookups, "bf", sizeof lookups);
348
349 for (i = 0; i < MAXDNSLUS && lookups[i]; i++) {
350 switch (lookups[i]) {
351#ifdef YP
352 case 'y':
353 /* There is no YP support. */
354 break;
355#endif /* YP */
356 case 'b':
357 strncpy(qbuf, net, sizeof qbuf-1);
358 qbuf[sizeof qbuf-1] = '\0';
359 anslen = res_search(qbuf, C_IN, T_PTR, (u_char *)&buf,
360 sizeof(buf));
361 if (anslen < 0) {
362#ifdef DEBUG
363 if (_res.options & RES_DEBUG)
364 printf("res_query failed\n");
365#endif
366 break;
367 }
368 net_entry = getnetanswer(&buf, anslen, BYNAME);
369 if (net_entry != NULL)
370 return (net_entry);
371 break;
372 case 'f':
373 net_entry = _getnetbyname(net);
374 if (net_entry != NULL)
375 return (net_entry);
376 break;
377 }
378 }
379
380 /* Nothing matched. */
381 return (NULL);
382}
diff --git a/src/lib/libc/net/getproto.c b/src/lib/libc/net/getproto.c
new file mode 100644
index 0000000000..474d8d9427
--- /dev/null
+++ b/src/lib/libc/net/getproto.c
@@ -0,0 +1,55 @@
1/*
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: getproto.c,v 1.3 1997/07/09 01:08:31 millert Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <netdb.h>
39
40extern int _proto_stayopen;
41
42struct protoent *
43getprotobynumber(proto)
44 register int proto;
45{
46 register struct protoent *p;
47
48 setprotoent(_proto_stayopen);
49 while ((p = getprotoent()))
50 if (p->p_proto == proto)
51 break;
52 if (!_proto_stayopen)
53 endprotoent();
54 return (p);
55}
diff --git a/src/lib/libc/net/getprotoent.3 b/src/lib/libc/net/getprotoent.3
new file mode 100644
index 0000000000..f67987954f
--- /dev/null
+++ b/src/lib/libc/net/getprotoent.3
@@ -0,0 +1,144 @@
1.\" $OpenBSD: getprotoent.3,v 1.2 1996/08/19 08:28:50 tholo Exp $
2.\"
3.\" Copyright (c) 1983, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd June 4, 1993
35.Dt GETPROTOENT 3
36.Os BSD 4.2
37.Sh NAME
38.Nm getprotoent ,
39.Nm getprotobynumber ,
40.Nm getprotobyname ,
41.Nm setprotoent ,
42.Nm endprotoent
43.Nd get protocol entry
44.Sh SYNOPSIS
45.Fd #include <netdb.h>
46.Ft struct protoent *
47.Fn getprotoent
48.Ft struct protoent *
49.Fn getprotobyname "char *name"
50.Ft struct protoent *
51.Fn getprotobynumber "int proto"
52.Fn setprotoent "int stayopen"
53.Fn endprotoent
54.Sh DESCRIPTION
55The
56.Fn getprotoent ,
57.Fn getprotobyname ,
58and
59.Fn getprotobynumber
60functions
61each return a pointer to an object with the
62following structure
63containing the broken-out
64fields of a line in the network protocol data base,
65.Pa /etc/protocols .
66.Bd -literal -offset indent
67.Pp
68struct protoent {
69 char *p_name; /* official name of protocol */
70 char **p_aliases; /* alias list */
71 int p_proto; /* protocol number */
72};
73.Ed
74.Pp
75The members of this structure are:
76.Bl -tag -width p_aliases
77.It Fa p_name
78The official name of the protocol.
79.It Fa p_aliases
80A zero terminated list of alternate names for the protocol.
81.It Fa p_proto
82The protocol number.
83.El
84.Pp
85The
86.Fn getprotoent
87function
88reads the next line of the file, opening the file if necessary.
89.Pp
90The
91.Fn setprotoent
92function
93opens and rewinds the file. If the
94.Fa stayopen
95flag is non-zero,
96the net data base will not be closed after each call to
97.Fn getprotobyname
98or
99.Fn getprotobynumber .
100.Pp
101The
102.Fn endprotoent
103function
104closes the file.
105.Pp
106The
107.Fn getprotobyname
108function
109and
110.Fn getprotobynumber
111sequentially search from the beginning
112of the file until a matching
113protocol name or
114protocol number is found,
115or until
116.Dv EOF
117is encountered.
118.Sh RETURN VALUES
119Null pointer
120(0) returned on
121.Dv EOF
122or error.
123.Sh FILES
124.Bl -tag -width /etc/protocols -compact
125.It Pa /etc/protocols
126.El
127.Sh SEE ALSO
128.Xr protocols 5
129.Sh HISTORY
130The
131.Fn getprotoent ,
132.Fn getprotobynumber ,
133.Fn getprotobyname ,
134.Fn setprotoent ,
135and
136.Fn endprotoent
137functions appeared in
138.Bx 4.2 .
139.Sh BUGS
140These functions use a static data space;
141if the data is needed for future use, it should be
142copied before any subsequent calls overwrite it.
143Only the Internet
144protocols are currently understood.
diff --git a/src/lib/libc/net/getprotoent.c b/src/lib/libc/net/getprotoent.c
new file mode 100644
index 0000000000..2bef526e7a
--- /dev/null
+++ b/src/lib/libc/net/getprotoent.c
@@ -0,0 +1,123 @@
1/*
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: getprotoent.c,v 1.3 1998/03/16 05:06:59 millert Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/types.h>
39#include <sys/socket.h>
40#include <netdb.h>
41#include <stdio.h>
42#include <stdlib.h>
43#include <string.h>
44
45#define MAXALIASES 35
46
47static FILE *protof = NULL;
48static char line[BUFSIZ+1];
49static struct protoent proto;
50static char *proto_aliases[MAXALIASES];
51int _proto_stayopen;
52
53void
54setprotoent(f)
55 int f;
56{
57 if (protof == NULL)
58 protof = fopen(_PATH_PROTOCOLS, "r" );
59 else
60 rewind(protof);
61 _proto_stayopen |= f;
62}
63
64void
65endprotoent()
66{
67 if (protof) {
68 fclose(protof);
69 protof = NULL;
70 }
71 _proto_stayopen = 0;
72}
73
74struct protoent *
75getprotoent()
76{
77 char *p, *cp, **q;
78 size_t len;
79
80 if (protof == NULL && (protof = fopen(_PATH_PROTOCOLS, "r" )) == NULL)
81 return (NULL);
82again:
83 if ((p = fgetln(protof, &len)) == NULL)
84 return (NULL);
85 if (p[len-1] == '\n')
86 len--;
87 if (len >= sizeof(line) || len == 0)
88 goto again;
89 p = memcpy(line, p, len);
90 line[len] = '\0';
91 if (*p == '#')
92 goto again;
93 if ((cp = strchr(p, '#')) != NULL)
94 *cp = '\0';
95 proto.p_name = p;
96 cp = strpbrk(p, " \t");
97 if (cp == NULL)
98 goto again;
99 *cp++ = '\0';
100 while (*cp == ' ' || *cp == '\t')
101 cp++;
102 p = strpbrk(cp, " \t");
103 if (p != NULL)
104 *p++ = '\0';
105 proto.p_proto = atoi(cp);
106 q = proto.p_aliases = proto_aliases;
107 if (p != NULL) {
108 cp = p;
109 while (cp && *cp) {
110 if (*cp == ' ' || *cp == '\t') {
111 cp++;
112 continue;
113 }
114 if (q < &proto_aliases[MAXALIASES - 1])
115 *q++ = cp;
116 cp = strpbrk(cp, " \t");
117 if (cp != NULL)
118 *cp++ = '\0';
119 }
120 }
121 *q = NULL;
122 return (&proto);
123}
diff --git a/src/lib/libc/net/getprotoname.c b/src/lib/libc/net/getprotoname.c
new file mode 100644
index 0000000000..7a4e5fede5
--- /dev/null
+++ b/src/lib/libc/net/getprotoname.c
@@ -0,0 +1,62 @@
1/*
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: getprotoname.c,v 1.3 1997/07/09 01:08:32 millert Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <netdb.h>
39#include <string.h>
40
41extern int _proto_stayopen;
42
43struct protoent *
44getprotobyname(name)
45 register const char *name;
46{
47 register struct protoent *p;
48 register char **cp;
49
50 setprotoent(_proto_stayopen);
51 while ((p = getprotoent())) {
52 if (strcmp(p->p_name, name) == 0)
53 break;
54 for (cp = p->p_aliases; *cp != 0; cp++)
55 if (strcmp(*cp, name) == 0)
56 goto found;
57 }
58found:
59 if (!_proto_stayopen)
60 endprotoent();
61 return (p);
62}
diff --git a/src/lib/libc/net/getservbyname.c b/src/lib/libc/net/getservbyname.c
new file mode 100644
index 0000000000..25f0e27d06
--- /dev/null
+++ b/src/lib/libc/net/getservbyname.c
@@ -0,0 +1,65 @@
1/*
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: getservbyname.c,v 1.3 1997/07/09 01:08:34 millert Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <netdb.h>
39#include <string.h>
40
41extern int _serv_stayopen;
42
43struct servent *
44getservbyname(name, proto)
45 const char *name, *proto;
46{
47 register struct servent *p;
48 register char **cp;
49
50 setservent(_serv_stayopen);
51 while ((p = getservent())) {
52 if (strcmp(name, p->s_name) == 0)
53 goto gotname;
54 for (cp = p->s_aliases; *cp; cp++)
55 if (strcmp(name, *cp) == 0)
56 goto gotname;
57 continue;
58gotname:
59 if (proto == 0 || strcmp(p->s_proto, proto) == 0)
60 break;
61 }
62 if (!_serv_stayopen)
63 endservent();
64 return (p);
65}
diff --git a/src/lib/libc/net/getservbyport.c b/src/lib/libc/net/getservbyport.c
new file mode 100644
index 0000000000..4b063760d2
--- /dev/null
+++ b/src/lib/libc/net/getservbyport.c
@@ -0,0 +1,60 @@
1/*
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: getservbyport.c,v 1.3 1997/07/09 01:08:35 millert Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <netdb.h>
39#include <string.h>
40
41extern int _serv_stayopen;
42
43struct servent *
44getservbyport(port, proto)
45 int port;
46 const char *proto;
47{
48 register struct servent *p;
49
50 setservent(_serv_stayopen);
51 while ((p = getservent())) {
52 if (p->s_port != port)
53 continue;
54 if (proto == 0 || strcmp(p->s_proto, proto) == 0)
55 break;
56 }
57 if (!_serv_stayopen)
58 endservent();
59 return (p);
60}
diff --git a/src/lib/libc/net/getservent.3 b/src/lib/libc/net/getservent.3
new file mode 100644
index 0000000000..d1684c28c4
--- /dev/null
+++ b/src/lib/libc/net/getservent.3
@@ -0,0 +1,155 @@
1.\" $OpenBSD: getservent.3,v 1.3 1996/08/30 02:00:11 millert Exp $
2.\"
3.\" Copyright (c) 1983, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd January 12, 1994
35.Dt GETSERVENT 3
36.Os BSD 4.2
37.Sh NAME
38.Nm getservent ,
39.Nm getservbyport ,
40.Nm getservbyname ,
41.Nm setservent ,
42.Nm endservent
43.Nd get service entry
44.Sh SYNOPSIS
45.Fd #include <netdb.h>
46.Ft struct servent *
47.Fn getservent
48.Ft struct servent *
49.Fn getservbyname "char *name" "char *proto"
50.Ft struct servent *
51.Fn getservbyport "int port" "char *proto"
52.Ft void
53.Fn setservent "int stayopen"
54.Ft void
55.Fn endservent void
56.Sh DESCRIPTION
57The
58.Fn getservent ,
59.Fn getservbyname ,
60and
61.Fn getservbyport
62functions
63each return a pointer to an object with the
64following structure
65containing the broken-out
66fields of a line in the network services data base,
67.Pa /etc/services .
68.Bd -literal -offset indent
69struct servent {
70 char *s_name; /* official name of service */
71 char **s_aliases; /* alias list */
72 int s_port; /* port service resides at */
73 char *s_proto; /* protocol to use */
74};
75.Ed
76.Pp
77The members of this structure are:
78.Bl -tag -width s_aliases
79.It Fa s_name
80The official name of the service.
81.It Fa s_aliases
82A zero terminated list of alternate names for the service.
83.It Fa s_port
84The port number at which the service resides.
85Port numbers are returned in network byte order.
86.It Fa s_proto
87The name of the protocol to use when contacting the
88service.
89.El
90.Pp
91The
92.Fn getservent
93function
94reads the next line of the file, opening the file if necessary.
95.Pp
96The
97.Fn setservent
98function
99opens and rewinds the file. If the
100.Fa stayopen
101flag is non-zero,
102the net data base will not be closed after each call to
103.Fn getservbyname
104or
105.Fn getservbyport .
106.Pp
107The
108.Fn endservent
109function
110closes the file.
111.Pp
112The
113.Fn getservbyname
114and
115.Fn getservbyport
116functions
117sequentially search from the beginning
118of the file until a matching
119protocol name or
120port number is found,
121or until
122.Dv EOF
123is encountered.
124If a protocol name is also supplied (non-
125.Dv NULL ) ,
126searches must also match the protocol.
127.ne 1i
128.Sh FILES
129.Bl -tag -width /etc/services -compact
130.It Pa /etc/services
131.El
132.Sh DIAGNOSTICS
133Null pointer
134(0) returned on
135.Dv EOF
136or error.
137.Sh SEE ALSO
138.Xr getprotoent 3 ,
139.Xr services 5
140.Sh HISTORY
141The
142.Fn getservent ,
143.Fn getservbyport ,
144.Fn getservbyname ,
145.Fn setservent ,
146and
147.Fn endservent
148functions appeared in
149.Bx 4.2 .
150.Sh BUGS
151These functions use static data storage;
152if the data is needed for future use, it should be
153copied before any subsequent calls overwrite it.
154Expecting port numbers to fit in a 32 bit
155quantity is probably naive.
diff --git a/src/lib/libc/net/getservent.c b/src/lib/libc/net/getservent.c
new file mode 100644
index 0000000000..7d8cb6d8ca
--- /dev/null
+++ b/src/lib/libc/net/getservent.c
@@ -0,0 +1,125 @@
1/*
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: getservent.c,v 1.4 1998/03/16 05:07:00 millert Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/types.h>
39#include <sys/socket.h>
40#include <netdb.h>
41#include <stdio.h>
42#include <string.h>
43#include <stdlib.h>
44
45#define MAXALIASES 35
46
47static FILE *servf = NULL;
48static char line[BUFSIZ+1];
49static struct servent serv;
50static char *serv_aliases[MAXALIASES];
51int _serv_stayopen;
52
53void
54setservent(f)
55 int f;
56{
57 if (servf == NULL)
58 servf = fopen(_PATH_SERVICES, "r" );
59 else
60 rewind(servf);
61 _serv_stayopen |= f;
62}
63
64void
65endservent()
66{
67 if (servf) {
68 fclose(servf);
69 servf = NULL;
70 }
71 _serv_stayopen = 0;
72}
73
74struct servent *
75getservent()
76{
77 char *p, *cp, **q;
78 size_t len;
79
80 if (servf == NULL && (servf = fopen(_PATH_SERVICES, "r" )) == NULL)
81 return (NULL);
82again:
83 if ((p = fgetln(servf, &len)) == NULL)
84 return (NULL);
85 if (p[len-1] == '\n')
86 len--;
87 if (len >= sizeof(line) || len == 0)
88 goto again;
89 p = memcpy(line, p, len);
90 line[len] = '\0';
91 if (*p == '#')
92 goto again;
93 if ((cp = strchr(p, '#')) != NULL)
94 *cp = '\0';
95 serv.s_name = p;
96 p = strpbrk(p, " \t");
97 if (p == NULL)
98 goto again;
99 *p++ = '\0';
100 while (*p == ' ' || *p == '\t')
101 p++;
102 cp = strpbrk(p, ",/");
103 if (cp == NULL)
104 goto again;
105 *cp++ = '\0';
106 serv.s_port = htons((in_port_t)atoi(p));
107 serv.s_proto = cp;
108 q = serv.s_aliases = serv_aliases;
109 cp = strpbrk(cp, " \t");
110 if (cp != NULL)
111 *cp++ = '\0';
112 while (cp && *cp) {
113 if (*cp == ' ' || *cp == '\t') {
114 cp++;
115 continue;
116 }
117 if (q < &serv_aliases[MAXALIASES - 1])
118 *q++ = cp;
119 cp = strpbrk(cp, " \t");
120 if (cp != NULL)
121 *cp++ = '\0';
122 }
123 *q = NULL;
124 return (&serv);
125}
diff --git a/src/lib/libc/net/herror.c b/src/lib/libc/net/herror.c
new file mode 100644
index 0000000000..737bb115a7
--- /dev/null
+++ b/src/lib/libc/net/herror.c
@@ -0,0 +1,121 @@
1/* $OpenBSD: herror.c,v 1.4 1997/03/13 19:07:28 downsj Exp $ */
2
3/*
4 * ++Copyright++ 1987, 1993
5 * -
6 * Copyright (c) 1987, 1993
7 * The Regents of the University of California. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by the University of
20 * California, Berkeley and its contributors.
21 * 4. Neither the name of the University nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 * -
37 * Portions Copyright (c) 1993 by Digital Equipment Corporation.
38 *
39 * Permission to use, copy, modify, and distribute this software for any
40 * purpose with or without fee is hereby granted, provided that the above
41 * copyright notice and this permission notice appear in all copies, and that
42 * the name of Digital Equipment Corporation not be used in advertising or
43 * publicity pertaining to distribution of the document or software without
44 * specific, written prior permission.
45 *
46 * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
47 * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
48 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
49 * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
50 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
51 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
52 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
53 * SOFTWARE.
54 * -
55 * --Copyright--
56 */
57
58#if defined(LIBC_SCCS) && !defined(lint)
59#if 0
60static char sccsid[] = "@(#)herror.c 8.1 (Berkeley) 6/4/93";
61static char rcsid[] = "$From: herror.c,v 8.3 1996/08/05 08:31:35 vixie Exp $";
62#else
63static char rcsid[] = "$OpenBSD: herror.c,v 1.4 1997/03/13 19:07:28 downsj Exp $";
64#endif
65#endif /* LIBC_SCCS and not lint */
66
67#include <sys/types.h>
68#include <sys/param.h>
69#include <sys/uio.h>
70#include <netdb.h>
71#include <unistd.h>
72#include <string.h>
73
74const char *h_errlist[] = {
75 "Resolver Error 0 (no error)",
76 "Unknown host", /* 1 HOST_NOT_FOUND */
77 "Host name lookup failure", /* 2 TRY_AGAIN */
78 "Unknown server error", /* 3 NO_RECOVERY */
79 "No address associated with name", /* 4 NO_ADDRESS */
80};
81int h_nerr = { sizeof h_errlist / sizeof h_errlist[0] };
82
83extern int h_errno;
84
85/*
86 * herror --
87 * print the error indicated by the h_errno value.
88 */
89void
90herror(s)
91 const char *s;
92{
93 struct iovec iov[4];
94 register struct iovec *v = iov;
95
96 if (s && *s) {
97 v->iov_base = (char *)s;
98 v->iov_len = strlen(s);
99 v++;
100 v->iov_base = ": ";
101 v->iov_len = 2;
102 v++;
103 }
104 v->iov_base = (char *)hstrerror(h_errno);
105 v->iov_len = strlen(v->iov_base);
106 v++;
107 v->iov_base = "\n";
108 v->iov_len = 1;
109 writev(STDERR_FILENO, iov, (v - iov) + 1);
110}
111
112const char *
113hstrerror(err)
114 int err;
115{
116 if (err < 0)
117 return ("Resolver internal error");
118 else if (err < h_nerr)
119 return (h_errlist[err]);
120 return ("Unknown resolver error");
121}
diff --git a/src/lib/libc/net/htonl.c b/src/lib/libc/net/htonl.c
new file mode 100644
index 0000000000..73b7432731
--- /dev/null
+++ b/src/lib/libc/net/htonl.c
@@ -0,0 +1,25 @@
1/*
2 * Written by J.T. Conklin <jtc@netbsd.org>.
3 * Public domain.
4 */
5
6#if defined(LIBC_SCCS) && !defined(lint)
7static char *rcsid = "$OpenBSD: htonl.c,v 1.4 1996/12/12 03:19:55 tholo Exp $";
8#endif /* LIBC_SCCS and not lint */
9
10#include <sys/types.h>
11#include <machine/endian.h>
12
13#undef htonl
14
15u_int32_t
16htonl(x)
17 u_int32_t x;
18{
19#if BYTE_ORDER == LITTLE_ENDIAN
20 u_char *s = (u_char *)&x;
21 return (u_int32_t)(s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]);
22#else
23 return x;
24#endif
25}
diff --git a/src/lib/libc/net/htons.c b/src/lib/libc/net/htons.c
new file mode 100644
index 0000000000..47cf25952d
--- /dev/null
+++ b/src/lib/libc/net/htons.c
@@ -0,0 +1,29 @@
1/*
2 * Written by J.T. Conklin <jtc@netbsd.org>.
3 * Public domain.
4 */
5
6#if defined(LIBC_SCCS) && !defined(lint)
7static char *rcsid = "$OpenBSD: htons.c,v 1.6 1997/07/25 20:30:07 mickey Exp $";
8#endif /* LIBC_SCCS and not lint */
9
10#include <sys/types.h>
11#include <machine/endian.h>
12
13#undef htons
14
15u_int16_t
16#ifdef __STDC__
17htons(u_int16_t x)
18#else
19htons(x)
20 u_int16_t x;
21#endif
22{
23#if BYTE_ORDER == LITTLE_ENDIAN
24 u_char *s = (u_char *) &x;
25 return (u_int16_t)(s[0] << 8 | s[1]);
26#else
27 return x;
28#endif
29}
diff --git a/src/lib/libc/net/inet.3 b/src/lib/libc/net/inet.3
new file mode 100644
index 0000000000..2fb86cd927
--- /dev/null
+++ b/src/lib/libc/net/inet.3
@@ -0,0 +1,319 @@
1.\" $OpenBSD: inet.3,v 1.4 1997/06/23 04:01:11 millert Exp $
2.\" $NetBSD: inet.3,v 1.7 1997/06/18 02:25:24 lukem Exp $
3.\"
4.\" Copyright (c) 1983, 1990, 1991, 1993
5.\" The Regents of the University of California. All rights reserved.
6.\"
7.\" Redistribution and use in source and binary forms, with or without
8.\" modification, are permitted provided that the following conditions
9.\" are met:
10.\" 1. Redistributions of source code must retain the above copyright
11.\" notice, this list of conditions and the following disclaimer.
12.\" 2. Redistributions in binary form must reproduce the above copyright
13.\" notice, this list of conditions and the following disclaimer in the
14.\" documentation and/or other materials provided with the distribution.
15.\" 3. All advertising materials mentioning features or use of this software
16.\" must display the following acknowledgement:
17.\" This product includes software developed by the University of
18.\" California, Berkeley and its contributors.
19.\" 4. Neither the name of the University nor the names of its contributors
20.\" may be used to endorse or promote products derived from this software
21.\" without specific prior written permission.
22.\"
23.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33.\" SUCH DAMAGE.
34.\"
35.\" @(#)inet.3 8.1 (Berkeley) 6/4/93
36.\"
37.Dd June 18, 1997
38.Dt INET 3
39.Os BSD 4.2
40.Sh NAME
41.Nm inet_addr ,
42.Nm inet_aton ,
43.Nm inet_lnaof ,
44.Nm inet_makeaddr ,
45.Nm inet_netof ,
46.Nm inet_network ,
47.Nm inet_ntoa ,
48.Nm inet_ntop ,
49.Nm inet_pton
50.Nd Internet address manipulation routines
51.Sh SYNOPSIS
52.Fd #include <sys/socket.h>
53.Fd #include <netinet/in.h>
54.Fd #include <arpa/inet.h>
55.Ft in_addr_t
56.Fn inet_addr "const char *cp"
57.Ft int
58.Fn inet_aton "const char *cp" "struct in_addr *addr"
59.Ft in_addr_t
60.Fn inet_lnaof "struct in_addr in"
61.Ft struct in_addr
62.Fn inet_makeaddr "unsigned long net" "unsigned long lna"
63.Ft in_addr_t
64.Fn inet_netof "struct in_addr in"
65.Ft in_addr_t
66.Fn inet_network "const char *cp"
67.Ft char *
68.Fn inet_ntoa "struct in_addr in"
69.Ft const char *
70.Fn inet_ntop "int af" "const void *src" "char *dst" "size_t size"
71.Ft int
72.Fn inet_pton "int af" "const char *src" "void *dst"
73.Sh DESCRIPTION
74The routines
75.Fn inet_aton ,
76.Fn inet_addr
77and
78.Fn inet_network
79interpret character strings representing
80numbers expressed in the Internet standard
81.Ql \&.
82notation.
83The
84.Fn inet_pton
85function converts a presentation format address (that is, printable form
86as held in a character string) to network format (usually a
87.Ft struct in_addr
88or some other internal binary representation, in network byte order). It
89returns 1 if the address was valid for the specified address family, or
900 if the address wasn't parseable in the specified address family, or -1
91if some system error occurred (in which case
92.Va errno
93will have been set). This function is presently valid for AF_INET and
94AF_INET6. The
95.Fn inet_aton
96routine interprets the specified character string as an Internet address,
97placing the address into the structure provided.
98It returns 1 if the string was successfully interpreted,
99or 0 if the string is invalid.
100The
101.Fn inet_addr
102and
103.Fn inet_network
104functions return numbers suitable for use
105as Internet addresses and Internet network
106numbers, respectively.
107.Pp
108The function
109.Fn inet_ntop
110converts an address from network format (usually a
111.Ft struct in_addr
112or some other binary form, in network byte order) to presentation format
113(suitable for external display purposes). It returns NULL if a system
114error occurs (in which case,
115.Va errno
116will have been set), or it returns a pointer to the destination string.
117The routine
118.Fn inet_ntoa
119takes an Internet address and returns an
120.Tn ASCII
121string representing the address in
122.Ql \&.
123notation. The routine
124.Fn inet_makeaddr
125takes an Internet network number and a local
126network address and constructs an Internet address
127from it. The routines
128.Fn inet_netof
129and
130.Fn inet_lnaof
131break apart Internet host addresses, returning
132the network number and local network address part,
133respectively.
134.Pp
135All Internet addresses are returned in network
136order (bytes ordered from left to right).
137All network numbers and local address parts are
138returned as machine format integer values.
139.Sh INTERNET ADDRESSES (IP VERSION 4)
140Values specified using the
141.Ql \&.
142notation take one
143of the following forms:
144.Bd -literal -offset indent
145a.b.c.d
146a.b.c
147a.b
148a
149.Ed
150.Pp
151When four parts are specified, each is interpreted
152as a byte of data and assigned, from left to right,
153to the four bytes of an Internet address. Note
154that when an Internet address is viewed as a 32-bit
155integer quantity on a system that uses little-endian
156byte order (such as the
157.Tn Intel 386, 486
158and
159.Tn Pentium
160processors) the bytes referred to above appear as
161.Dq Li d.c.b.a .
162That is, little-endian bytes are ordered from right to left.
163.Pp
164When a three part address is specified, the last
165part is interpreted as a 16-bit quantity and placed
166in the right-most two bytes of the network address.
167This makes the three part address format convenient
168for specifying Class B network addresses as
169.Dq Li 128.net.host .
170.Pp
171When a two part address is supplied, the last part
172is interpreted as a 24-bit quantity and placed in
173the right most three bytes of the network address.
174This makes the two part address format convenient
175for specifying Class A network addresses as
176.Dq Li net.host .
177.Pp
178When only one part is given, the value is stored
179directly in the network address without any byte
180rearrangement.
181.Pp
182All numbers supplied as
183.Dq parts
184in a
185.Ql \&.
186notation
187may be decimal, octal, or hexadecimal, as specified
188in the C language (i.e., a leading 0x or 0X implies
189hexadecimal; otherwise, a leading 0 implies octal;
190otherwise, the number is interpreted as decimal).
191.Sh INTERNET ADDRESSES (IP VERSION 6)
192The presentation format of an IPv6 address is given in [RFC1884 2.2]:
193.Pp
194There are three conventional forms for representing IPv6 addresses as
195text strings:
196.Bl -enum
197.It
198The preferred form is x:x:x:x:x:x:x:x, where the 'x's are the
199hexadecimal values of the eight 16-bit pieces of the address.
200Examples:
201.Bd -literal -offset indent
202FEDC:BA98:7654:3210:FEDC:BA98:7654:3210
2031080:0:0:0:8:800:200C:417A
204.Ed
205.Pp
206Note that it is not necessary to write the leading zeros in an
207individual field, but there must be at least one numeral in
208every field (except for the case described in 2.).
209.It
210Due to the method of allocating certain styles of IPv6
211addresses, it will be common for addresses to contain long
212strings of zero bits. In order to make writing addresses
213.Pp
214containing zero bits easier a special syntax is available to
215compress the zeros. The use of ``::'' indicates multiple groups
216of 16-bits of zeros. The ``::'' can only appear once in an
217address. The ``::'' can also be used to compress the leading
218and/or trailing zeros in an address.
219.Pp
220For example the following addresses:
221.Bd -literal -offset indent
2221080:0:0:0:8:800:200C:417A a unicast address
223FF01:0:0:0:0:0:0:43 a multicast address
2240:0:0:0:0:0:0:1 the loopback address
2250:0:0:0:0:0:0:0 the unspecified addresses
226.Ed
227.Pp
228may be represented as:
229.Bd -literal -offset indent
2301080::8:800:200C:417A a unicast address
231FF01::43 a multicast address
232::1 the loopback address
233:: the unspecified addresses
234.Ed
235.It
236An alternative form that is sometimes more convenient when
237dealing with a mixed environment of IPv4 and IPv6 nodes is
238x:x:x:x:x:x:d.d.d.d, where the 'x's are the hexadecimal values
239of the six high-order 16-bit pieces of the address, and the 'd's
240are the decimal values of the four low-order 8-bit pieces of the
241address (standard IPv4 representation). Examples:
242.Bd -literal -offset indent
2430:0:0:0:0:0:13.1.68.3
2440:0:0:0:0:FFFF:129.144.52.38
245.Ed
246.Pp
247or in compressed form:
248.Bd -literal -offset indent
249::13.1.68.3
250::FFFF:129.144.52.38
251.Ed
252.El
253.Sh DIAGNOSTICS
254The constant
255.Dv INADDR_NONE
256is returned by
257.Fn inet_addr
258and
259.Fn inet_network
260for malformed requests.
261.Sh SEE ALSO
262.Xr byteorder 3 ,
263.Xr gethostbyname 3 ,
264.Xr getnetent 3 ,
265.Xr inet_net 3 ,
266.Xr hosts 5 ,
267.Xr networks 5
268.Sh STANDARDS
269The
270.Nm inet_ntop
271and
272.Nm inet_pton
273functions conforms to the IETF IPng BSD API and address formatting
274specifications. Note that
275.Nm inet_pton
276does not accept 1-, 2-, or 3-part dotted addresses; all four parts
277must be specified. This is a narrower input set than that accepted by
278.Nm inet_aton .
279.Sh HISTORY
280The
281.Nm inet_addr ,
282.Nm inet_network ,
283.Nm inet_makeaddr ,
284.Nm inet_lnaof
285and
286.Nm inet_netof
287functions appeared in
288.Bx 4.2 .
289The
290.Nm inet_aton
291and
292.Nm inet_ntoa
293functions appeared in
294.Bx 4.3 .
295The
296.Nm inet_pton
297and
298.Nm inet_ntop
299functions appeared in BIND 4.9.4.
300.Sh BUGS
301The value
302.Dv INADDR_NONE
303(0xffffffff) is a valid broadcast address, but
304.Fn inet_addr
305cannot return that value without indicating failure.
306The newer
307.Fn inet_aton
308function does not share this problem.
309.Pp
310The problem of host byte ordering versus network byte ordering is
311confusing.
312.Pp
313The string returned by
314.Fn inet_ntoa
315resides in a static memory area.
316.Pp
317.Fn inet_addr
318should return a
319.Fa "struct in_addr" .
diff --git a/src/lib/libc/net/inet_addr.c b/src/lib/libc/net/inet_addr.c
new file mode 100644
index 0000000000..5e4dcdafb2
--- /dev/null
+++ b/src/lib/libc/net/inet_addr.c
@@ -0,0 +1,187 @@
1/* $OpenBSD: inet_addr.c,v 1.5 1997/04/05 21:13:10 millert Exp $ */
2
3/*
4 * ++Copyright++ 1983, 1990, 1993
5 * -
6 * Copyright (c) 1983, 1990, 1993
7 * The Regents of the University of California. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by the University of
20 * California, Berkeley and its contributors.
21 * 4. Neither the name of the University nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 * -
37 * Portions Copyright (c) 1993 by Digital Equipment Corporation.
38 *
39 * Permission to use, copy, modify, and distribute this software for any
40 * purpose with or without fee is hereby granted, provided that the above
41 * copyright notice and this permission notice appear in all copies, and that
42 * the name of Digital Equipment Corporation not be used in advertising or
43 * publicity pertaining to distribution of the document or software without
44 * specific, written prior permission.
45 *
46 * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
47 * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
48 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
49 * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
50 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
51 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
52 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
53 * SOFTWARE.
54 * -
55 * --Copyright--
56 */
57
58#if defined(LIBC_SCCS) && !defined(lint)
59#if 0
60static char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93";
61static char rcsid[] = "$From: inet_addr.c,v 8.5 1996/08/05 08:31:35 vixie Exp $";
62#else
63static char rcsid[] = "$OpenBSD: inet_addr.c,v 1.5 1997/04/05 21:13:10 millert Exp $";
64#endif
65#endif /* LIBC_SCCS and not lint */
66
67#include <sys/types.h>
68#include <sys/param.h>
69#include <netinet/in.h>
70#include <arpa/inet.h>
71#include <ctype.h>
72
73/*
74 * Ascii internet address interpretation routine.
75 * The value returned is in network order.
76 */
77in_addr_t
78inet_addr(cp)
79 register const char *cp;
80{
81 struct in_addr val;
82
83 if (inet_aton(cp, &val))
84 return (val.s_addr);
85 return (INADDR_NONE);
86}
87
88/*
89 * Check whether "cp" is a valid ascii representation
90 * of an Internet address and convert to a binary address.
91 * Returns 1 if the address is valid, 0 if not.
92 * This replaces inet_addr, the return value from which
93 * cannot distinguish between failure and a local broadcast address.
94 */
95int
96inet_aton(cp, addr)
97 register const char *cp;
98 struct in_addr *addr;
99{
100 register in_addr_t val;
101 register int base, n;
102 register char c;
103 u_int parts[4];
104 register u_int *pp = parts;
105
106 c = *cp;
107 for (;;) {
108 /*
109 * Collect number up to ``.''.
110 * Values are specified as for C:
111 * 0x=hex, 0=octal, isdigit=decimal.
112 */
113 if (!isdigit(c))
114 return (0);
115 val = 0; base = 10;
116 if (c == '0') {
117 c = *++cp;
118 if (c == 'x' || c == 'X')
119 base = 16, c = *++cp;
120 else
121 base = 8;
122 }
123 for (;;) {
124 if (isascii(c) && isdigit(c)) {
125 val = (val * base) + (c - '0');
126 c = *++cp;
127 } else if (base == 16 && isascii(c) && isxdigit(c)) {
128 val = (val << 4) |
129 (c + 10 - (islower(c) ? 'a' : 'A'));
130 c = *++cp;
131 } else
132 break;
133 }
134 if (c == '.') {
135 /*
136 * Internet format:
137 * a.b.c.d
138 * a.b.c (with c treated as 16 bits)
139 * a.b (with b treated as 24 bits)
140 */
141 if (pp >= parts + 3)
142 return (0);
143 *pp++ = val;
144 c = *++cp;
145 } else
146 break;
147 }
148 /*
149 * Check for trailing characters.
150 */
151 if (c != '\0' && (!isascii(c) || !isspace(c)))
152 return (0);
153 /*
154 * Concoct the address according to
155 * the number of parts specified.
156 */
157 n = pp - parts + 1;
158 switch (n) {
159
160 case 0:
161 return (0); /* initial nondigit */
162
163 case 1: /* a -- 32 bits */
164 break;
165
166 case 2: /* a.b -- 8.24 bits */
167 if (val > 0xffffff)
168 return (0);
169 val |= parts[0] << 24;
170 break;
171
172 case 3: /* a.b.c -- 8.8.16 bits */
173 if (val > 0xffff)
174 return (0);
175 val |= (parts[0] << 24) | (parts[1] << 16);
176 break;
177
178 case 4: /* a.b.c.d -- 8.8.8.8 bits */
179 if (val > 0xff)
180 return (0);
181 val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
182 break;
183 }
184 if (addr)
185 addr->s_addr = htonl(val);
186 return (1);
187}
diff --git a/src/lib/libc/net/inet_lnaof.c b/src/lib/libc/net/inet_lnaof.c
new file mode 100644
index 0000000000..6aed18699b
--- /dev/null
+++ b/src/lib/libc/net/inet_lnaof.c
@@ -0,0 +1,59 @@
1/*
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: inet_lnaof.c,v 1.3 1997/04/05 21:13:11 millert Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/param.h>
39#include <netinet/in.h>
40#include <arpa/inet.h>
41
42/*
43 * Return the local network address portion of an
44 * internet address; handles class a/b/c network
45 * number formats.
46 */
47in_addr_t
48inet_lnaof(in)
49 struct in_addr in;
50{
51 register in_addr_t i = ntohl(in.s_addr);
52
53 if (IN_CLASSA(i))
54 return ((i)&IN_CLASSA_HOST);
55 else if (IN_CLASSB(i))
56 return ((i)&IN_CLASSB_HOST);
57 else
58 return ((i)&IN_CLASSC_HOST);
59}
diff --git a/src/lib/libc/net/inet_makeaddr.c b/src/lib/libc/net/inet_makeaddr.c
new file mode 100644
index 0000000000..196a589e4c
--- /dev/null
+++ b/src/lib/libc/net/inet_makeaddr.c
@@ -0,0 +1,62 @@
1/*
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: inet_makeaddr.c,v 1.3 1997/04/05 21:13:12 millert Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/param.h>
39#include <netinet/in.h>
40#include <arpa/inet.h>
41
42/*
43 * Formulate an Internet address from network + host. Used in
44 * building addresses stored in the ifnet structure.
45 */
46struct in_addr
47inet_makeaddr(net, host)
48 in_addr_t net, host;
49{
50 in_addr_t addr;
51
52 if (net < 128)
53 addr = (net << IN_CLASSA_NSHIFT) | (host & IN_CLASSA_HOST);
54 else if (net < 65536)
55 addr = (net << IN_CLASSB_NSHIFT) | (host & IN_CLASSB_HOST);
56 else if (net < 16777216L)
57 addr = (net << IN_CLASSC_NSHIFT) | (host & IN_CLASSC_HOST);
58 else
59 addr = net | host;
60 addr = htonl(addr);
61 return (*(struct in_addr *)&addr);
62}
diff --git a/src/lib/libc/net/inet_net.3 b/src/lib/libc/net/inet_net.3
new file mode 100644
index 0000000000..1a42aff6ea
--- /dev/null
+++ b/src/lib/libc/net/inet_net.3
@@ -0,0 +1,149 @@
1.\" $OpenBSD: inet_net.3,v 1.1 1997/06/23 03:37:26 millert 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.Ft 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 NULL if a system error occurs (in which case,
65.Va errno
66will have been set), or it returns a pointer to the destination string.
67.Pp
68The
69.Fn inet_net_pton
70function converts a presentation format Internet network number (that is,
71printable form as held in a character string) to network format (usually a
72.Ft struct in_addr
73or some other internal binary representation, in network byte order).
74It returns the number of bits (either computed based on the class, or
75specified with /CIDR), or -1 if a failure occurred
76(in which case
77.Va errno
78will have been set.
79It will be set to
80.Er ENOENT
81if the Internet network number was not valid).
82.Pp
83The currently supported value for
84.Fa af
85is: AF_INET.
86.Fa size
87is the size of the result buffer
88.Fa dst .
89.Pp
90.Sh NETWORK NUMBERS (IP VERSION 4)
91Internet network numbers may be specified in one of the following forms:
92.Bd -literal -offset indent
93a.b.c.d/bits
94a.b.c.d
95a.b.c
96a.b
97a
98.Ed
99.Pp
100When four parts are specified, each is interpreted
101as a byte of data and assigned, from left to right,
102to the four bytes of an Internet network number. Note
103that when an Internet network number is viewed as a 32-bit
104integer quantity on a system that uses little-endian
105byte order (such as the
106.Tn Intel 386, 486
107and
108.Tn Pentium
109processors) the bytes referred to above appear as
110.Dq Li d.c.b.a .
111That is, little-endian bytes are ordered from right to left.
112.Pp
113When a three part number is specified, the last
114part is interpreted as a 16-bit quantity and placed
115in the right-most two bytes of the Internet network number.
116This makes the three part number format convenient
117for specifying Class B network numbers as
118.Dq Li 128.net.host .
119.Pp
120When a two part number is supplied, the last part
121is interpreted as a 24-bit quantity and placed in
122the right most three bytes of the Internet network number.
123This makes the two part number format convenient
124for specifying Class A network numbers as
125.Dq Li net.host .
126.Pp
127When only one part is given, the value is stored
128directly in the Internet network number without any byte
129rearrangement.
130.Pp
131All numbers supplied as
132.Dq parts
133in a
134.Ql \&.
135notation
136may be decimal, octal, or hexadecimal, as specified
137in the C language (i.e., a leading 0x or 0X implies
138hexadecimal; otherwise, a leading 0 implies octal;
139otherwise, the number is interpreted as decimal).
140.Sh SEE ALSO
141.Xr byteorder 3 ,
142.Xr inet 3 ,
143.Xr networks 5
144.Sh HISTORY
145The
146.Nm inet_net_ntop
147and
148.Nm inet_net_pton
149functions 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..943ec44550
--- /dev/null
+++ b/src/lib/libc/net/inet_net_ntop.c
@@ -0,0 +1,139 @@
1/* $OpenBSD: inet_net_ntop.c,v 1.1 1997/03/13 19:07:30 downsj 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.1 1997/03/13 19:07:30 downsj 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 __P((const u_char *src, int bits,
39 char *dst, size_t size));
40
41/*
42 * char *
43 * inet_net_ntop(af, src, bits, dst, size)
44 * convert network number from network to presentation format.
45 * generates CIDR style result always.
46 * return:
47 * pointer to dst, or NULL if an error occurred (check errno).
48 * author:
49 * Paul Vixie (ISC), July 1996
50 */
51char *
52inet_net_ntop(af, src, bits, dst, size)
53 int af;
54 const void *src;
55 int bits;
56 char *dst;
57 size_t size;
58{
59 switch (af) {
60 case AF_INET:
61 return (inet_net_ntop_ipv4(src, bits, dst, size));
62 default:
63 errno = EAFNOSUPPORT;
64 return (NULL);
65 }
66}
67
68/*
69 * static char *
70 * inet_net_ntop_ipv4(src, bits, dst, size)
71 * convert IPv4 network number from network to presentation format.
72 * generates CIDR style result always.
73 * return:
74 * pointer to dst, or NULL if an error occurred (check errno).
75 * note:
76 * network byte order assumed. this means 192.5.5.240/28 has
77 * 0x11110000 in its fourth octet.
78 * author:
79 * Paul Vixie (ISC), July 1996
80 */
81static char *
82inet_net_ntop_ipv4(src, bits, dst, size)
83 const u_char *src;
84 int bits;
85 char *dst;
86 size_t size;
87{
88 char *odst = dst;
89 char *t;
90 u_int m;
91 int b;
92
93 if (bits < 0 || bits > 32) {
94 errno = EINVAL;
95 return (NULL);
96 }
97 if (bits == 0) {
98 if (size < sizeof "0")
99 goto emsgsize;
100 *dst++ = '0';
101 *dst = '\0';
102 }
103
104 /* Format whole octets. */
105 for (b = bits / 8; b > 0; b--) {
106 if (size < sizeof "255.")
107 goto emsgsize;
108 t = dst;
109 dst += sprintf(dst, "%u", *src++);
110 if (b > 1) {
111 *dst++ = '.';
112 *dst = '\0';
113 }
114 size -= (size_t)(dst - t);
115 }
116
117 /* Format partial octet. */
118 b = bits % 8;
119 if (b > 0) {
120 if (size < sizeof ".255")
121 goto emsgsize;
122 t = dst;
123 if (dst != odst)
124 *dst++ = '.';
125 m = ((1 << b) - 1) << (8 - b);
126 dst += sprintf(dst, "%u", *src & m);
127 size -= (size_t)(dst - t);
128 }
129
130 /* Format CIDR /width. */
131 if (size < sizeof "/32")
132 goto emsgsize;
133 dst += sprintf(dst, "/%u", bits);
134 return (odst);
135
136 emsgsize:
137 errno = EMSGSIZE;
138 return (NULL);
139}
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..b529e83664
--- /dev/null
+++ b/src/lib/libc/net/inet_net_pton.c
@@ -0,0 +1,207 @@
1/* $OpenBSD: inet_net_pton.c,v 1.1 1997/03/13 19:07:30 downsj 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.1 1997/03/13 19:07:30 downsj 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 __P((const char *src, u_char *dst,
41 size_t size));
42
43/*
44 * static int
45 * inet_net_pton(af, src, dst, size)
46 * convert network number from presentation to network format.
47 * accepts hex octets, hex strings, decimal octets, and /CIDR.
48 * "size" is in bytes and describes "dst".
49 * return:
50 * number of bits, either imputed classfully or specified with /CIDR,
51 * or -1 if some failure occurred (check errno). ENOENT means it was
52 * not a valid network specification.
53 * author:
54 * Paul Vixie (ISC), June 1996
55 */
56int
57inet_net_pton(af, src, dst, size)
58 int af;
59 const char *src;
60 void *dst;
61 size_t size;
62{
63 switch (af) {
64 case AF_INET:
65 return (inet_net_pton_ipv4(src, dst, size));
66 default:
67 errno = EAFNOSUPPORT;
68 return (-1);
69 }
70}
71
72/*
73 * static int
74 * inet_net_pton_ipv4(src, dst, size)
75 * convert IPv4 network number from presentation to network format.
76 * accepts hex octets, hex strings, decimal octets, and /CIDR.
77 * "size" is in bytes and describes "dst".
78 * return:
79 * number of bits, either imputed classfully or specified with /CIDR,
80 * or -1 if some failure occurred (check errno). ENOENT means it was
81 * not an IPv4 network specification.
82 * note:
83 * network byte order assumed. this means 192.5.5.240/28 has
84 * 0x11110000 in its fourth octet.
85 * author:
86 * Paul Vixie (ISC), June 1996
87 */
88static int
89inet_net_pton_ipv4(src, dst, size)
90 const char *src;
91 u_char *dst;
92 size_t size;
93{
94 static const char
95 xdigits[] = "0123456789abcdef",
96 digits[] = "0123456789";
97 int n, ch, tmp, dirty, bits;
98 const u_char *odst = dst;
99
100 ch = *src++;
101 if (ch == '0' && (src[0] == 'x' || src[0] == 'X')
102 && isascii(src[1]) && isxdigit(src[1])) {
103 /* Hexadecimal: Eat nybble string. */
104 if (size <= 0)
105 goto emsgsize;
106 *dst = 0, dirty = 0;
107 src++; /* skip x or X. */
108 while ((ch = *src++) != '\0' &&
109 isascii(ch) && isxdigit(ch)) {
110 if (isupper(ch))
111 ch = tolower(ch);
112 n = strchr(xdigits, ch) - xdigits;
113 assert(n >= 0 && n <= 15);
114 *dst |= n;
115 if (!dirty++)
116 *dst <<= 4;
117 else if (size-- > 0)
118 *++dst = 0, dirty = 0;
119 else
120 goto emsgsize;
121 }
122 if (dirty)
123 size--;
124 } else if (isascii(ch) && isdigit(ch)) {
125 /* Decimal: eat dotted digit string. */
126 for (;;) {
127 tmp = 0;
128 do {
129 n = strchr(digits, ch) - digits;
130 assert(n >= 0 && n <= 9);
131 tmp *= 10;
132 tmp += n;
133 if (tmp > 255)
134 goto enoent;
135 } while ((ch = *src++) != '\0' &&
136 isascii(ch) && isdigit(ch));
137 if (size-- <= 0)
138 goto emsgsize;
139 *dst++ = (u_char) tmp;
140 if (ch == '\0' || ch == '/')
141 break;
142 if (ch != '.')
143 goto enoent;
144 ch = *src++;
145 if (!isascii(ch) || !isdigit(ch))
146 goto enoent;
147 }
148 } else
149 goto enoent;
150
151 bits = -1;
152 if (ch == '/' && isascii(src[0]) && isdigit(src[0]) && dst > odst) {
153 /* CIDR width specifier. Nothing can follow it. */
154 ch = *src++; /* Skip over the /. */
155 bits = 0;
156 do {
157 n = strchr(digits, ch) - digits;
158 assert(n >= 0 && n <= 9);
159 bits *= 10;
160 bits += n;
161 } while ((ch = *src++) != '\0' &&
162 isascii(ch) && isdigit(ch));
163 if (ch != '\0')
164 goto enoent;
165 if (bits > 32)
166 goto emsgsize;
167 }
168
169 /* Firey death and destruction unless we prefetched EOS. */
170 if (ch != '\0')
171 goto enoent;
172
173 /* If nothing was written to the destination, we found no address. */
174 if (dst == odst)
175 goto enoent;
176 /* If no CIDR spec was given, infer width from net class. */
177 if (bits == -1) {
178 if (*odst >= 240) /* Class E */
179 bits = 32;
180 else if (*odst >= 224) /* Class D */
181 bits = 4;
182 else if (*odst >= 192) /* Class C */
183 bits = 24;
184 else if (*odst >= 128) /* Class B */
185 bits = 16;
186 else /* Class A */
187 bits = 8;
188 /* If imputed mask is narrower than specified octets, widen. */
189 if (bits >= 8 && bits < ((dst - odst) * 8))
190 bits = (dst - odst) * 8;
191 }
192 /* Extend network to cover the actual mask. */
193 while (bits > ((dst - odst) * 8)) {
194 if (size-- <= 0)
195 goto emsgsize;
196 *dst++ = '\0';
197 }
198 return (bits);
199
200 enoent:
201 errno = ENOENT;
202 return (-1);
203
204 emsgsize:
205 errno = EMSGSIZE;
206 return (-1);
207}
diff --git a/src/lib/libc/net/inet_neta.c b/src/lib/libc/net/inet_neta.c
new file mode 100644
index 0000000000..ffcddd8d91
--- /dev/null
+++ b/src/lib/libc/net/inet_neta.c
@@ -0,0 +1,83 @@
1/* $OpenBSD: inet_neta.c,v 1.2 1997/04/05 21:13:12 millert Exp $ */
2
3/*
4 * Copyright (c) 1996 by Internet Software Consortium.
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
11 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
12 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
13 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
16 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
17 * SOFTWARE.
18 */
19
20#if defined(LIBC_SCCS) && !defined(lint)
21#if 0
22static const char rcsid[] = "$Id: inet_neta.c,v 1.2 1997/04/05 21:13:12 millert Exp $";
23#else
24static const char rcsid[] = "$OpenBSD: inet_neta.c,v 1.2 1997/04/05 21:13:12 millert Exp $";
25#endif
26#endif
27
28#include <sys/types.h>
29#include <sys/socket.h>
30#include <netinet/in.h>
31#include <arpa/inet.h>
32
33#include <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 *tp;
56
57 while (src & 0xffffffff) {
58 u_char b = (src & 0xff000000) >> 24;
59
60 src <<= 8;
61 if (b) {
62 if (size < sizeof "255.")
63 goto emsgsize;
64 tp = dst;
65 dst += sprintf(dst, "%u", b);
66 if (src != 0L) {
67 *dst++ = '.';
68 *dst = '\0';
69 }
70 size -= (size_t)(dst - tp);
71 }
72 }
73 if (dst == odst) {
74 if (size < sizeof "0.0.0.0")
75 goto emsgsize;
76 strcpy(dst, "0.0.0.0");
77 }
78 return (odst);
79
80 emsgsize:
81 errno = EMSGSIZE;
82 return (NULL);
83}
diff --git a/src/lib/libc/net/inet_netof.c b/src/lib/libc/net/inet_netof.c
new file mode 100644
index 0000000000..f3b9c01697
--- /dev/null
+++ b/src/lib/libc/net/inet_netof.c
@@ -0,0 +1,58 @@
1/*
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: inet_netof.c,v 1.3 1997/04/05 21:13:13 millert Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/param.h>
39#include <netinet/in.h>
40#include <arpa/inet.h>
41
42/*
43 * Return the network number from an internet
44 * address; handles class a/b/c network #'s.
45 */
46in_addr_t
47inet_netof(in)
48 struct in_addr in;
49{
50 register in_addr_t i = ntohl(in.s_addr);
51
52 if (IN_CLASSA(i))
53 return (((i)&IN_CLASSA_NET) >> IN_CLASSA_NSHIFT);
54 else if (IN_CLASSB(i))
55 return (((i)&IN_CLASSB_NET) >> IN_CLASSB_NSHIFT);
56 else
57 return (((i)&IN_CLASSC_NET) >> IN_CLASSC_NSHIFT);
58}
diff --git a/src/lib/libc/net/inet_network.c b/src/lib/libc/net/inet_network.c
new file mode 100644
index 0000000000..8a9a555d62
--- /dev/null
+++ b/src/lib/libc/net/inet_network.c
@@ -0,0 +1,92 @@
1/*
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: inet_network.c,v 1.7 1997/07/09 01:08:37 millert Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/types.h>
39#include <netinet/in.h>
40#include <arpa/inet.h>
41#include <ctype.h>
42
43/*
44 * Internet network address interpretation routine.
45 * The library routines call this routine to interpret
46 * network numbers.
47 */
48in_addr_t
49inet_network(cp)
50 register const char *cp;
51{
52 register in_addr_t val, base, n;
53 register char c;
54 in_addr_t parts[4], *pp = parts;
55 register int i;
56
57again:
58 val = 0; base = 10;
59 if (*cp == '0')
60 base = 8, cp++;
61 if (*cp == 'x' || *cp == 'X')
62 base = 16, cp++;
63 while ((c = *cp)) {
64 if (isdigit(c)) {
65 val = (val * base) + (c - '0');
66 cp++;
67 continue;
68 }
69 if (base == 16 && isxdigit(c)) {
70 val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A'));
71 cp++;
72 continue;
73 }
74 break;
75 }
76 if (*cp == '.') {
77 if (pp >= parts + 3)
78 return (INADDR_NONE);
79 *pp++ = val, cp++;
80 goto again;
81 }
82 if (*cp && !isspace(*cp))
83 return (INADDR_NONE);
84 *pp++ = val;
85 n = pp - parts;
86 for (val = 0, i = 0; i < 4; i++) {
87 val <<= 8;
88 if (i < n)
89 val |= parts[i] & 0xff;
90 }
91 return (val);
92}
diff --git a/src/lib/libc/net/inet_ntoa.c b/src/lib/libc/net/inet_ntoa.c
new file mode 100644
index 0000000000..148732ba5a
--- /dev/null
+++ b/src/lib/libc/net/inet_ntoa.c
@@ -0,0 +1,59 @@
1/*
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: inet_ntoa.c,v 1.2 1996/08/19 08:29:16 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38/*
39 * Convert network-format internet address
40 * to base 256 d.d.d.d representation.
41 */
42#include <sys/types.h>
43#include <netinet/in.h>
44#include <arpa/inet.h>
45#include <stdio.h>
46
47char *
48inet_ntoa(in)
49 struct in_addr in;
50{
51 static char b[18];
52 register char *p;
53
54 p = (char *)&in;
55#define UC(b) (((int)b)&0xff)
56 (void)snprintf(b, sizeof(b),
57 "%d.%d.%d.%d", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3]));
58 return (b);
59}
diff --git a/src/lib/libc/net/inet_ntop.c b/src/lib/libc/net/inet_ntop.c
new file mode 100644
index 0000000000..64d0d13768
--- /dev/null
+++ b/src/lib/libc/net/inet_ntop.c
@@ -0,0 +1,194 @@
1/* $OpenBSD: inet_ntop.c,v 1.1 1997/03/13 19:07:32 downsj 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.1 1997/03/13 19:07:32 downsj 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 __P((const u_char *src, char *dst, size_t size));
43static const char *inet_ntop6 __P((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
92 if (sprintf(tmp, fmt, src[0], src[1], src[2], src[3]) > size) {
93 errno = ENOSPC;
94 return (NULL);
95 }
96 strcpy(dst, tmp);
97 return (dst);
98}
99
100/* const char *
101 * inet_ntop6(src, dst, size)
102 * convert IPv6 binary address into presentation (printable) format
103 * author:
104 * Paul Vixie, 1996.
105 */
106static const char *
107inet_ntop6(src, dst, size)
108 const u_char *src;
109 char *dst;
110 size_t size;
111{
112 /*
113 * Note that int32_t and int16_t need only be "at least" large enough
114 * to contain a value of the specified size. On some systems, like
115 * Crays, there is no such thing as an integer variable with 16 bits.
116 * Keep this in mind if you think this function should have been coded
117 * to use pointer overlays. All the world's not a VAX.
118 */
119 char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
120 struct { int base, len; } best, cur;
121 u_int words[IN6ADDRSZ / INT16SZ];
122 int i;
123
124 /*
125 * Preprocess:
126 * Copy the input (bytewise) array into a wordwise array.
127 * Find the longest run of 0x00's in src[] for :: shorthanding.
128 */
129 memset(words, '\0', sizeof words);
130 for (i = 0; i < IN6ADDRSZ; i++)
131 words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
132 best.base = -1;
133 cur.base = -1;
134 for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
135 if (words[i] == 0) {
136 if (cur.base == -1)
137 cur.base = i, cur.len = 1;
138 else
139 cur.len++;
140 } else {
141 if (cur.base != -1) {
142 if (best.base == -1 || cur.len > best.len)
143 best = cur;
144 cur.base = -1;
145 }
146 }
147 }
148 if (cur.base != -1) {
149 if (best.base == -1 || cur.len > best.len)
150 best = cur;
151 }
152 if (best.base != -1 && best.len < 2)
153 best.base = -1;
154
155 /*
156 * Format the result.
157 */
158 tp = tmp;
159 for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
160 /* Are we inside the best run of 0x00's? */
161 if (best.base != -1 && i >= best.base &&
162 i < (best.base + best.len)) {
163 if (i == best.base)
164 *tp++ = ':';
165 continue;
166 }
167 /* Are we following an initial run of 0x00s or any real hex? */
168 if (i != 0)
169 *tp++ = ':';
170 /* Is this address an encapsulated IPv4? */
171 if (i == 6 && best.base == 0 &&
172 (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
173 if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp)))
174 return (NULL);
175 tp += strlen(tp);
176 break;
177 }
178 tp += sprintf(tp, "%x", words[i]);
179 }
180 /* Was it a trailing run of 0x00's? */
181 if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ))
182 *tp++ = ':';
183 *tp++ = '\0';
184
185 /*
186 * Check for overflow, copy, and we're done.
187 */
188 if ((size_t)(tp - tmp) > size) {
189 errno = ENOSPC;
190 return (NULL);
191 }
192 strcpy(dst, tmp);
193 return (dst);
194}
diff --git a/src/lib/libc/net/inet_pton.c b/src/lib/libc/net/inet_pton.c
new file mode 100644
index 0000000000..46b4b24819
--- /dev/null
+++ b/src/lib/libc/net/inet_pton.c
@@ -0,0 +1,220 @@
1/* $OpenBSD: inet_pton.c,v 1.2 1997/04/13 05:08:24 deraadt 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.2 1997/04/13 05:08:24 deraadt 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 __P((const char *src, u_char *dst));
42static int inet_pton6 __P((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 }
180 if (tp + INT16SZ > endp)
181 return (0);
182 *tp++ = (u_char) (val >> 8) & 0xff;
183 *tp++ = (u_char) val & 0xff;
184 saw_xdigit = 0;
185 val = 0;
186 continue;
187 }
188 if (ch == '.' && ((tp + INADDRSZ) <= endp) &&
189 inet_pton4(curtok, tp) > 0) {
190 tp += INADDRSZ;
191 saw_xdigit = 0;
192 break; /* '\0' was seen by inet_pton4(). */
193 }
194 return (0);
195 }
196 if (saw_xdigit) {
197 if (tp + INT16SZ > endp)
198 return (0);
199 *tp++ = (u_char) (val >> 8) & 0xff;
200 *tp++ = (u_char) val & 0xff;
201 }
202 if (colonp != NULL) {
203 /*
204 * Since some memmove()'s erroneously fail to handle
205 * overlapping regions, we'll do the shift by hand.
206 */
207 const int n = tp - colonp;
208 int i;
209
210 for (i = 1; i <= n; i++) {
211 endp[- i] = colonp[n - i];
212 colonp[n - i] = 0;
213 }
214 tp = endp;
215 }
216 if (tp != endp)
217 return (0);
218 memcpy(dst, tmp, IN6ADDRSZ);
219 return (1);
220}
diff --git a/src/lib/libc/net/ipx.3 b/src/lib/libc/net/ipx.3
new file mode 100644
index 0000000000..073be74807
--- /dev/null
+++ b/src/lib/libc/net/ipx.3
@@ -0,0 +1,126 @@
1.\" $OpenBSD: ipx.3,v 1.3 1997/09/09 11:45:17 kstailey Exp $
2.\"
3.\" Copyright (c) 1986, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd June 4, 1993
35.Dt IPX 3
36.Os OpenBSD 1.2
37.Sh NAME
38.Nm ipx_addr ,
39.Nm ipx_ntoa
40.Nd IPX address conversion routines
41.Sh SYNOPSIS
42.Fd #include <sys/types.h>
43.Fd #include <netipx/ipx.h>
44.Ft struct ipx_addr
45.Fn ipx_addr "char *cp"
46.Ft char *
47.Fn ipx_ntoa "struct ipx_addr ipx"
48.Sh DESCRIPTION
49The routine
50.Fn ipx_addr
51interprets character strings representing
52.Tn IPX
53addresses, returning binary information suitable
54for use in system calls.
55The routine
56.Fn ipx_ntoa
57takes
58.Tn IPX
59addresses and returns
60.Tn ASCII
61strings representing the address in a
62notation in common use:
63.Bd -filled -offset indent
64<network number>.<host number>.<port number>
65.Ed
66.Pp
67Trailing zero fields are suppressed, and each number is printed in hexadecimal,
68in a format suitable for input to
69.Fn ipx_addr .
70Any fields lacking super-decimal digits will have a
71trailing
72.Ql H
73appended.
74.Pp
75An effort has been made to insure that
76.Fn ipx_addr
77be compatible with most formats in common use.
78It will first separate an address into 1 to 3 fields using a single delimiter
79chosen from
80period
81.Ql \&. ,
82colon
83.Ql \&:
84or pound-sign
85.Ql \&# .
86Each field is then examined for byte separators (colon or period).
87If there are byte separators, each subfield separated is taken to be
88a small hexadecimal number, and the entirety is taken as a network-byte-ordered
89quantity to be zero extended in the high-network-order bytes.
90Next, the field is inspected for hyphens, in which case
91the field is assumed to be a number in decimal notation
92with hyphens separating the millenia.
93Next, the field is assumed to be a number:
94It is interpreted
95as hexadecimal if there is a leading
96.Ql 0x
97(as in C),
98a trailing
99.Ql H
100(as in Mesa), or there are any super-decimal digits present.
101It is interpreted as octal is there is a leading
102.Ql 0
103and there are no super-octal digits.
104Otherwise, it is converted as a decimal number.
105.Sh RETURN VALUES
106None. (See
107.Sx BUGS . )
108.Sh SEE ALSO
109.Xr ns 4 ,
110.Xr hosts 5 ,
111.Xr networks 5
112.Sh HISTORY
113The precursor
114.Fn ns_addr
115and
116.Fn ns_ntoa
117functions appeared in
118.Bx 4.3 .
119.Sh BUGS
120The string returned by
121.Fn ipx_ntoa
122resides in a static memory area.
123The function
124.Fn ipx_addr
125should diagnose improperly formed input, and there should be an unambiguous
126way 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..a76e03e913
--- /dev/null
+++ b/src/lib/libc/net/ipx_addr.c
@@ -0,0 +1,229 @@
1/*
2 * Copyright (c) 1986, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * J.Q. Johnson.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 *
36 * from @(#)ipx_addr.c
37 */
38
39#if defined(LIBC_SCCS) && !defined(lint)
40static char rcsid[] = "$OpenBSD: ipx_addr.c,v 1.3 1997/07/09 01:08:39 millert Exp $";
41#endif /* LIBC_SCCS and not lint */
42
43#include <sys/param.h>
44#include <netipx/ipx.h>
45#include <stdio.h>
46#include <string.h>
47
48static struct ipx_addr addr, zero_addr;
49
50static void Field(), cvtbase();
51
52struct ipx_addr
53ipx_addr(name)
54 const char *name;
55{
56 char separator;
57 char *hostname, *socketname, *cp;
58 char buf[50];
59
60 (void)strncpy(buf, name, sizeof(buf) - 1);
61 buf[sizeof(buf) - 1] = '\0';
62
63 /*
64 * First, figure out what he intends as a field separtor.
65 * Despite the way this routine is written, the prefered
66 * form 2-272.AA001234H.01777, i.e. XDE standard.
67 * Great efforts are made to insure backward compatability.
68 */
69 if ((hostname = strchr(buf, '#')))
70 separator = '#';
71 else {
72 hostname = strchr(buf, '.');
73 if ((cp = strchr(buf, ':')) &&
74 ((hostname && cp < hostname) || (hostname == 0))) {
75 hostname = cp;
76 separator = ':';
77 } else
78 separator = '.';
79 }
80 if (hostname)
81 *hostname++ = 0;
82
83 addr = zero_addr;
84 Field(buf, addr.ipx_net.c_net, 4);
85 if (hostname == 0)
86 return (addr); /* No separator means net only */
87
88 socketname = strchr(hostname, separator);
89 if (socketname) {
90 *socketname++ = 0;
91 Field(socketname, (u_char *)&addr.ipx_port, 2);
92 }
93
94 Field(hostname, addr.ipx_host.c_host, 6);
95
96 return (addr);
97}
98
99static void
100Field(buf, out, len)
101 char *buf;
102 u_char *out;
103 int len;
104{
105 register char *bp = buf;
106 int i, ibase, base16 = 0, base10 = 0, clen = 0;
107 int hb[6], *hp;
108 char *fmt;
109
110 /*
111 * first try 2-273#2-852-151-014#socket
112 */
113 if ((*buf != '-') &&
114 (1 < (i = sscanf(buf, "%d-%d-%d-%d-%d",
115 &hb[0], &hb[1], &hb[2], &hb[3], &hb[4])))) {
116 cvtbase(1000L, 256, hb, i, out, len);
117 return;
118 }
119 /*
120 * try form 8E1#0.0.AA.0.5E.E6#socket
121 */
122 if (1 < (i = sscanf(buf,"%x.%x.%x.%x.%x.%x",
123 &hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) {
124 cvtbase(256L, 256, hb, i, out, len);
125 return;
126 }
127 /*
128 * try form 8E1#0:0:AA:0:5E:E6#socket
129 */
130 if (1 < (i = sscanf(buf,"%x:%x:%x:%x:%x:%x",
131 &hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) {
132 cvtbase(256L, 256, hb, i, out, len);
133 return;
134 }
135 /*
136 * This is REALLY stretching it but there was a
137 * comma notation separting shorts -- definitely non standard
138 */
139 if (1 < (i = sscanf(buf,"%x,%x,%x",
140 &hb[0], &hb[1], &hb[2]))) {
141 hb[0] = htons(hb[0]); hb[1] = htons(hb[1]);
142 hb[2] = htons(hb[2]);
143 cvtbase(65536L, 256, hb, i, out, len);
144 return;
145 }
146
147 /* Need to decide if base 10, 16 or 8 */
148 while (*bp) switch (*bp++) {
149
150 case '0': case '1': case '2': case '3': case '4': case '5':
151 case '6': case '7': case '-':
152 break;
153
154 case '8': case '9':
155 base10 = 1;
156 break;
157
158 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
159 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
160 base16 = 1;
161 break;
162
163 case 'x': case 'X':
164 *--bp = '0';
165 base16 = 1;
166 break;
167
168 case 'h': case 'H':
169 base16 = 1;
170 /* fall into */
171
172 default:
173 *--bp = 0; /* Ends Loop */
174 }
175 if (base16) {
176 fmt = "%3x";
177 ibase = 4096;
178 } else if (base10 == 0 && *buf == '0') {
179 fmt = "%3o";
180 ibase = 512;
181 } else {
182 fmt = "%3d";
183 ibase = 1000;
184 }
185
186 for (bp = buf; *bp++; ) clen++;
187 if (clen == 0) clen++;
188 if (clen > 18) clen = 18;
189 i = ((clen - 1) / 3) + 1;
190 bp = clen + buf - 3;
191 hp = hb + i - 1;
192
193 while (hp > hb) {
194 (void)sscanf(bp, fmt, hp);
195 bp[0] = 0;
196 hp--;
197 bp -= 3;
198 }
199 (void)sscanf(buf, fmt, hp);
200 cvtbase((long)ibase, 256, hb, i, out, len);
201}
202
203static void
204cvtbase(oldbase,newbase,input,inlen,result,reslen)
205 long oldbase;
206 int newbase;
207 int input[];
208 int inlen;
209 unsigned char result[];
210 int reslen;
211{
212 int d, e;
213 long sum;
214
215 e = 1;
216 while (e > 0 && reslen > 0) {
217 d = 0; e = 0; sum = 0;
218 /* long division: input=input/newbase */
219 while (d < inlen) {
220 sum = sum*oldbase + (long) input[d];
221 e += (sum > 0);
222 input[d++] = sum / newbase;
223 sum %= newbase;
224 }
225 result[--reslen] = sum; /* accumulate remainder */
226 }
227 for (d=0; d < reslen; d++)
228 result[d] = 0;
229}
diff --git a/src/lib/libc/net/ipx_ntoa.c b/src/lib/libc/net/ipx_ntoa.c
new file mode 100644
index 0000000000..1dcfe7181b
--- /dev/null
+++ b/src/lib/libc/net/ipx_ntoa.c
@@ -0,0 +1,58 @@
1/*
2 * Copyright (c) 1986, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: ipx_ntoa.c,v 1.2 1996/08/19 08:29:20 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/param.h>
39#include <netipx/ipx.h>
40#include <stdio.h>
41
42char *
43ipx_ntoa(addr)
44 struct ipx_addr addr;
45{
46 static char obuf[] = "xxxx.xx:xx:xx:xx:xx:xx.uuuuu";
47
48 sprintf(obuf, "%8xH.%02x:%02x:%02x:%02x:%02x:%02x.%u",
49 ntohl(addr.ipx_net.l_net),
50 addr.ipx_host.c_host[0],
51 addr.ipx_host.c_host[1],
52 addr.ipx_host.c_host[2],
53 addr.ipx_host.c_host[3],
54 addr.ipx_host.c_host[4],
55 addr.ipx_host.c_host[5],
56 ntohs(addr.ipx_port));
57 return (obuf);
58}
diff --git a/src/lib/libc/net/iso_addr.3 b/src/lib/libc/net/iso_addr.3
new file mode 100644
index 0000000000..d9bf9086be
--- /dev/null
+++ b/src/lib/libc/net/iso_addr.3
@@ -0,0 +1,110 @@
1.\" $OpenBSD: iso_addr.3,v 1.2 1996/08/19 08:29:22 tholo Exp $
2.\"
3.\" Copyright (c) 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd June 4, 1993
35.Dt ISO_ADDR 3
36.Os
37.Sh NAME
38.Nm iso_addr ,
39.Nm iso_ntoa
40.Nd "elementary network address conversion routines for Open System Interconnection
41.Sh SYNOPSIS
42.Fd #include <sys/types.h>
43.Fd #include <netiso/iso.h>
44.Ft struct iso_addr *
45.Fn iso_addr "char *cp"
46.Ft char *
47.Fn iso_ntoa "struct iso_addr *isoa"
48.Sh DESCRIPTION
49The routine
50.Fn iso_addr
51interprets character strings representing
52.Tn OSI
53addresses, returning binary information suitable
54for use in system calls.
55The routine
56.Fn iso_ntoa
57takes
58.Tn OSI
59addresses and returns
60.Tn ASCII
61strings representing NSAPs (network service
62access points) in a
63notation inverse to that accepted by
64.Fn iso_addr .
65.Pp
66Unfortunately, no universal standard exists for representing
67.Tn OSI
68network addresses.
69.Pp
70The format employed by
71.Fn iso_addr
72is a sequence of hexadecimal
73.Dq digits
74(optionally separated by periods),
75of the form:
76.Bd -filled -offset indent
77<hex digits>.<hex digits>.<hex digits>
78.Ed
79.Pp
80Each pair of hexadecimal digits represents a byte
81with the leading digit indicating the higher-ordered bits.
82A period following an even number of bytes has no
83effect (but may be used to increase legibility).
84A period following an odd number of bytes has the
85effect of causing the byte of address being translated
86to have its higher order bits filled with zeros.
87.Sh RETURN VALUES
88.Fn iso_ntoa
89always returns a null terminated string.
90.Fn iso_addr
91always returns a pointer to a struct iso_addr.
92(See
93.Sx BUGS . )
94.Sh SEE ALSO
95.Xr iso 4
96.Sh HISTORY
97The
98.Fn iso_addr
99and
100.Fn iso_ntoa
101functions appeared in
102.Bx 4.3 Reno .
103.Sh BUGS
104The returned values
105reside in a static memory area.
106.Pp
107The function
108.Fn iso_addr
109should diagnose improperly formed input, and there should be an unambiguous
110way to recognize this.
diff --git a/src/lib/libc/net/iso_addr.c b/src/lib/libc/net/iso_addr.c
new file mode 100644
index 0000000000..01561e395b
--- /dev/null
+++ b/src/lib/libc/net/iso_addr.c
@@ -0,0 +1,119 @@
1/*
2 * Copyright (c) 1989, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: iso_addr.c,v 1.2 1996/08/19 08:29:23 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/types.h>
39#include <netiso/iso.h>
40#include <string.h>
41
42/* States*/
43#define VIRGIN 0
44#define GOTONE 1
45#define GOTTWO 2
46/* Inputs */
47#define DIGIT (4*0)
48#define END (4*1)
49#define DELIM (4*2)
50
51struct iso_addr *
52iso_addr(addr)
53 register const char *addr;
54{
55 static struct iso_addr out_addr;
56 register char *cp = out_addr.isoa_genaddr;
57 char *cplim = cp + sizeof(out_addr.isoa_genaddr);
58 register int byte = 0, state = VIRGIN, new;
59
60 bzero((char *)&out_addr, sizeof(out_addr));
61 do {
62 if ((*addr >= '0') && (*addr <= '9')) {
63 new = *addr - '0';
64 } else if ((*addr >= 'a') && (*addr <= 'f')) {
65 new = *addr - 'a' + 10;
66 } else if ((*addr >= 'A') && (*addr <= 'F')) {
67 new = *addr - 'A' + 10;
68 } else if (*addr == 0)
69 state |= END;
70 else
71 state |= DELIM;
72 addr++;
73 switch (state /* | INPUT */) {
74 case GOTTWO | DIGIT:
75 *cp++ = byte; /*FALLTHROUGH*/
76 case VIRGIN | DIGIT:
77 state = GOTONE; byte = new; continue;
78 case GOTONE | DIGIT:
79 state = GOTTWO; byte = new + (byte << 4); continue;
80 default: /* | DELIM */
81 state = VIRGIN; *cp++ = byte; byte = 0; continue;
82 case GOTONE | END:
83 case GOTTWO | END:
84 *cp++ = byte; /* FALLTHROUGH */
85 case VIRGIN | END:
86 break;
87 }
88 break;
89 } while (cp < cplim);
90 out_addr.isoa_len = cp - out_addr.isoa_genaddr;
91 return (&out_addr);
92}
93static char hexlist[] = "0123456789abcdef";
94
95char *
96iso_ntoa(isoa)
97 const struct iso_addr *isoa;
98{
99 static char obuf[64];
100 register char *out = obuf;
101 register int i;
102 register u_char *in = (u_char *)isoa->isoa_genaddr;
103 u_char *inlim = in + isoa->isoa_len;
104
105 out[1] = 0;
106 while (in < inlim) {
107 i = *in++;
108 *out++ = '.';
109 if (i > 0xf) {
110 out[1] = hexlist[i & 0xf];
111 i >>= 4;
112 out[0] = hexlist[i];
113 out += 2;
114 } else
115 *out++ = hexlist[i];
116 }
117 *out = 0;
118 return(obuf + 1);
119}
diff --git a/src/lib/libc/net/link_addr.3 b/src/lib/libc/net/link_addr.3
new file mode 100644
index 0000000000..eb6c952177
--- /dev/null
+++ b/src/lib/libc/net/link_addr.3
@@ -0,0 +1,131 @@
1.\" $OpenBSD: link_addr.3,v 1.2 1996/08/19 08:29:25 tholo Exp $
2.\"
3.\" Copyright (c) 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" This code is derived from software contributed to Berkeley by
7.\" Donn Seeley at BSDI.
8.\"
9.\" Redistribution and use in source and binary forms, with or without
10.\" modification, are permitted provided that the following conditions
11.\" are met:
12.\" 1. Redistributions of source code must retain the above copyright
13.\" notice, this list of conditions and the following disclaimer.
14.\" 2. Redistributions in binary form must reproduce the above copyright
15.\" notice, this list of conditions and the following disclaimer in the
16.\" documentation and/or other materials provided with the distribution.
17.\" 3. All advertising materials mentioning features or use of this software
18.\" must display the following acknowledgement:
19.\" This product includes software developed by the University of
20.\" California, Berkeley and its contributors.
21.\" 4. Neither the name of the University nor the names of its contributors
22.\" may be used to endorse or promote products derived from this software
23.\" without specific prior written permission.
24.\"
25.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35.\" SUCH DAMAGE.
36.\"
37.Dd July 28, 1993
38.Dt LINK_ADDR 3
39.Os BSD 4.4
40.Sh NAME
41.Nm link_addr ,
42.Nm link_ntoa
43.Nd elementary address specification routines for link level access
44.Sh SYNOPSIS
45.Fd #include <sys/types.h>
46.Fd #include <sys/socket.h>
47.Fd #include <net/if_dl.h>
48.Ft void
49.Fn link_addr "const char *addr" "struct sockaddr_dl *sdl"
50.Ft char *
51.Fn link_ntoa "const struct sockaddr_dl *sdl"
52.Sh DESCRIPTION
53The routine
54.Fn link_addr
55interprets character strings representing
56link-level addresses, returning binary information suitable
57for use in system calls.
58The routine
59.Fn link_ntoa
60takes
61a link-level
62address and returns an
63.Tn ASCII
64string representing some of the information present,
65including the link level address itself, and the interface name
66or number, if present.
67This facility is experimental and is
68still subject to change.
69.Pp
70For
71.Fn link_addr ,
72the string
73.Fa addr
74may contain
75an optional network interface identifier of the form
76.Dq "name unit-number" ,
77suitable for the first argument to
78.Xr ifconfig 4 ,
79followed in all cases by a colon and
80an interface address in the form of
81groups of hexadecimal digits
82separated by periods.
83Each group represents a byte of address;
84address bytes are filled left to right from
85low order bytes through high order bytes.
86.Pp
87.\" A regular expression may make this format clearer:
88.\" .Bd -literal -offset indent
89.\" ([a-z]+[0-9]+:)?[0-9a-f]+(\e.[0-9a-f]+)*
90.\" .Ed
91.\" .Pp
92Thus
93.Li le0:8.0.9.13.d.30
94represents an ethernet address
95to be transmitted on the first Lance ethernet interface.
96.Sh RETURN VALUES
97.Fn link_ntoa
98always returns a null terminated string.
99.Fn link_addr
100has no return value.
101(See
102.Sx BUGS . )
103.Sh SEE ALSO
104.Xr iso 4 ,
105.Sh HISTORY
106The
107.Fn link_addr
108and
109.Fn link_ntoa
110functions appeared in
111.Bx 4.3 Reno .
112.Sh BUGS
113The returned values for link_ntoa
114reside in a static memory area.
115.Pp
116The function
117.Fn link_addr
118should diagnose improperly formed input, and there should be an unambiguous
119way to recognize this.
120.Pp
121If the
122.Va sdl_len
123field of the link socket address
124.Fa sdl
125is 0,
126.Fn link_ntoa
127will not insert a colon before the interface address bytes.
128If this translated address is given to
129.Fn link_addr
130without inserting an initial colon,
131the latter will not interpret it correctly.
diff --git a/src/lib/libc/net/linkaddr.c b/src/lib/libc/net/linkaddr.c
new file mode 100644
index 0000000000..fb522f3233
--- /dev/null
+++ b/src/lib/libc/net/linkaddr.c
@@ -0,0 +1,158 @@
1/*-
2 * Copyright (c) 1990, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: linkaddr.c,v 1.2 1996/08/19 08:29:27 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/types.h>
39#include <sys/socket.h>
40#include <net/if_dl.h>
41#include <string.h>
42
43/* States*/
44#define NAMING 0
45#define GOTONE 1
46#define GOTTWO 2
47#define RESET 3
48/* Inputs */
49#define DIGIT (4*0)
50#define END (4*1)
51#define DELIM (4*2)
52#define LETTER (4*3)
53
54void
55link_addr(addr, sdl)
56 register const char *addr;
57 register struct sockaddr_dl *sdl;
58{
59 register char *cp = sdl->sdl_data;
60 char *cplim = sdl->sdl_len + (char *)sdl;
61 register int byte = 0, state = NAMING, new;
62
63 bzero((char *)&sdl->sdl_family, sdl->sdl_len - 1);
64 sdl->sdl_family = AF_LINK;
65 do {
66 state &= ~LETTER;
67 if ((*addr >= '0') && (*addr <= '9')) {
68 new = *addr - '0';
69 } else if ((*addr >= 'a') && (*addr <= 'f')) {
70 new = *addr - 'a' + 10;
71 } else if ((*addr >= 'A') && (*addr <= 'F')) {
72 new = *addr - 'A' + 10;
73 } else if (*addr == 0) {
74 state |= END;
75 } else if (state == NAMING &&
76 (((*addr >= 'A') && (*addr <= 'Z')) ||
77 ((*addr >= 'a') && (*addr <= 'z'))))
78 state |= LETTER;
79 else
80 state |= DELIM;
81 addr++;
82 switch (state /* | INPUT */) {
83 case NAMING | DIGIT:
84 case NAMING | LETTER:
85 *cp++ = addr[-1];
86 continue;
87 case NAMING | DELIM:
88 state = RESET;
89 sdl->sdl_nlen = cp - sdl->sdl_data;
90 continue;
91 case GOTTWO | DIGIT:
92 *cp++ = byte;
93 /* FALLTHROUGH */
94 case RESET | DIGIT:
95 state = GOTONE;
96 byte = new;
97 continue;
98 case GOTONE | DIGIT:
99 state = GOTTWO;
100 byte = new + (byte << 4);
101 continue;
102 default: /* | DELIM */
103 state = RESET;
104 *cp++ = byte;
105 byte = 0;
106 continue;
107 case GOTONE | END:
108 case GOTTWO | END:
109 *cp++ = byte;
110 /* FALLTHROUGH */
111 case RESET | END:
112 break;
113 }
114 break;
115 } while (cp < cplim);
116 sdl->sdl_alen = cp - LLADDR(sdl);
117 new = cp - (char *)sdl;
118 if (new > sizeof(*sdl))
119 sdl->sdl_len = new;
120 return;
121}
122
123static char hexlist[] = "0123456789abcdef";
124
125char *
126link_ntoa(sdl)
127 register const struct sockaddr_dl *sdl;
128{
129 static char obuf[64];
130 register char *out = obuf;
131 register int i;
132 register u_char *in = (u_char *)LLADDR(sdl);
133 u_char *inlim = in + sdl->sdl_alen;
134 int firsttime = 1;
135
136 if (sdl->sdl_nlen) {
137 bcopy(sdl->sdl_data, obuf, sdl->sdl_nlen);
138 out += sdl->sdl_nlen;
139 if (sdl->sdl_alen)
140 *out++ = ':';
141 }
142 while (in < inlim) {
143 if (firsttime)
144 firsttime = 0;
145 else
146 *out++ = '.';
147 i = *in++;
148 if (i > 0xf) {
149 out[1] = hexlist[i & 0xf];
150 i >>= 4;
151 out[0] = hexlist[i];
152 out += 2;
153 } else
154 *out++ = hexlist[i];
155 }
156 *out = 0;
157 return (obuf);
158}
diff --git a/src/lib/libc/net/ns.3 b/src/lib/libc/net/ns.3
new file mode 100644
index 0000000000..6e096d9f4b
--- /dev/null
+++ b/src/lib/libc/net/ns.3
@@ -0,0 +1,130 @@
1.\" $OpenBSD: ns.3,v 1.2 1996/08/19 08:29:29 tholo Exp $
2.\"
3.\" Copyright (c) 1986, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd June 4, 1993
35.Dt NS 3
36.Os BSD 4.3
37.Sh NAME
38.Nm ns_addr ,
39.Nm ns_ntoa
40.Nd Xerox
41.Tn NS Ns (tm)
42address conversion routines
43.Sh SYNOPSIS
44.Fd #include <sys/types.h>
45.Fd #include <netns/ns.h>
46.Ft struct ns_addr
47.Fn ns_addr "char *cp"
48.Ft char *
49.Fn ns_ntoa "struct ns_addr ns"
50.Sh DESCRIPTION
51The routine
52.Fn ns_addr
53interprets character strings representing
54.Tn XNS
55addresses, returning binary information suitable
56for use in system calls.
57The routine
58.Fn ns_ntoa
59takes
60.Tn XNS
61addresses and returns
62.Tn ASCII
63strings representing the address in a
64notation in common use in the Xerox Development Environment:
65.Bd -filled -offset indent
66<network number>.<host number>.<port number>
67.Ed
68.Pp
69Trailing zero fields are suppressed, and each number is printed in hexadecimal,
70in a format suitable for input to
71.Fn ns_addr .
72Any fields lacking super-decimal digits will have a
73trailing
74.Ql H
75appended.
76.Pp
77Unfortunately, no universal standard exists for representing
78.Tn XNS
79addresses.
80An effort has been made to insure that
81.Fn ns_addr
82be compatible with most formats in common use.
83It will first separate an address into 1 to 3 fields using a single delimiter
84chosen from
85period
86.Ql \&. ,
87colon
88.Ql \&:
89or pound-sign
90.Ql \&# .
91Each field is then examined for byte separators (colon or period).
92If there are byte separators, each subfield separated is taken to be
93a small hexadecimal number, and the entirety is taken as a network-byte-ordered
94quantity to be zero extended in the high-network-order bytes.
95Next, the field is inspected for hyphens, in which case
96the field is assumed to be a number in decimal notation
97with hyphens separating the millenia.
98Next, the field is assumed to be a number:
99It is interpreted
100as hexadecimal if there is a leading
101.Ql 0x
102(as in C),
103a trailing
104.Ql H
105(as in Mesa), or there are any super-decimal digits present.
106It is interpreted as octal is there is a leading
107.Ql 0
108and there are no super-octal digits.
109Otherwise, it is converted as a decimal number.
110.Sh RETURN VALUES
111None. (See
112.Sx BUGS . )
113.Sh SEE ALSO
114.Xr hosts 5 ,
115.Xr networks 5 ,
116.Sh HISTORY
117The
118.Fn ns_addr
119and
120.Fn ns_toa
121functions appeared in
122.Bx 4.3 .
123.Sh BUGS
124The string returned by
125.Fn ns_ntoa
126resides in a static memory area.
127The function
128.Fn ns_addr
129should diagnose improperly formed input, and there should be an unambiguous
130way to recognize this.
diff --git a/src/lib/libc/net/ns_addr.c b/src/lib/libc/net/ns_addr.c
new file mode 100644
index 0000000000..8f2e4bc513
--- /dev/null
+++ b/src/lib/libc/net/ns_addr.c
@@ -0,0 +1,228 @@
1/*
2 * Copyright (c) 1986, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * J.Q. Johnson.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char rcsid[] = "$OpenBSD: ns_addr.c,v 1.4 1997/07/21 20:31:05 deraadt Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#include <sys/param.h>
42#include <netns/ns.h>
43#include <stdio.h>
44#include <string.h>
45
46static struct ns_addr addr, zero_addr;
47
48static void Field __P((char *, u_int8_t *, int));
49static void cvtbase __P((long, int, int[], int, u_int8_t[], int));
50
51struct ns_addr
52ns_addr(name)
53 const char *name;
54{
55 char separator;
56 char *hostname, *socketname, *cp;
57 char buf[50];
58
59 (void)strncpy(buf, name, sizeof(buf) - 1);
60 buf[sizeof(buf) - 1] = '\0';
61
62 /*
63 * First, figure out what he intends as a field separtor.
64 * Despite the way this routine is written, the prefered
65 * form 2-272.AA001234H.01777, i.e. XDE standard.
66 * Great efforts are made to insure backward compatability.
67 */
68 if ((hostname = strchr(buf, '#')))
69 separator = '#';
70 else {
71 hostname = strchr(buf, '.');
72 if ((cp = strchr(buf, ':')) &&
73 ((hostname && cp < hostname) || (hostname == 0))) {
74 hostname = cp;
75 separator = ':';
76 } else
77 separator = '.';
78 }
79 if (hostname)
80 *hostname++ = 0;
81
82 addr = zero_addr;
83 Field(buf, addr.x_net.c_net, 4);
84 if (hostname == 0)
85 return (addr); /* No separator means net only */
86
87 socketname = strchr(hostname, separator);
88 if (socketname) {
89 *socketname++ = 0;
90 Field(socketname, (u_char *)&addr.x_port, 2);
91 }
92
93 Field(hostname, (u_char *)addr.x_host.c_host, 6);
94
95 return (addr);
96}
97
98static void
99Field(buf, out, len)
100 char *buf;
101 u_char *out;
102 int len;
103{
104 register char *bp = buf;
105 int i, ibase, base16 = 0, base10 = 0, clen = 0;
106 int hb[6], *hp;
107 char *fmt;
108
109 /*
110 * first try 2-273#2-852-151-014#socket
111 */
112 if ((*buf != '-') &&
113 (1 < (i = sscanf(buf, "%d-%d-%d-%d-%d",
114 &hb[0], &hb[1], &hb[2], &hb[3], &hb[4])))) {
115 cvtbase(1000L, 256, hb, i, out, len);
116 return;
117 }
118 /*
119 * try form 8E1#0.0.AA.0.5E.E6#socket
120 */
121 if (1 < (i = sscanf(buf,"%x.%x.%x.%x.%x.%x",
122 &hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) {
123 cvtbase(256L, 256, hb, i, out, len);
124 return;
125 }
126 /*
127 * try form 8E1#0:0:AA:0:5E:E6#socket
128 */
129 if (1 < (i = sscanf(buf,"%x:%x:%x:%x:%x:%x",
130 &hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) {
131 cvtbase(256L, 256, hb, i, out, len);
132 return;
133 }
134 /*
135 * This is REALLY stretching it but there was a
136 * comma notation separting shorts -- definitely non standard
137 */
138 if (1 < (i = sscanf(buf,"%x,%x,%x",
139 &hb[0], &hb[1], &hb[2]))) {
140 hb[0] = htons(hb[0]); hb[1] = htons(hb[1]);
141 hb[2] = htons(hb[2]);
142 cvtbase(65536L, 256, hb, i, out, len);
143 return;
144 }
145
146 /* Need to decide if base 10, 16 or 8 */
147 while (*bp) switch (*bp++) {
148
149 case '0': case '1': case '2': case '3': case '4': case '5':
150 case '6': case '7': case '-':
151 break;
152
153 case '8': case '9':
154 base10 = 1;
155 break;
156
157 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
158 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
159 base16 = 1;
160 break;
161
162 case 'x': case 'X':
163 *--bp = '0';
164 base16 = 1;
165 break;
166
167 case 'h': case 'H':
168 base16 = 1;
169 /* fall into */
170
171 default:
172 *--bp = 0; /* Ends Loop */
173 }
174 if (base16) {
175 fmt = "%3x";
176 ibase = 4096;
177 } else if (base10 == 0 && *buf == '0') {
178 fmt = "%3o";
179 ibase = 512;
180 } else {
181 fmt = "%3d";
182 ibase = 1000;
183 }
184
185 for (bp = buf; *bp++; ) clen++;
186 if (clen == 0) clen++;
187 if (clen > 18) clen = 18;
188 i = ((clen - 1) / 3) + 1;
189 bp = clen + buf - 3;
190 hp = hb + i - 1;
191
192 while (hp > hb) {
193 (void)sscanf(bp, fmt, hp);
194 bp[0] = 0;
195 hp--;
196 bp -= 3;
197 }
198 (void)sscanf(buf, fmt, hp);
199 cvtbase((long)ibase, 256, hb, i, out, len);
200}
201
202static void
203cvtbase(oldbase,newbase,input,inlen,result,reslen)
204 long oldbase;
205 int newbase;
206 int input[];
207 int inlen;
208 unsigned char result[];
209 int reslen;
210{
211 int d, e;
212 long sum;
213
214 e = 1;
215 while (e > 0 && reslen > 0) {
216 d = 0; e = 0; sum = 0;
217 /* long division: input=input/newbase */
218 while (d < inlen) {
219 sum = sum*oldbase + (long) input[d];
220 e += (sum > 0);
221 input[d++] = sum / newbase;
222 sum %= newbase;
223 }
224 result[--reslen] = sum; /* accumulate remainder */
225 }
226 for (d=0; d < reslen; d++)
227 result[d] = 0;
228}
diff --git a/src/lib/libc/net/ns_ntoa.c b/src/lib/libc/net/ns_ntoa.c
new file mode 100644
index 0000000000..c33f710966
--- /dev/null
+++ b/src/lib/libc/net/ns_ntoa.c
@@ -0,0 +1,101 @@
1/*
2 * Copyright (c) 1986, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: ns_ntoa.c,v 1.7 1997/08/24 21:25:48 millert Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/param.h>
39#include <netns/ns.h>
40#include <stdio.h>
41
42static char *spectHex __P((char *));
43
44char *
45ns_ntoa(addr)
46 struct ns_addr addr;
47{
48 static char obuf[40];
49 union { union ns_net net_e; u_int32_t long_e; } net;
50 in_port_t port = htons(addr.x_port);
51 register char *cp;
52 char *cp2;
53 register u_char *up = addr.x_host.c_host;
54 u_char *uplim = up + 6;
55
56 net.net_e = addr.x_net;
57 sprintf(obuf, "%x", ntohl(net.long_e));
58 cp = spectHex(obuf);
59 cp2 = cp + 1;
60 while (*up==0 && up < uplim) up++;
61 if (up == uplim) {
62 if (port) {
63 sprintf(cp, ".0");
64 cp += 2;
65 }
66 } else {
67 sprintf(cp, ".%x", *up++);
68 while (up < uplim) {
69 while (*cp) cp++;
70 sprintf(cp, "%02x", *up++);
71 }
72 cp = spectHex(cp2);
73 }
74 if (port) {
75 sprintf(cp, ".%x", port);
76 spectHex(cp + 1);
77 }
78 return (obuf);
79}
80
81static char *
82spectHex(p0)
83 char *p0;
84{
85 int ok = 0;
86 int nonzero = 0;
87 register char *p = p0;
88 for (; *p; p++) switch (*p) {
89
90 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
91 *p += ('A' - 'a');
92 /* fall into . . . */
93 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
94 ok = 1;
95 case '1': case '2': case '3': case '4': case '5':
96 case '6': case '7': case '8': case '9':
97 nonzero = 1;
98 }
99 if (nonzero && !ok) { *p++ = 'H'; *p = 0; }
100 return (p);
101}
diff --git a/src/lib/libc/net/nsap_addr.c b/src/lib/libc/net/nsap_addr.c
new file mode 100644
index 0000000000..22a5f8d66e
--- /dev/null
+++ b/src/lib/libc/net/nsap_addr.c
@@ -0,0 +1,109 @@
1/* $OpenBSD: nsap_addr.c,v 1.4 1997/07/09 01:08:45 millert Exp $ */
2
3/*
4 * Copyright (c) 1996 by Internet Software Consortium.
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
11 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
12 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
13 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
16 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
17 * SOFTWARE.
18 */
19
20#if defined(LIBC_SCCS) && !defined(lint)
21#if 0
22static char rcsid[] = "$From: nsap_addr.c,v 8.3 1996/08/05 08:31:35 vixie Exp $";
23#else
24static char rcsid[] = "$OpenBSD: nsap_addr.c,v 1.4 1997/07/09 01:08:45 millert Exp $";
25#endif
26#endif /* LIBC_SCCS and not lint */
27
28#include <sys/types.h>
29#include <sys/param.h>
30#include <sys/socket.h>
31#include <netinet/in.h>
32#include <arpa/nameser.h>
33#include <ctype.h>
34#include <resolv.h>
35
36static char
37xtob(c)
38 register int c;
39{
40 return (c - (((c >= '0') && (c <= '9')) ? '0' : '7'));
41}
42
43u_int
44inet_nsap_addr(ascii, binary, maxlen)
45 const char *ascii;
46 u_char *binary;
47 int maxlen;
48{
49 register u_char c, nib;
50 u_int len = 0;
51
52 while ((c = *ascii++) != '\0' && len < maxlen) {
53 if (c == '.' || c == '+' || c == '/')
54 continue;
55 if (!isascii(c))
56 return (0);
57 if (islower(c))
58 c = toupper(c);
59 if (isxdigit(c)) {
60 nib = xtob(c);
61 if ((c = *ascii++)) {
62 c = toupper(c);
63 if (isxdigit(c)) {
64 *binary++ = (nib << 4) | xtob(c);
65 len++;
66 } else
67 return (0);
68 }
69 else
70 return (0);
71 }
72 else
73 return (0);
74 }
75 return (len);
76}
77
78char *
79inet_nsap_ntoa(binlen, binary, ascii)
80 int binlen;
81 register const u_char *binary;
82 register char *ascii;
83{
84 register int nib;
85 int i;
86 static char tmpbuf[255*3];
87 char *start;
88
89 if (ascii)
90 start = ascii;
91 else {
92 ascii = tmpbuf;
93 start = tmpbuf;
94 }
95
96 if (binlen > 255)
97 binlen = 255;
98
99 for (i = 0; i < binlen; i++) {
100 nib = *binary >> 4;
101 *ascii++ = nib + (nib < 10 ? '0' : '7');
102 nib = *binary++ & 0x0f;
103 *ascii++ = nib + (nib < 10 ? '0' : '7');
104 if (((i % 2) == 0 && (i + 1) < binlen))
105 *ascii++ = '.';
106 }
107 *ascii = '\0';
108 return (start);
109}
diff --git a/src/lib/libc/net/ntohl.c b/src/lib/libc/net/ntohl.c
new file mode 100644
index 0000000000..7d3e227e60
--- /dev/null
+++ b/src/lib/libc/net/ntohl.c
@@ -0,0 +1,25 @@
1/*
2 * Written by J.T. Conklin <jtc@netbsd.org>.
3 * Public domain.
4 */
5
6#if defined(LIBC_SCCS) && !defined(lint)
7static char *rcsid = "$OpenBSD: ntohl.c,v 1.4 1996/12/12 03:19:56 tholo Exp $";
8#endif /* LIBC_SCCS and not lint */
9
10#include <sys/types.h>
11#include <machine/endian.h>
12
13#undef ntohl
14
15u_int32_t
16ntohl(x)
17 u_int32_t x;
18{
19#if BYTE_ORDER == LITTLE_ENDIAN
20 u_char *s = (u_char *)&x;
21 return (u_int32_t)(s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]);
22#else
23 return x;
24#endif
25}
diff --git a/src/lib/libc/net/ntohs.c b/src/lib/libc/net/ntohs.c
new file mode 100644
index 0000000000..cf6414d4a6
--- /dev/null
+++ b/src/lib/libc/net/ntohs.c
@@ -0,0 +1,29 @@
1/*
2 * Written by J.T. Conklin <jtc@netbsd.org>.
3 * Public domain.
4 */
5
6#if defined(LIBC_SCCS) && !defined(lint)
7static char *rcsid = "$OpenBSD: ntohs.c,v 1.6 1997/07/25 20:30:07 mickey Exp $";
8#endif /* LIBC_SCCS and not lint */
9
10#include <sys/types.h>
11#include <machine/endian.h>
12
13#undef ntohs
14
15u_int16_t
16#ifdef __STDC__
17ntohs(u_int16_t x)
18#else
19ntohs(x)
20 u_int16_t x;
21#endif
22{
23#if BYTE_ORDER == LITTLE_ENDIAN
24 u_char *s = (u_char *) &x;
25 return (u_int16_t)(s[0] << 8 | s[1]);
26#else
27 return x;
28#endif
29}
diff --git a/src/lib/libc/net/rcmd.3 b/src/lib/libc/net/rcmd.3
new file mode 100644
index 0000000000..e69e822834
--- /dev/null
+++ b/src/lib/libc/net/rcmd.3
@@ -0,0 +1,227 @@
1.\" $OpenBSD: rcmd.3,v 1.10 1997/09/29 18:25:47 deraadt Exp $
2.\"
3.\" Copyright (c) 1983, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd June 4, 1993
35.Dt RCMD 3
36.Os BSD 4.2
37.Sh NAME
38.Nm rcmd ,
39.Nm rresvport ,
40.Nm iruserok ,
41.Nm ruserok
42.Nd routines for returning a stream to a remote command
43.Sh SYNOPSIS
44.Fd #include <unistd.h>
45.Ft int
46.Fn rcmd "char **ahost" "int inport" "const char *locuser" "const char *remuser" "const char *cmd" "int *fd2p"
47.Ft int
48.Fn rresvport "int *port"
49.Ft int
50.Fn iruserok "u_int32_t raddr" "int superuser" "const char *ruser" "const char *luser"
51.Ft int
52.Fn ruserok "const char *rhost" "int superuser" "const char *ruser" "const char *luser"
53.Sh DESCRIPTION
54The
55.Fn rcmd
56function
57is used by the super-user to execute a command on a remote
58machine using an authentication scheme based on reserved
59port numbers. If the calling process is not setuid and the
60.Li RSH
61environment variable is set and
62.Fa inport
63is
64.Li shell/tcp ,
65.Xr rcmdsh 3
66is called instead with the value of
67.Li RSH .
68Alternately, if the user is not the super-user,
69.Fn rcmd
70will invoke
71.Xr rcmdsh 3
72to run the command via
73.Xr rsh 1 .
74The
75.Fn rresvport
76function
77returns a descriptor to a socket
78with an address in the privileged port space.
79The
80.Fn iruserok
81and
82.Fn ruserok
83functions are used by servers
84to authenticate clients requesting service with
85.Fn rcmd .
86All four functions are present in the same file and are used
87by the
88.Xr rshd 8
89server (among others).
90.Pp
91The
92.Fn rcmd
93function
94looks up the host
95.Fa *ahost
96using
97.Xr gethostbyname 3 ,
98returning \-1 if the host does not exist.
99Otherwise
100.Fa *ahost
101is set to the standard name of the host
102and a connection is established to a server
103residing at the well-known Internet port
104.Fa inport .
105If the user is not the super-user, the only valid port is
106.Li shell/tcp ,
107(usually port 514).
108.Pp
109If the connection succeeds,
110a socket in the Internet domain of type
111.Dv SOCK_STREAM
112is returned to the caller, and given to the remote
113command as
114.Em stdin
115and
116.Em stdout .
117If
118.Fa fd2p
119is non-zero, then an auxiliary channel to a control
120process will be set up, and a descriptor for it will be placed
121in
122.Fa *fd2p .
123The control process will return diagnostic
124output from the command (unit 2) on this channel, and will also
125accept bytes on this channel as being
126.Tn UNIX
127signal numbers, to be
128forwarded to the process group of the command.
129If
130.Fa fd2p
131is 0, then the
132.Em stderr
133(unit 2 of the remote
134command) will be made the same as the
135.Em stdout
136and no
137provision is made for sending arbitrary signals to the remote process,
138although you may be able to get its attention by using out-of-band data.
139Note that if the user is not the super-user,
140.Fa fd2p
141must be 0.
142.Pp
143The protocol is described in detail in
144.Xr rshd 8 .
145.Pp
146The
147.Fn rresvport
148function is used to obtain a socket with a privileged
149address bound to it. This socket is suitable for use
150by
151.Fn rcmd
152and several other functions. Privileged Internet ports are those
153in the range 0 to 1023. Only the super-user
154is allowed to bind an address of this sort to a socket.
155.Fn rresvport
156needs to be seeded with a port number; if that port
157is not available it will find another.
158.Pp
159The
160.Fn iruserok
161and
162.Fn ruserok
163functions take a remote host's IP address or name, respectively,
164two user names and a flag indicating whether the local user's
165name is that of the super-user.
166Then, if the user is
167.Em NOT
168the super-user, it checks the
169.Pa /etc/hosts.equiv
170file.
171If that lookup is not done, or is unsuccessful, the
172.Pa .rhosts
173in the local user's home directory is checked to see if the request for
174service is allowed.
175.Pp
176If this file does not exist, is not a regular file, is owned by anyone
177other than the user or the super-user, or is writeable by anyone other
178than the owner, the check automatically fails.
179Zero is returned if the machine name is listed in the
180.Dq Pa hosts.equiv
181file, or the host and remote user name are found in the
182.Dq Pa .rhosts
183file; otherwise
184.Fn iruserok
185and
186.Fn ruserok
187return \-1.
188If the local domain (as obtained from
189.Xr gethostname 3 )
190is the same as the remote domain, only the machine name need be specified.
191.Pp
192If the IP address of the remote host is known,
193.Fn iruserok
194should be used in preference to
195.Fn ruserok ,
196as it does not require trusting the DNS server for the remote host's domain.
197.Sh DIAGNOSTICS
198The
199.Fn rcmd
200function
201returns a valid socket descriptor on success.
202It returns \-1 on error and prints a diagnostic message on the standard error.
203.Pp
204The
205.Fn rresvport
206function
207returns a valid, bound socket descriptor on success.
208It returns \-1 on error with the global value
209.Va errno
210set according to the reason for failure.
211The error code
212.Dv EAGAIN
213is overloaded to mean ``All network ports in use.''
214.Sh SEE ALSO
215.Xr rlogin 1 ,
216.Xr rsh 1 ,
217.Xr intro 2 ,
218.Xr rexec 3 ,
219.Xr rcmdsh 3 ,
220.Xr rexecd 8 ,
221.Xr rlogind 8 ,
222.Xr bindresvport 3 ,
223.Xr rshd 8
224.Sh HISTORY
225These
226functions appeared in
227.Bx 4.2 .
diff --git a/src/lib/libc/net/rcmd.c b/src/lib/libc/net/rcmd.c
new file mode 100644
index 0000000000..c933f5b447
--- /dev/null
+++ b/src/lib/libc/net/rcmd.c
@@ -0,0 +1,607 @@
1/*
2 * Copyright (c) 1995, 1996, 1998 Theo de Raadt. All rights reserved.
3 * Copyright (c) 1983, 1993, 1994
4 * The Regents of the University of California. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by the University of
17 * California, Berkeley and its contributors.
18 * This product includes software developed by Theo de Raadt.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36#if defined(LIBC_SCCS) && !defined(lint)
37static char *rcsid = "$OpenBSD: rcmd.c,v 1.31 1998/03/19 00:30:05 millert Exp $";
38#endif /* LIBC_SCCS and not lint */
39
40#include <sys/param.h>
41#include <sys/socket.h>
42#include <sys/stat.h>
43
44#include <netinet/in.h>
45#include <arpa/inet.h>
46
47#include <signal.h>
48#include <fcntl.h>
49#include <netdb.h>
50#include <unistd.h>
51#include <pwd.h>
52#include <errno.h>
53#include <stdio.h>
54#include <ctype.h>
55#include <string.h>
56#include <syslog.h>
57#include <stdlib.h>
58#include <netgroup.h>
59
60int __ivaliduser __P((FILE *, in_addr_t, const char *, const char *));
61static int __icheckhost __P((u_int32_t, const char *));
62static char *__gethostloop __P((u_int32_t));
63
64int
65rcmd(ahost, rport, locuser, remuser, cmd, fd2p)
66 char **ahost;
67 in_port_t rport;
68 const char *locuser, *remuser, *cmd;
69 int *fd2p;
70{
71 struct hostent *hp;
72 struct sockaddr_in sin, from;
73 fd_set *readsp = NULL;
74 int oldmask;
75 pid_t pid;
76 int s, lport, timo;
77 char c, *p;
78
79 /* call rcmdsh() with specified remote shell if appropriate. */
80 if (!issetugid() && (p = getenv("RSH"))) {
81 struct servent *sp = getservbyname("shell", "tcp");
82
83 if (sp && sp->s_port == rport)
84 return (rcmdsh(ahost, rport, locuser, remuser,
85 cmd, p));
86 }
87
88 /* use rsh(1) if non-root and remote port is shell. */
89 if (geteuid()) {
90 struct servent *sp = getservbyname("shell", "tcp");
91
92 if (sp && sp->s_port == rport)
93 return (rcmdsh(ahost, rport, locuser, remuser,
94 cmd, NULL));
95 }
96
97 pid = getpid();
98 hp = gethostbyname(*ahost);
99 if (hp == NULL) {
100 herror(*ahost);
101 return (-1);
102 }
103 *ahost = hp->h_name;
104
105 oldmask = sigblock(sigmask(SIGURG));
106 for (timo = 1, lport = IPPORT_RESERVED - 1;;) {
107 s = rresvport(&lport);
108 if (s < 0) {
109 if (errno == EAGAIN)
110 (void)fprintf(stderr,
111 "rcmd: socket: All ports in use\n");
112 else
113 (void)fprintf(stderr, "rcmd: socket: %s\n",
114 strerror(errno));
115 sigsetmask(oldmask);
116 return (-1);
117 }
118 fcntl(s, F_SETOWN, pid);
119 bzero(&sin, sizeof sin);
120 sin.sin_len = sizeof(struct sockaddr_in);
121 sin.sin_family = hp->h_addrtype;
122 sin.sin_port = rport;
123 bcopy(hp->h_addr_list[0], &sin.sin_addr, hp->h_length);
124 if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0)
125 break;
126 (void)close(s);
127 if (errno == EADDRINUSE) {
128 lport--;
129 continue;
130 }
131 if (errno == ECONNREFUSED && timo <= 16) {
132 (void)sleep(timo);
133 timo *= 2;
134 continue;
135 }
136 if (hp->h_addr_list[1] != NULL) {
137 int oerrno = errno;
138
139 (void)fprintf(stderr, "connect to address %s: ",
140 inet_ntoa(sin.sin_addr));
141 errno = oerrno;
142 perror(0);
143 hp->h_addr_list++;
144 bcopy(hp->h_addr_list[0], &sin.sin_addr, hp->h_length);
145 (void)fprintf(stderr, "Trying %s...\n",
146 inet_ntoa(sin.sin_addr));
147 continue;
148 }
149 (void)fprintf(stderr, "%s: %s\n", hp->h_name, strerror(errno));
150 sigsetmask(oldmask);
151 return (-1);
152 }
153#if 0
154 /*
155 * try to rresvport() to the same port. This will make rresvport()
156 * fail it's first bind, resulting in it choosing a random port.
157 */
158 lport--;
159#endif
160 if (fd2p == 0) {
161 write(s, "", 1);
162 lport = 0;
163 } else {
164 char num[8];
165 int s2 = rresvport(&lport), s3;
166 int len = sizeof(from);
167 int fdssize = howmany(MAX(s, s2)+1, NFDBITS) * sizeof(fd_mask);
168
169 if (s2 < 0)
170 goto bad;
171 readsp = (fd_set *)malloc(fdssize);
172 if (readsp == NULL)
173 goto bad;
174 listen(s2, 1);
175 (void)snprintf(num, sizeof(num), "%d", lport);
176 if (write(s, num, strlen(num)+1) != strlen(num)+1) {
177 (void)fprintf(stderr,
178 "rcmd: write (setting up stderr): %s\n",
179 strerror(errno));
180 (void)close(s2);
181 goto bad;
182 }
183again:
184 bzero(readsp, fdssize);
185 FD_SET(s, readsp);
186 FD_SET(s2, readsp);
187 errno = 0;
188 if (select(MAX(s, s2) + 1, readsp, 0, 0, 0) < 1 ||
189 !FD_ISSET(s2, readsp)) {
190 if (errno != 0)
191 (void)fprintf(stderr,
192 "rcmd: select (setting up stderr): %s\n",
193 strerror(errno));
194 else
195 (void)fprintf(stderr,
196 "select: protocol failure in circuit setup\n");
197 (void)close(s2);
198 goto bad;
199 }
200 s3 = accept(s2, (struct sockaddr *)&from, &len);
201 /*
202 * XXX careful for ftp bounce attacks. If discovered, shut them
203 * down and check for the real auxiliary channel to connect.
204 */
205 if (from.sin_family == AF_INET && from.sin_port == htons(20)) {
206 close(s3);
207 goto again;
208 }
209 (void)close(s2);
210 if (s3 < 0) {
211 (void)fprintf(stderr,
212 "rcmd: accept: %s\n", strerror(errno));
213 lport = 0;
214 goto bad;
215 }
216 *fd2p = s3;
217 from.sin_port = ntohs(from.sin_port);
218 if (from.sin_family != AF_INET ||
219 from.sin_port >= IPPORT_RESERVED ||
220 from.sin_port < IPPORT_RESERVED / 2) {
221 (void)fprintf(stderr,
222 "socket: protocol failure in circuit setup.\n");
223 goto bad2;
224 }
225 }
226 (void)write(s, locuser, strlen(locuser)+1);
227 (void)write(s, remuser, strlen(remuser)+1);
228 (void)write(s, cmd, strlen(cmd)+1);
229 if (read(s, &c, 1) != 1) {
230 (void)fprintf(stderr,
231 "rcmd: %s: %s\n", *ahost, strerror(errno));
232 goto bad2;
233 }
234 if (c != 0) {
235 while (read(s, &c, 1) == 1) {
236 (void)write(STDERR_FILENO, &c, 1);
237 if (c == '\n')
238 break;
239 }
240 goto bad2;
241 }
242 sigsetmask(oldmask);
243 free(readsp);
244 return (s);
245bad2:
246 if (lport)
247 (void)close(*fd2p);
248bad:
249 if (readsp)
250 free(readsp);
251 (void)close(s);
252 sigsetmask(oldmask);
253 return (-1);
254}
255
256int
257rresvport(alport)
258 int *alport;
259{
260 struct sockaddr_in sin;
261 int s;
262
263 bzero(&sin, sizeof sin);
264 sin.sin_len = sizeof(struct sockaddr_in);
265 sin.sin_family = AF_INET;
266 sin.sin_addr.s_addr = INADDR_ANY;
267 s = socket(AF_INET, SOCK_STREAM, 0);
268 if (s < 0)
269 return (-1);
270 sin.sin_port = htons((in_port_t)*alport);
271 if (*alport < IPPORT_RESERVED - 1) {
272 if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0)
273 return (s);
274 if (errno != EADDRINUSE) {
275 (void)close(s);
276 return (-1);
277 }
278 }
279 sin.sin_port = 0;
280 if (bindresvport(s, &sin) == -1) {
281 (void)close(s);
282 return (-1);
283 }
284 *alport = (int)ntohs(sin.sin_port);
285 return (s);
286}
287
288int __check_rhosts_file = 1;
289char *__rcmd_errstr;
290
291int
292ruserok(rhost, superuser, ruser, luser)
293 const char *rhost, *ruser, *luser;
294 int superuser;
295{
296 struct hostent *hp;
297 char **ap;
298 int i;
299#define MAXADDRS 35
300 u_int32_t addrs[MAXADDRS + 1];
301
302 if ((hp = gethostbyname(rhost)) == NULL)
303 return (-1);
304 for (i = 0, ap = hp->h_addr_list; *ap && i < MAXADDRS; ++ap, ++i)
305 bcopy(*ap, &addrs[i], sizeof(addrs[i]));
306 addrs[i] = 0;
307
308 for (i = 0; i < MAXADDRS && addrs[i]; i++)
309 if (iruserok((in_addr_t)addrs[i], superuser, ruser, luser) == 0)
310 return (0);
311 return (-1);
312}
313
314/*
315 * New .rhosts strategy: We are passed an ip address. We spin through
316 * hosts.equiv and .rhosts looking for a match. When the .rhosts only
317 * has ip addresses, we don't have to trust a nameserver. When it
318 * contains hostnames, we spin through the list of addresses the nameserver
319 * gives us and look for a match.
320 *
321 * Returns 0 if ok, -1 if not ok.
322 */
323int
324iruserok(raddr, superuser, ruser, luser)
325 u_int32_t raddr;
326 int superuser;
327 const char *ruser, *luser;
328{
329 register char *cp;
330 struct stat sbuf;
331 struct passwd *pwd;
332 FILE *hostf;
333 uid_t uid;
334 int first;
335 char pbuf[MAXPATHLEN];
336
337 first = 1;
338 hostf = superuser ? NULL : fopen(_PATH_HEQUIV, "r");
339again:
340 if (hostf) {
341 if (__ivaliduser(hostf, raddr, luser, ruser) == 0) {
342 (void)fclose(hostf);
343 return (0);
344 }
345 (void)fclose(hostf);
346 }
347 if (first == 1 && (__check_rhosts_file || superuser)) {
348 first = 0;
349 if ((pwd = getpwnam(luser)) == NULL)
350 return (-1);
351 (void)strcpy(pbuf, pwd->pw_dir);
352 (void)strcat(pbuf, "/.rhosts");
353
354 /*
355 * Change effective uid while opening .rhosts. If root and
356 * reading an NFS mounted file system, can't read files that
357 * are protected read/write owner only.
358 */
359 uid = geteuid();
360 (void)seteuid(pwd->pw_uid);
361 hostf = fopen(pbuf, "r");
362 (void)seteuid(uid);
363
364 if (hostf == NULL)
365 return (-1);
366 /*
367 * If not a regular file, or is owned by someone other than
368 * user or root or if writeable by anyone but the owner, quit.
369 */
370 cp = NULL;
371 if (lstat(pbuf, &sbuf) < 0)
372 cp = ".rhosts lstat failed";
373 else if (!S_ISREG(sbuf.st_mode))
374 cp = ".rhosts not regular file";
375 else if (fstat(fileno(hostf), &sbuf) < 0)
376 cp = ".rhosts fstat failed";
377 else if (sbuf.st_uid && sbuf.st_uid != pwd->pw_uid)
378 cp = "bad .rhosts owner";
379 else if (sbuf.st_mode & (S_IWGRP|S_IWOTH))
380 cp = ".rhosts writeable by other than owner";
381 /* If there were any problems, quit. */
382 if (cp) {
383 __rcmd_errstr = cp;
384 (void)fclose(hostf);
385 return (-1);
386 }
387 goto again;
388 }
389 return (-1);
390}
391
392/*
393 * XXX
394 * Don't make static, used by lpd(8).
395 *
396 * Returns 0 if ok, -1 if not ok.
397 */
398int
399__ivaliduser(hostf, raddrl, luser, ruser)
400 FILE *hostf;
401 in_addr_t raddrl;
402 const char *luser, *ruser;
403{
404 register char *user, *p;
405 char *buf;
406 const char *auser, *ahost;
407 int hostok, userok;
408 char *rhost = (char *)-1;
409 char domain[MAXHOSTNAMELEN];
410 u_int32_t raddr = (u_int32_t)raddrl;
411 size_t buflen;
412
413 getdomainname(domain, sizeof(domain));
414
415 while ((buf = fgetln(hostf, &buflen))) {
416 p = buf;
417 if (*p == '#')
418 continue;
419 while (*p != '\n' && *p != ' ' && *p != '\t' && p < buf + buflen) {
420 if (!isprint(*p))
421 goto bail;
422 *p = isupper(*p) ? tolower(*p) : *p;
423 p++;
424 }
425 if (p >= buf + buflen)
426 continue;
427 if (*p == ' ' || *p == '\t') {
428 *p++ = '\0';
429 while ((*p == ' ' || *p == '\t') && p < buf + buflen)
430 p++;
431 if (p >= buf + buflen)
432 continue;
433 user = p;
434 while (*p != '\n' && *p != ' ' &&
435 *p != '\t' && p < buf + buflen) {
436 if (!isprint(*p))
437 goto bail;
438 p++;
439 }
440 } else
441 user = p;
442 *p = '\0';
443
444 if (p == buf)
445 continue;
446
447 auser = *user ? user : luser;
448 ahost = buf;
449
450 if (strlen(ahost) >= MAXHOSTNAMELEN)
451 continue;
452
453 /*
454 * innetgr() must lookup a hostname (we do not attempt
455 * to change the semantics so that netgroups may have
456 * #.#.#.# addresses in the list.)
457 */
458 if (ahost[0] == '+')
459 switch (ahost[1]) {
460 case '\0':
461 hostok = 1;
462 break;
463 case '@':
464 if (rhost == (char *)-1)
465 rhost = __gethostloop(raddr);
466 hostok = 0;
467 if (rhost)
468 hostok = innetgr(&ahost[2], rhost,
469 NULL, domain);
470 break;
471 default:
472 hostok = __icheckhost(raddr, &ahost[1]);
473 break;
474 }
475 else if (ahost[0] == '-')
476 switch (ahost[1]) {
477 case '\0':
478 hostok = -1;
479 break;
480 case '@':
481 if (rhost == (char *)-1)
482 rhost = __gethostloop(raddr);
483 hostok = 0;
484 if (rhost)
485 hostok = -innetgr(&ahost[2], rhost,
486 NULL, domain);
487 break;
488 default:
489 hostok = -__icheckhost(raddr, &ahost[1]);
490 break;
491 }
492 else
493 hostok = __icheckhost(raddr, ahost);
494
495
496 if (auser[0] == '+')
497 switch (auser[1]) {
498 case '\0':
499 userok = 1;
500 break;
501 case '@':
502 userok = innetgr(&auser[2], NULL, ruser,
503 domain);
504 break;
505 default:
506 userok = strcmp(ruser, &auser[1]) ? 0 : 1;
507 break;
508 }
509 else if (auser[0] == '-')
510 switch (auser[1]) {
511 case '\0':
512 userok = -1;
513 break;
514 case '@':
515 userok = -innetgr(&auser[2], NULL, ruser,
516 domain);
517 break;
518 default:
519 userok = strcmp(ruser, &auser[1]) ? 0 : -1;
520 break;
521 }
522 else
523 userok = strcmp(ruser, auser) ? 0 : 1;
524
525 /* Check if one component did not match */
526 if (hostok == 0 || userok == 0)
527 continue;
528
529 /* Check if we got a forbidden pair */
530 if (userok <= -1 || hostok <= -1)
531 return (-1);
532
533 /* Check if we got a valid pair */
534 if (hostok >= 1 && userok >= 1)
535 return (0);
536 }
537bail:
538 return (-1);
539}
540
541/*
542 * Returns "true" if match, 0 if no match. If we do not find any
543 * semblance of an A->PTR->A loop, allow a simple #.#.#.# match to work.
544 */
545static int
546__icheckhost(raddr, lhost)
547 u_int32_t raddr;
548 const char *lhost;
549{
550 register struct hostent *hp;
551 register char **pp;
552 struct in_addr in;
553
554 hp = gethostbyname(lhost);
555 if (hp != NULL) {
556 /* Spin through ip addresses. */
557 for (pp = hp->h_addr_list; *pp; ++pp)
558 if (!bcmp(&raddr, *pp, sizeof(raddr)))
559 return (1);
560 }
561
562 in.s_addr = raddr;
563 if (strcmp(lhost, inet_ntoa(in)) == 0)
564 return (1);
565 return (0);
566}
567
568/*
569 * Return the hostname associated with the supplied address.
570 * Do a reverse lookup as well for security. If a loop cannot
571 * be found, pack the result of inet_ntoa() into the string.
572 */
573static char *
574__gethostloop(raddr)
575 u_int32_t raddr;
576{
577 static char remotehost[MAXHOSTNAMELEN];
578 struct hostent *hp;
579 struct in_addr in;
580
581 hp = gethostbyaddr((char *) &raddr, sizeof(raddr), AF_INET);
582 if (hp == NULL)
583 return (NULL);
584
585 /*
586 * Look up the name and check that the supplied
587 * address is in the list
588 */
589 strncpy(remotehost, hp->h_name, sizeof(remotehost) - 1);
590 remotehost[sizeof(remotehost) - 1] = '\0';
591 hp = gethostbyname(remotehost);
592 if (hp == NULL)
593 return (NULL);
594
595 for (; hp->h_addr_list[0] != NULL; hp->h_addr_list++)
596 if (!bcmp(hp->h_addr_list[0], (caddr_t)&raddr, sizeof(raddr)))
597 return (remotehost);
598
599 /*
600 * either the DNS adminstrator has made a configuration
601 * mistake, or someone has attempted to spoof us
602 */
603 in.s_addr = raddr;
604 syslog(LOG_NOTICE, "rcmd: address %s not listed for host %s",
605 inet_ntoa(in), hp->h_name);
606 return (NULL);
607}
diff --git a/src/lib/libc/net/rcmdsh.3 b/src/lib/libc/net/rcmdsh.3
new file mode 100644
index 0000000000..fd89acee8f
--- /dev/null
+++ b/src/lib/libc/net/rcmdsh.3
@@ -0,0 +1,108 @@
1.\" $OpenBSD: rcmdsh.3,v 1.3 1998/06/26 17:54:09 millert Exp $
2.\"
3.\" Copyright (c) 1983, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd Sep 1, 1996
35.Dt RCMDSH 3
36.Os OpenBSD
37.Sh NAME
38.Nm rcmdsh
39.Nd return a stream to a remote command without superuser
40.Sh SYNOPSIS
41.Fd #include <unistd.h>
42.Ft int
43.Fn rcmdsh "char **ahost" "int inport" "const char *locuser" "const char *remuser" "const char *cmd" "char *rshprog"
44.Sh DESCRIPTION
45The
46.Fn rcmdsh
47function
48is used by normal users to execute a command on
49a remote machine using an authentication scheme based
50on reserved port numbers using
51.Xr rshd 8
52or the value of
53.Fa rshprog
54(if non-NULL).
55.Pp
56The
57.Fn rcmdsh
58function
59looks up the host
60.Fa *ahost
61using
62.Xr gethostbyname 3 ,
63returning \-1 if the host does not exist.
64Otherwise
65.Fa *ahost
66is set to the standard name of the host
67and a connection is established to a server
68residing at the well-known Internet port
69.Li shell/tcp
70(or whatever port is used by
71.Fa rshprog
72). The parameter
73.Fa inport
74is ignored; it is only included to provide an interface similar to
75.Xr rcmd 3 .
76.Pp
77If the connection succeeds,
78a socket in the
79.Tn UNIX
80domain of type
81.Dv SOCK_STREAM
82is returned to the caller, and given to the remote
83command as
84.Em stdin
85and
86.Em stdout ,
87and
88.Em stderr .
89.Sh DIAGNOSTICS
90The
91.Fn rcmdsh
92function
93returns a valid socket descriptor on success.
94It returns \-1 on error and prints a diagnostic message on the standard error.
95.Sh SEE ALSO
96.Xr rsh 1 ,
97.Xr socketpair 2 ,
98.Xr rcmd 3 ,
99.Xr rshd 8
100.Sh BUGS
101If
102.Xr rsh 1
103gets an error a file descriptor is still returned instead of \-1.
104.Sh HISTORY
105The
106.Fn rcmdsh
107function first appeared in
108.Ox 2.0 .
diff --git a/src/lib/libc/net/rcmdsh.c b/src/lib/libc/net/rcmdsh.c
new file mode 100644
index 0000000000..93523a4c56
--- /dev/null
+++ b/src/lib/libc/net/rcmdsh.c
@@ -0,0 +1,124 @@
1/* $OpenBSD: rcmdsh.c,v 1.5 1998/04/25 16:23:58 millert Exp $ */
2
3/*
4 * This is an rcmd() replacement originally by
5 * Chris Siebenmann <cks@utcc.utoronto.ca>.
6 */
7
8#if defined(LIBC_SCCS) && !defined(lint)
9static char *rcsid = "$OpenBSD: rcmdsh.c,v 1.5 1998/04/25 16:23:58 millert Exp $";
10#endif /* LIBC_SCCS and not lint */
11
12#include <sys/types.h>
13#include <sys/socket.h>
14#include <sys/wait.h>
15#include <signal.h>
16#include <errno.h>
17#include <netdb.h>
18#include <stdio.h>
19#include <string.h>
20#include <pwd.h>
21#include <paths.h>
22#include <unistd.h>
23
24/*
25 * This is a replacement rcmd() function that uses the rsh(1)
26 * program in place of a direct rcmd(3) function call so as to
27 * avoid having to be root. Note that rport is ignored.
28 */
29/* ARGSUSED */
30int
31rcmdsh(ahost, rport, locuser, remuser, cmd, rshprog)
32 char **ahost;
33 int rport;
34 const char *locuser, *remuser, *cmd;
35 char *rshprog;
36{
37 struct hostent *hp;
38 int cpid, sp[2];
39 char *p;
40 struct passwd *pw;
41
42 /* What rsh/shell to use. */
43 if (rshprog == NULL)
44 rshprog = _PATH_RSH;
45
46 /* locuser must exist on this host. */
47 if ((pw = getpwnam(locuser)) == NULL) {
48 (void) fprintf(stderr, "rcmdsh: unknown user: %s\n", locuser);
49 return(-1);
50 }
51
52 /* Validate remote hostname. */
53 if (strcmp(*ahost, "localhost") != 0) {
54 if ((hp = gethostbyname(*ahost)) == NULL) {
55 herror(*ahost);
56 return(-1);
57 }
58 *ahost = hp->h_name;
59 }
60
61 /* Get a socketpair we'll use for stdin and stdout. */
62 if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, sp) < 0) {
63 perror("rcmdsh: socketpair");
64 return(-1);
65 }
66
67 cpid = fork();
68 if (cpid < 0) {
69 perror("rcmdsh: fork failed");
70 return(-1);
71 } else if (cpid == 0) {
72 /*
73 * Child. We use sp[1] to be stdin/stdout, and close sp[0].
74 */
75 (void) close(sp[0]);
76 if (dup2(sp[1], 0) < 0 || dup2(0, 1) < 0) {
77 perror("rcmdsh: dup2 failed");
78 _exit(255);
79 }
80 /* Fork again to lose parent. */
81 cpid = fork();
82 if (cpid < 0) {
83 perror("rcmdsh: fork to lose parent failed");
84 _exit(255);
85 }
86 if (cpid > 0)
87 _exit(0);
88
89 /* In grandchild here. Become local user for rshprog. */
90 if (setuid(pw->pw_uid)) {
91 (void) fprintf(stderr, "rcmdsh: setuid(%u): %s\n",
92 pw->pw_uid, strerror(errno));
93 _exit(255);
94 }
95
96 /*
97 * If remote host is "localhost" and local and remote user
98 * are the same, avoid running remote shell for efficiency.
99 */
100 if (!strcmp(*ahost, "localhost") && !strcmp(locuser, remuser)) {
101 if (pw->pw_shell[0] == '\0')
102 rshprog = _PATH_BSHELL;
103 else
104 rshprog = pw->pw_shell;
105 p = strrchr(rshprog, '/');
106 execlp(rshprog, p ? p+1 : rshprog, "-c", cmd,
107 (char *) NULL);
108 } else {
109 p = strrchr(rshprog, '/');
110 execlp(rshprog, p ? p+1 : rshprog, *ahost, "-l",
111 remuser, cmd, (char *) NULL);
112 }
113 (void) fprintf(stderr, "rcmdsh: execlp %s failed: %s\n",
114 rshprog, strerror(errno));
115 _exit(255);
116 } else {
117 /* Parent. close sp[1], return sp[0]. */
118 (void) close(sp[1]);
119 /* Reap child. */
120 (void) wait(NULL);
121 return(sp[0]);
122 }
123 /* NOTREACHED */
124}
diff --git a/src/lib/libc/net/recv.c b/src/lib/libc/net/recv.c
new file mode 100644
index 0000000000..d209a07213
--- /dev/null
+++ b/src/lib/libc/net/recv.c
@@ -0,0 +1,50 @@
1/*
2 * Copyright (c) 1988, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: recv.c,v 1.2 1996/08/19 08:29:40 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/types.h>
39#include <sys/socket.h>
40
41#include <stddef.h>
42
43ssize_t
44recv(s, buf, len, flags)
45 int s, flags;
46 size_t len;
47 void *buf;
48{
49 return (recvfrom(s, buf, len, flags, NULL, 0));
50}
diff --git a/src/lib/libc/net/res_comp.c b/src/lib/libc/net/res_comp.c
new file mode 100644
index 0000000000..f7a0358967
--- /dev/null
+++ b/src/lib/libc/net/res_comp.c
@@ -0,0 +1,510 @@
1/* $OpenBSD: res_comp.c,v 1.8 1997/07/09 01:08:49 millert Exp $ */
2
3/*
4 * ++Copyright++ 1985, 1993
5 * -
6 * Copyright (c) 1985, 1993
7 * The Regents of the University of California. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by the University of
20 * California, Berkeley and its contributors.
21 * 4. Neither the name of the University nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 * -
37 * Portions Copyright (c) 1993 by Digital Equipment Corporation.
38 *
39 * Permission to use, copy, modify, and distribute this software for any
40 * purpose with or without fee is hereby granted, provided that the above
41 * copyright notice and this permission notice appear in all copies, and that
42 * the name of Digital Equipment Corporation not be used in advertising or
43 * publicity pertaining to distribution of the document or software without
44 * specific, written prior permission.
45 *
46 * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
47 * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
48 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
49 * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
50 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
51 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
52 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
53 * SOFTWARE.
54 * -
55 * --Copyright--
56 */
57
58#if defined(LIBC_SCCS) && !defined(lint)
59#if 0
60static char sccsid[] = "@(#)res_comp.c 8.1 (Berkeley) 6/4/93";
61static char rcsid[] = "$From: res_comp.c,v 8.11 1996/12/02 09:17:22 vixie Exp $";
62#else
63static char rcsid[] = "$OpenBSD: res_comp.c,v 1.8 1997/07/09 01:08:49 millert Exp $";
64#endif
65#endif /* LIBC_SCCS and not lint */
66
67#include <sys/types.h>
68#include <sys/param.h>
69#include <netinet/in.h>
70#include <arpa/nameser.h>
71
72#include <stdio.h>
73#include <resolv.h>
74#include <ctype.h>
75
76#include <unistd.h>
77#include <string.h>
78
79static int dn_find __P((u_char *exp_dn, u_char *msg,
80 u_char **dnptrs, u_char **lastdnptr));
81
82/*
83 * Expand compressed domain name 'comp_dn' to full domain name.
84 * 'msg' is a pointer to the begining of the message,
85 * 'eomorig' points to the first location after the message,
86 * 'exp_dn' is a pointer to a buffer of size 'length' for the result.
87 * Return size of compressed name or -1 if there was an error.
88 */
89int
90dn_expand(msg, eomorig, comp_dn, exp_dn, length)
91 const u_char *msg, *eomorig, *comp_dn;
92 char *exp_dn;
93 int length;
94{
95 register const u_char *cp;
96 register char *dn;
97 register int n, c;
98 char *eom;
99 int len = -1, checked = 0;
100
101 dn = exp_dn;
102 cp = comp_dn;
103 if (length > MAXHOSTNAMELEN-1)
104 length = MAXHOSTNAMELEN-1;
105 eom = exp_dn + length;
106 /*
107 * fetch next label in domain name
108 */
109 while ((n = *cp++)) {
110 /*
111 * Check for indirection
112 */
113 switch (n & INDIR_MASK) {
114 case 0:
115 if (dn != exp_dn) {
116 if (dn >= eom)
117 return (-1);
118 *dn++ = '.';
119 }
120 if (dn+n >= eom)
121 return (-1);
122 checked += n + 1;
123 while (--n >= 0) {
124 if (((c = *cp++) == '.') || (c == '\\')) {
125 if (dn + n + 2 >= eom)
126 return (-1);
127 *dn++ = '\\';
128 }
129 *dn++ = c;
130 if (cp >= eomorig) /* out of range */
131 return (-1);
132 }
133 break;
134
135 case INDIR_MASK:
136 if (len < 0)
137 len = cp - comp_dn + 1;
138 cp = msg + (((n & 0x3f) << 8) | (*cp & 0xff));
139 if (cp < msg || cp >= eomorig) /* out of range */
140 return (-1);
141 checked += 2;
142 /*
143 * Check for loops in the compressed name;
144 * if we've looked at the whole message,
145 * there must be a loop.
146 */
147 if (checked >= eomorig - msg)
148 return (-1);
149 break;
150
151 default:
152 return (-1); /* flag error */
153 }
154 }
155 *dn = '\0';
156 if (len < 0)
157 len = cp - comp_dn;
158 return (len);
159}
160
161/*
162 * Compress domain name 'exp_dn' into 'comp_dn'.
163 * Return the size of the compressed name or -1.
164 * 'length' is the size of the array pointed to by 'comp_dn'.
165 * 'dnptrs' is a list of pointers to previous compressed names. dnptrs[0]
166 * is a pointer to the beginning of the message. The list ends with NULL.
167 * 'lastdnptr' is a pointer to the end of the arrary pointed to
168 * by 'dnptrs'. Side effect is to update the list of pointers for
169 * labels inserted into the message as we compress the name.
170 * If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr'
171 * is NULL, we don't update the list.
172 */
173int
174dn_comp(exp_dn, comp_dn, length, dnptrs, lastdnptr)
175 const char *exp_dn;
176 u_char *comp_dn, **dnptrs, **lastdnptr;
177 int length;
178{
179 register u_char *cp, *dn;
180 register int c, l;
181 u_char **cpp, **lpp, *sp, *eob;
182 u_char *msg;
183
184 dn = (u_char *)exp_dn;
185 cp = comp_dn;
186 eob = cp + length;
187 lpp = cpp = NULL;
188 if (dnptrs != NULL) {
189 if ((msg = *dnptrs++) != NULL) {
190 for (cpp = dnptrs; *cpp != NULL; cpp++)
191 ;
192 lpp = cpp; /* end of list to search */
193 }
194 } else
195 msg = NULL;
196 for (c = *dn++; c != '\0'; ) {
197 /* look to see if we can use pointers */
198 if (msg != NULL) {
199 if ((l = dn_find(dn-1, msg, dnptrs, lpp)) >= 0) {
200 if (cp+1 >= eob)
201 return (-1);
202 *cp++ = (l >> 8) | INDIR_MASK;
203 *cp++ = l % 256;
204 return (cp - comp_dn);
205 }
206 /* not found, save it */
207 if (lastdnptr != NULL && cpp < lastdnptr-1) {
208 *cpp++ = cp;
209 *cpp = NULL;
210 }
211 }
212 sp = cp++; /* save ptr to length byte */
213 do {
214 if (c == '.') {
215 c = *dn++;
216 break;
217 }
218 if (c == '\\') {
219 if ((c = *dn++) == '\0')
220 break;
221 }
222 if (cp >= eob) {
223 if (msg != NULL)
224 *lpp = NULL;
225 return (-1);
226 }
227 *cp++ = c;
228 } while ((c = *dn++) != '\0');
229 /* catch trailing '.'s but not '..' */
230 if ((l = cp - sp - 1) == 0 && c == '\0') {
231 cp--;
232 break;
233 }
234 if (l <= 0 || l > MAXLABEL) {
235 if (msg != NULL)
236 *lpp = NULL;
237 return (-1);
238 }
239 *sp = l;
240 }
241 if (cp >= eob) {
242 if (msg != NULL)
243 *lpp = NULL;
244 return (-1);
245 }
246 *cp++ = '\0';
247 return (cp - comp_dn);
248}
249
250/*
251 * Skip over a compressed domain name. Return the size or -1.
252 */
253int
254__dn_skipname(comp_dn, eom)
255 const u_char *comp_dn, *eom;
256{
257 register const u_char *cp;
258 register int n;
259
260 cp = comp_dn;
261 while (cp < eom && (n = *cp++)) {
262 /*
263 * check for indirection
264 */
265 switch (n & INDIR_MASK) {
266 case 0: /* normal case, n == len */
267 cp += n;
268 continue;
269 case INDIR_MASK: /* indirection */
270 cp++;
271 break;
272 default: /* illegal type */
273 return (-1);
274 }
275 break;
276 }
277 if (cp > eom)
278 return (-1);
279 return (cp - comp_dn);
280}
281
282static int
283mklower(ch)
284 register int ch;
285{
286 if (isascii(ch) && isupper(ch))
287 return (tolower(ch));
288 return (ch);
289}
290
291/*
292 * Search for expanded name from a list of previously compressed names.
293 * Return the offset from msg if found or -1.
294 * dnptrs is the pointer to the first name on the list,
295 * not the pointer to the start of the message.
296 */
297static int
298dn_find(exp_dn, msg, dnptrs, lastdnptr)
299 u_char *exp_dn, *msg;
300 u_char **dnptrs, **lastdnptr;
301{
302 register u_char *dn, *cp, **cpp;
303 register int n;
304 u_char *sp;
305
306 for (cpp = dnptrs; cpp < lastdnptr; cpp++) {
307 dn = exp_dn;
308 sp = cp = *cpp;
309 while ((n = *cp++)) {
310 /*
311 * check for indirection
312 */
313 switch (n & INDIR_MASK) {
314 case 0: /* normal case, n == len */
315 while (--n >= 0) {
316 if (*dn == '.')
317 goto next;
318 if (*dn == '\\')
319 dn++;
320 if (mklower(*dn++) != mklower(*cp++))
321 goto next;
322 }
323 if ((n = *dn++) == '\0' && *cp == '\0')
324 return (sp - msg);
325 if (n == '.')
326 continue;
327 goto next;
328
329 case INDIR_MASK: /* indirection */
330 cp = msg + (((n & 0x3f) << 8) | *cp);
331 break;
332
333 default: /* illegal type */
334 return (-1);
335 }
336 }
337 if (*dn == '\0')
338 return (sp - msg);
339 next: ;
340 }
341 return (-1);
342}
343
344/*
345 * Verify that a domain name uses an acceptable character set.
346 */
347
348/*
349 * Note the conspicuous absence of ctype macros in these definitions. On
350 * non-ASCII hosts, we can't depend on string literals or ctype macros to
351 * tell us anything about network-format data. The rest of the BIND system
352 * is not careful about this, but for some reason, we're doing it right here.
353 */
354#define PERIOD 0x2e
355#define hyphenchar(c) ((c) == 0x2d)
356#define bslashchar(c) ((c) == 0x5c)
357#define periodchar(c) ((c) == PERIOD)
358#define asterchar(c) ((c) == 0x2a)
359#define alphachar(c) (((c) >= 0x41 && (c) <= 0x5a) \
360 || ((c) >= 0x61 && (c) <= 0x7a))
361#define digitchar(c) ((c) >= 0x30 && (c) <= 0x39)
362
363#define borderchar(c) (alphachar(c) || digitchar(c))
364#define middlechar(c) (borderchar(c) || hyphenchar(c))
365#define domainchar(c) ((c) > 0x20 && (c) < 0x7f)
366
367int
368res_hnok(dn)
369 const char *dn;
370{
371 int pch = PERIOD, ch = *dn++;
372
373 while (ch != '\0') {
374 int nch = *dn++;
375
376 if (periodchar(ch)) {
377 ;
378 } else if (periodchar(pch)) {
379 if (!borderchar(ch))
380 return (0);
381 } else if (periodchar(nch) || nch == '\0') {
382 if (!borderchar(ch))
383 return (0);
384 } else {
385 if (!middlechar(ch))
386 return (0);
387 }
388 pch = ch, ch = nch;
389 }
390 return (1);
391}
392
393/*
394 * hostname-like (A, MX, WKS) owners can have "*" as their first label
395 * but must otherwise be as a host name.
396 */
397int
398res_ownok(dn)
399 const char *dn;
400{
401 if (asterchar(dn[0])) {
402 if (periodchar(dn[1]))
403 return (res_hnok(dn+2));
404 if (dn[1] == '\0')
405 return (1);
406 }
407 return (res_hnok(dn));
408}
409
410/*
411 * SOA RNAMEs and RP RNAMEs can have any printable character in their first
412 * label, but the rest of the name has to look like a host name.
413 */
414int
415res_mailok(dn)
416 const char *dn;
417{
418 int ch, escaped = 0;
419
420 /* "." is a valid missing representation */
421 if (*dn == '\0')
422 return(1);
423
424 /* otherwise <label>.<hostname> */
425 while ((ch = *dn++) != '\0') {
426 if (!domainchar(ch))
427 return (0);
428 if (!escaped && periodchar(ch))
429 break;
430 if (escaped)
431 escaped = 0;
432 else if (bslashchar(ch))
433 escaped = 1;
434 }
435 if (periodchar(ch))
436 return (res_hnok(dn));
437 return(0);
438}
439
440/*
441 * This function is quite liberal, since RFC 1034's character sets are only
442 * recommendations.
443 */
444int
445res_dnok(dn)
446 const char *dn;
447{
448 int ch;
449
450 while ((ch = *dn++) != '\0')
451 if (!domainchar(ch))
452 return (0);
453 return (1);
454}
455
456/*
457 * Routines to insert/extract short/long's.
458 */
459
460u_int16_t
461_getshort(msgp)
462 register const u_char *msgp;
463{
464 register u_int16_t u;
465
466 GETSHORT(u, msgp);
467 return (u);
468}
469
470#ifdef NeXT
471/*
472 * nExt machines have some funky library conventions, which we must maintain.
473 */
474u_int16_t
475res_getshort(msgp)
476 register const u_char *msgp;
477{
478 return (_getshort(msgp));
479}
480#endif
481
482u_int32_t
483_getlong(msgp)
484 register const u_char *msgp;
485{
486 register u_int32_t u;
487
488 GETLONG(u, msgp);
489 return (u);
490}
491
492void
493#if defined(__STDC__) || defined(__cplusplus)
494__putshort(register u_int16_t s, register u_char *msgp) /* must match proto */
495#else
496__putshort(s, msgp)
497 register u_int16_t s;
498 register u_char *msgp;
499#endif
500{
501 PUTSHORT(s, msgp);
502}
503
504void
505__putlong(l, msgp)
506 register u_int32_t l;
507 register u_char *msgp;
508{
509 PUTLONG(l, msgp);
510}
diff --git a/src/lib/libc/net/res_data.c b/src/lib/libc/net/res_data.c
new file mode 100644
index 0000000000..b0d19c36bb
--- /dev/null
+++ b/src/lib/libc/net/res_data.c
@@ -0,0 +1,117 @@
1/* $OpenBSD: res_data.c,v 1.1 1997/03/13 19:07:36 downsj Exp $ */
2
3/*
4 * ++Copyright++ 1995
5 * -
6 * Copyright (c) 1995
7 * The Regents of the University of California. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by the University of
20 * California, Berkeley and its contributors.
21 * 4. Neither the name of the University nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 * -
37 * Portions Copyright (c) 1993 by Digital Equipment Corporation.
38 *
39 * Permission to use, copy, modify, and distribute this software for any
40 * purpose with or without fee is hereby granted, provided that the above
41 * copyright notice and this permission notice appear in all copies, and that
42 * the name of Digital Equipment Corporation not be used in advertising or
43 * publicity pertaining to distribution of the document or software without
44 * specific, written prior permission.
45 *
46 * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
47 * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
48 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
49 * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
50 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
51 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
52 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
53 * SOFTWARE.
54 * -
55 * --Copyright--
56 */
57
58#if defined(LIBC_SCCS) && !defined(lint)
59#if 0
60static char rcsid[] = "$From: res_data.c,v 8.2 1996/08/05 08:31:35 vixie Exp $";
61#else
62static char rcsid[] = "$OpenBSD: res_data.c,v 1.1 1997/03/13 19:07:36 downsj Exp $";
63#endif
64#endif /* LIBC_SCCS and not lint */
65
66#include <sys/types.h>
67#include <sys/param.h>
68#include <sys/socket.h>
69#include <sys/time.h>
70#include <netinet/in.h>
71#include <arpa/inet.h>
72#include <arpa/nameser.h>
73
74#include <stdio.h>
75#include <ctype.h>
76#include <resolv.h>
77#include <unistd.h>
78#include <stdlib.h>
79#include <string.h>
80
81const char *_res_opcodes[] = {
82 "QUERY",
83 "IQUERY",
84 "CQUERYM",
85 "CQUERYU", /* experimental */
86 "NOTIFY", /* experimental */
87 "5",
88 "6",
89 "7",
90 "8",
91 "UPDATEA",
92 "UPDATED",
93 "UPDATEDA",
94 "UPDATEM",
95 "UPDATEMA",
96 "ZONEINIT",
97 "ZONEREF",
98};
99
100const char *_res_resultcodes[] = {
101 "NOERROR",
102 "FORMERR",
103 "SERVFAIL",
104 "NXDOMAIN",
105 "NOTIMP",
106 "REFUSED",
107 "6",
108 "7",
109 "8",
110 "9",
111 "10",
112 "11",
113 "12",
114 "13",
115 "14",
116 "NOCHANGE",
117};
diff --git a/src/lib/libc/net/res_debug.c b/src/lib/libc/net/res_debug.c
new file mode 100644
index 0000000000..c2725395a0
--- /dev/null
+++ b/src/lib/libc/net/res_debug.c
@@ -0,0 +1,1518 @@
1/* $OpenBSD: res_debug.c,v 1.9 1998/03/19 00:30:06 millert Exp $ */
2
3/*
4 * ++Copyright++ 1985, 1990, 1993
5 * -
6 * Copyright (c) 1985, 1990, 1993
7 * The Regents of the University of California. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by the University of
20 * California, Berkeley and its contributors.
21 * 4. Neither the name of the University nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 * -
37 * Portions Copyright (c) 1993 by Digital Equipment Corporation.
38 *
39 * Permission to use, copy, modify, and distribute this software for any
40 * purpose with or without fee is hereby granted, provided that the above
41 * copyright notice and this permission notice appear in all copies, and that
42 * the name of Digital Equipment Corporation not be used in advertising or
43 * publicity pertaining to distribution of the document or software without
44 * specific, written prior permission.
45 *
46 * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
47 * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
48 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
49 * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
50 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
51 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
52 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
53 * SOFTWARE.
54 * -
55 * Portions Copyright (c) 1995 by International Business Machines, Inc.
56 *
57 * International Business Machines, Inc. (hereinafter called IBM) grants
58 * permission under its copyrights to use, copy, modify, and distribute this
59 * Software with or without fee, provided that the above copyright notice and
60 * all paragraphs of this notice appear in all copies, and that the name of IBM
61 * not be used in connection with the marketing of any product incorporating
62 * the Software or modifications thereof, without specific, written prior
63 * permission.
64 *
65 * To the extent it has a right to do so, IBM grants an immunity from suit
66 * under its patents, if any, for the use, sale or manufacture of products to
67 * the extent that such products are used for performing Domain Name System
68 * dynamic updates in TCP/IP networks by means of the Software. No immunity is
69 * granted for any product per se or for any other function of any product.
70 *
71 * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
72 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
73 * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
74 * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
75 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
76 * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
77 * --Copyright--
78 */
79
80#if defined(LIBC_SCCS) && !defined(lint)
81#if 0
82static char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93";
83static char rcsid[] = "$From: res_debug.c,v 8.19 1996/11/26 10:11:23 vixie Exp $";
84#else
85static char rcsid[] = "$OpenBSD: res_debug.c,v 1.9 1998/03/19 00:30:06 millert Exp $";
86#endif
87#endif /* LIBC_SCCS and not lint */
88
89#include <sys/param.h>
90#include <sys/types.h>
91#include <sys/socket.h>
92#include <netinet/in.h>
93#include <arpa/inet.h>
94#include <arpa/nameser.h>
95
96#include <ctype.h>
97#include <netdb.h>
98#include <resolv.h>
99#include <stdio.h>
100#include <time.h>
101
102#include <stdlib.h>
103#include <string.h>
104
105extern const char *_res_opcodes[];
106extern const char *_res_resultcodes[];
107
108/* XXX: we should use getservbyport() instead. */
109static const char *
110dewks(wks)
111 int wks;
112{
113 static char nbuf[20];
114
115 switch (wks) {
116 case 5: return "rje";
117 case 7: return "echo";
118 case 9: return "discard";
119 case 11: return "systat";
120 case 13: return "daytime";
121 case 15: return "netstat";
122 case 17: return "qotd";
123 case 19: return "chargen";
124 case 20: return "ftp-data";
125 case 21: return "ftp";
126 case 23: return "telnet";
127 case 25: return "smtp";
128 case 37: return "time";
129 case 39: return "rlp";
130 case 42: return "name";
131 case 43: return "whois";
132 case 53: return "domain";
133 case 57: return "apts";
134 case 59: return "apfs";
135 case 67: return "bootps";
136 case 68: return "bootpc";
137 case 69: return "tftp";
138 case 77: return "rje";
139 case 79: return "finger";
140 case 87: return "link";
141 case 95: return "supdup";
142 case 100: return "newacct";
143 case 101: return "hostnames";
144 case 102: return "iso-tsap";
145 case 103: return "x400";
146 case 104: return "x400-snd";
147 case 105: return "csnet-ns";
148 case 109: return "pop-2";
149 case 111: return "sunrpc";
150 case 113: return "auth";
151 case 115: return "sftp";
152 case 117: return "uucp-path";
153 case 119: return "nntp";
154 case 121: return "erpc";
155 case 123: return "ntp";
156 case 133: return "statsrv";
157 case 136: return "profile";
158 case 144: return "NeWS";
159 case 161: return "snmp";
160 case 162: return "snmp-trap";
161 case 170: return "print-srv";
162 default: (void) sprintf(nbuf, "%d", wks); return (nbuf);
163 }
164}
165
166/* XXX: we should use getprotobynumber() instead. */
167static const char *
168deproto(protonum)
169 int protonum;
170{
171 static char nbuf[20];
172
173 switch (protonum) {
174 case 1: return "icmp";
175 case 2: return "igmp";
176 case 3: return "ggp";
177 case 5: return "st";
178 case 6: return "tcp";
179 case 7: return "ucl";
180 case 8: return "egp";
181 case 9: return "igp";
182 case 11: return "nvp-II";
183 case 12: return "pup";
184 case 16: return "chaos";
185 case 17: return "udp";
186 default: (void) sprintf(nbuf, "%d", protonum); return (nbuf);
187 }
188}
189
190static const u_char *
191do_rrset(msg, len, cp, cnt, pflag, file, hs)
192 int cnt, pflag, len;
193 const u_char *cp, *msg;
194 const char *hs;
195 FILE *file;
196{
197 int n;
198 int sflag;
199
200 /*
201 * Print answer records.
202 */
203 sflag = (_res.pfcode & pflag);
204 if ((n = ntohs(cnt))) {
205 if ((!_res.pfcode) ||
206 ((sflag) && (_res.pfcode & RES_PRF_HEAD1)))
207 fprintf(file, hs);
208 while (--n >= 0) {
209 if ((!_res.pfcode) || sflag) {
210 cp = p_rr(cp, msg, file);
211 } else {
212 unsigned int dlen;
213 cp += __dn_skipname(cp, cp + MAXCDNAME);
214 cp += INT16SZ;
215 cp += INT16SZ;
216 cp += INT32SZ;
217 dlen = _getshort((u_char*)cp);
218 cp += INT16SZ;
219 cp += dlen;
220 }
221 if ((cp - msg) > len)
222 return (NULL);
223 }
224 if ((!_res.pfcode) ||
225 ((sflag) && (_res.pfcode & RES_PRF_HEAD1)))
226 putc('\n', file);
227 }
228 return (cp);
229}
230
231void
232__p_query(msg)
233 const u_char *msg;
234{
235 __fp_query(msg, stdout);
236}
237
238/*
239 * Print the current options.
240 * This is intended to be primarily a debugging routine.
241 */
242void
243__fp_resstat(statp, file)
244 struct __res_state *statp;
245 FILE *file;
246{
247 register u_long mask;
248
249 fprintf(file, ";; res options:");
250 if (!statp)
251 statp = &_res;
252 for (mask = 1; mask != 0; mask <<= 1)
253 if (statp->options & mask)
254 fprintf(file, " %s", p_option(mask));
255 putc('\n', file);
256}
257
258/*
259 * Print the contents of a query.
260 * This is intended to be primarily a debugging routine.
261 */
262void
263__fp_nquery(msg, len, file)
264 const u_char *msg;
265 int len;
266 FILE *file;
267{
268 register const u_char *cp, *endMark;
269 register const HEADER *hp;
270 register int n;
271
272 if ((_res.options & RES_INIT) == 0 && res_init() == -1)
273 return;
274
275#define TruncTest(x) if (x > endMark) goto trunc
276#define ErrorTest(x) if (x == NULL) goto error
277
278 /*
279 * Print header fields.
280 */
281 hp = (HEADER *)msg;
282 cp = msg + HFIXEDSZ;
283 endMark = msg + len;
284 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX) || hp->rcode) {
285 fprintf(file, ";; ->>HEADER<<- opcode: %s, status: %s, id: %d",
286 _res_opcodes[hp->opcode],
287 _res_resultcodes[hp->rcode],
288 ntohs(hp->id));
289 putc('\n', file);
290 }
291 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX))
292 putc(';', file);
293 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD2)) {
294 fprintf(file, "; flags:");
295 if (hp->qr)
296 fprintf(file, " qr");
297 if (hp->aa)
298 fprintf(file, " aa");
299 if (hp->tc)
300 fprintf(file, " tc");
301 if (hp->rd)
302 fprintf(file, " rd");
303 if (hp->ra)
304 fprintf(file, " ra");
305 if (hp->unused)
306 fprintf(file, " UNUSED-BIT-ON");
307 if (hp->ad)
308 fprintf(file, " ad");
309 if (hp->cd)
310 fprintf(file, " cd");
311 }
312 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD1)) {
313 fprintf(file, "; Ques: %d", ntohs(hp->qdcount));
314 fprintf(file, ", Ans: %d", ntohs(hp->ancount));
315 fprintf(file, ", Auth: %d", ntohs(hp->nscount));
316 fprintf(file, ", Addit: %d", ntohs(hp->arcount));
317 }
318 if ((!_res.pfcode) || (_res.pfcode &
319 (RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1))) {
320 putc('\n',file);
321 }
322 /*
323 * Print question records.
324 */
325 if ((n = ntohs(hp->qdcount))) {
326 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
327 fprintf(file, ";; QUESTIONS:\n");
328 while (--n >= 0) {
329 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
330 fprintf(file, ";;\t");
331 TruncTest(cp);
332 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
333 cp = p_cdnname(cp, msg, len, file);
334 else {
335 int n;
336 char name[MAXDNAME];
337
338 if ((n = dn_expand(msg, msg+len, cp, name,
339 sizeof name)) < 0)
340 cp = NULL;
341 else
342 cp += n;
343 }
344 ErrorTest(cp);
345 TruncTest(cp);
346 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
347 fprintf(file, ", type = %s",
348 __p_type(_getshort((u_char*)cp)));
349 cp += INT16SZ;
350 TruncTest(cp);
351 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
352 fprintf(file, ", class = %s\n",
353 __p_class(_getshort((u_char*)cp)));
354 cp += INT16SZ;
355 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
356 putc('\n', file);
357 }
358 }
359 /*
360 * Print authoritative answer records
361 */
362 TruncTest(cp);
363 cp = do_rrset(msg, len, cp, hp->ancount, RES_PRF_ANS, file,
364 ";; ANSWERS:\n");
365 ErrorTest(cp);
366
367 /*
368 * print name server records
369 */
370 TruncTest(cp);
371 cp = do_rrset(msg, len, cp, hp->nscount, RES_PRF_AUTH, file,
372 ";; AUTHORITY RECORDS:\n");
373 ErrorTest(cp);
374
375 TruncTest(cp);
376 /*
377 * print additional records
378 */
379 cp = do_rrset(msg, len, cp, hp->arcount, RES_PRF_ADD, file,
380 ";; ADDITIONAL RECORDS:\n");
381 ErrorTest(cp);
382 return;
383 trunc:
384 fprintf(file, "\n;; ...truncated\n");
385 return;
386 error:
387 fprintf(file, "\n;; ...malformed\n");
388}
389
390void
391__fp_query(msg, file)
392 const u_char *msg;
393 FILE *file;
394{
395 fp_nquery(msg, PACKETSZ, file);
396}
397
398const u_char *
399__p_cdnname(cp, msg, len, file)
400 const u_char *cp, *msg;
401 int len;
402 FILE *file;
403{
404 char name[MAXDNAME];
405 int n;
406
407 if ((n = dn_expand(msg, msg + len, cp, name, sizeof name)) < 0)
408 return (NULL);
409 if (name[0] == '\0')
410 putc('.', file);
411 else
412 fputs(name, file);
413 return (cp + n);
414}
415
416const u_char *
417__p_cdname(cp, msg, file)
418 const u_char *cp, *msg;
419 FILE *file;
420{
421 return (p_cdnname(cp, msg, PACKETSZ, file));
422}
423
424
425/* Return a fully-qualified domain name from a compressed name (with
426 length supplied). */
427
428const u_char *
429__p_fqnname(cp, msg, msglen, name, namelen)
430 const u_char *cp, *msg;
431 int msglen;
432 char *name;
433 int namelen;
434{
435 int n, newlen;
436
437 if ((n = dn_expand(msg, cp + msglen, cp, name, namelen)) < 0)
438 return (NULL);
439 newlen = strlen (name);
440 if (newlen == 0 || name[newlen - 1] != '.') {
441 if (newlen+1 >= namelen) /* Lack space for final dot */
442 return (NULL);
443 else
444 strcpy(name + newlen, ".");
445 }
446 return (cp + n);
447}
448
449/* XXX: the rest of these functions need to become length-limited, too. (vix)
450 */
451
452const u_char *
453__p_fqname(cp, msg, file)
454 const u_char *cp, *msg;
455 FILE *file;
456{
457 char name[MAXDNAME];
458 const u_char *n;
459
460 n = __p_fqnname(cp, msg, MAXCDNAME, name, sizeof name);
461 if (n == NULL)
462 return (NULL);
463 fputs(name, file);
464 return (n);
465}
466
467/*
468 * Print resource record fields in human readable form.
469 */
470const u_char *
471__p_rr(cp, msg, file)
472 const u_char *cp, *msg;
473 FILE *file;
474{
475 int type, class, dlen, n, c;
476 struct in_addr inaddr;
477 const u_char *cp1, *cp2;
478 u_int32_t tmpttl, t;
479 int lcnt;
480 u_int16_t keyflags;
481 char rrname[MAXDNAME]; /* The fqdn of this RR */
482 char base64_key[MAX_KEY_BASE64];
483
484 if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
485 h_errno = NETDB_INTERNAL;
486 return (NULL);
487 }
488 cp = __p_fqnname(cp, msg, MAXCDNAME, rrname, sizeof rrname);
489 if (!cp)
490 return (NULL); /* compression error */
491 fputs(rrname, file);
492
493 type = _getshort((u_char*)cp);
494 cp += INT16SZ;
495 class = _getshort((u_char*)cp);
496 cp += INT16SZ;
497 tmpttl = _getlong((u_char*)cp);
498 cp += INT32SZ;
499 dlen = _getshort((u_char*)cp);
500 cp += INT16SZ;
501 cp1 = cp;
502 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_TTLID))
503 fprintf(file, "\t%lu", (u_long)tmpttl);
504 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_CLASS))
505 fprintf(file, "\t%s", __p_class(class));
506 fprintf(file, "\t%s", __p_type(type));
507 /*
508 * Print type specific data, if appropriate
509 */
510 switch (type) {
511 case T_A:
512 switch (class) {
513 case C_IN:
514 case C_HS:
515 bcopy(cp, (char *)&inaddr, INADDRSZ);
516 if (dlen == 4) {
517 fprintf(file, "\t%s", inet_ntoa(inaddr));
518 cp += dlen;
519 } else if (dlen == 7) {
520 char *address;
521 u_char protocol;
522 in_port_t port;
523
524 address = inet_ntoa(inaddr);
525 cp += INADDRSZ;
526 protocol = *(u_char*)cp;
527 cp += sizeof (u_char);
528 port = _getshort((u_char*)cp);
529 cp += INT16SZ;
530 fprintf(file, "\t%s\t; proto %d, port %d",
531 address, protocol, port);
532 }
533 break;
534 default:
535 cp += dlen;
536 }
537 break;
538 case T_CNAME:
539 case T_MB:
540 case T_MG:
541 case T_MR:
542 case T_NS:
543 case T_PTR:
544 putc('\t', file);
545 if ((cp = p_fqname(cp, msg, file)) == NULL)
546 return (NULL);
547 break;
548
549 case T_HINFO:
550 case T_ISDN:
551 cp2 = cp + dlen;
552 (void) fputs("\t\"", file);
553 if ((n = (unsigned char) *cp++) != 0) {
554 for (c = n; c > 0 && cp < cp2; c--) {
555 if (strchr("\n\"\\", *cp))
556 (void) putc('\\', file);
557 (void) putc(*cp++, file);
558 }
559 }
560 putc('"', file);
561 if (cp < cp2 && (n = (unsigned char) *cp++) != 0) {
562 (void) fputs ("\t\"", file);
563 for (c = n; c > 0 && cp < cp2; c--) {
564 if (strchr("\n\"\\", *cp))
565 (void) putc('\\', file);
566 (void) putc(*cp++, file);
567 }
568 putc('"', file);
569 } else if (type == T_HINFO) {
570 (void) fputs("\"?\"", file);
571 fprintf(file, "\n;; *** Warning *** OS-type missing");
572 }
573 break;
574
575 case T_SOA:
576 putc('\t', file);
577 if ((cp = p_fqname(cp, msg, file)) == NULL)
578 return (NULL);
579 putc(' ', file);
580 if ((cp = p_fqname(cp, msg, file)) == NULL)
581 return (NULL);
582 fputs(" (\n", file);
583 t = _getlong((u_char*)cp); cp += INT32SZ;
584 fprintf(file, "\t\t\t%lu\t; serial\n", (u_long)t);
585 t = _getlong((u_char*)cp); cp += INT32SZ;
586 fprintf(file, "\t\t\t%lu\t; refresh (%s)\n",
587 (u_long)t, __p_time(t));
588 t = _getlong((u_char*)cp); cp += INT32SZ;
589 fprintf(file, "\t\t\t%lu\t; retry (%s)\n",
590 (u_long)t, __p_time(t));
591 t = _getlong((u_char*)cp); cp += INT32SZ;
592 fprintf(file, "\t\t\t%lu\t; expire (%s)\n",
593 (u_long)t, __p_time(t));
594 t = _getlong((u_char*)cp); cp += INT32SZ;
595 fprintf(file, "\t\t\t%lu )\t; minimum (%s)",
596 (u_long)t, __p_time(t));
597 break;
598
599 case T_MX:
600 case T_AFSDB:
601 case T_RT:
602 fprintf(file, "\t%d ", _getshort((u_char*)cp));
603 cp += INT16SZ;
604 if ((cp = p_fqname(cp, msg, file)) == NULL)
605 return (NULL);
606 break;
607
608 case T_PX:
609 fprintf(file, "\t%d ", _getshort((u_char*)cp));
610 cp += INT16SZ;
611 if ((cp = p_fqname(cp, msg, file)) == NULL)
612 return (NULL);
613 putc(' ', file);
614 if ((cp = p_fqname(cp, msg, file)) == NULL)
615 return (NULL);
616 break;
617
618 case T_X25:
619 cp2 = cp + dlen;
620 (void) fputs("\t\"", file);
621 if ((n = (unsigned char) *cp++) != 0) {
622 for (c = n; c > 0 && cp < cp2; c--) {
623 if (strchr("\n\"\\", *cp))
624 (void) putc('\\', file);
625 (void) putc(*cp++, file);
626 }
627 }
628 putc('"', file);
629 break;
630
631 case T_TXT:
632 (void) putc('\t', file);
633 cp2 = cp1 + dlen;
634 while (cp < cp2) {
635 putc('"', file);
636 if ((n = (unsigned char) *cp++)) {
637 for (c = n; c > 0 && cp < cp2; c--) {
638 if (strchr("\n\"\\", *cp))
639 (void) putc('\\', file);
640 (void) putc(*cp++, file);
641 }
642 }
643 putc('"', file);
644 if (cp < cp2)
645 putc(' ', file);
646 }
647 break;
648
649 case T_NSAP:
650 (void) fprintf(file, "\t%s", inet_nsap_ntoa(dlen, cp, NULL));
651 cp += dlen;
652 break;
653
654 case T_AAAA: {
655 char t[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
656
657 fprintf(file, "\t%s", inet_ntop(AF_INET6, cp, t, sizeof t));
658 cp += dlen;
659 break;
660 }
661
662 case T_LOC: {
663 char t[255];
664
665 fprintf(file, "\t%s", loc_ntoa(cp, t));
666 cp += dlen;
667 break;
668 }
669
670 case T_NAPTR: {
671 u_int order, preference;
672
673 order = _getshort(cp); cp += INT16SZ;
674 preference = _getshort(cp); cp += INT16SZ;
675 fprintf(file, "\t%u %u ",order, preference);
676 /* Flags */
677 n = *cp++;
678 fprintf(file,"\"%.*s\" ", (int)n, cp);
679 cp += n;
680 /* Service */
681 n = *cp++;
682 fprintf(file,"\"%.*s\" ", (int)n, cp);
683 cp += n;
684 /* Regexp */
685 n = *cp++;
686 fprintf(file,"\"%.*s\" ", (int)n, cp);
687 cp += n;
688 if ((cp = p_fqname(cp, msg, file)) == NULL)
689 return (NULL);
690 break;
691 }
692
693 case T_SRV: {
694 u_int priority, weight, port;
695
696 priority = _getshort(cp); cp += INT16SZ;
697 weight = _getshort(cp); cp += INT16SZ;
698 port = _getshort(cp); cp += INT16SZ;
699 fprintf(file, "\t%u %u %u ", priority, weight, port);
700 if ((cp = p_fqname(cp, msg, file)) == NULL)
701 return (NULL);
702 break;
703 }
704
705 case T_MINFO:
706 case T_RP:
707 putc('\t', file);
708 if ((cp = p_fqname(cp, msg, file)) == NULL)
709 return (NULL);
710 putc(' ', file);
711 if ((cp = p_fqname(cp, msg, file)) == NULL)
712 return (NULL);
713 break;
714
715 case T_UINFO:
716 putc('\t', file);
717 fputs((char *)cp, file);
718 cp += dlen;
719 break;
720
721 case T_UID:
722 case T_GID:
723 if (dlen == 4) {
724 fprintf(file, "\t%u", _getlong((u_char*)cp));
725 cp += INT32SZ;
726 }
727 break;
728
729 case T_WKS:
730 if (dlen < INT32SZ + 1)
731 break;
732 bcopy(cp, (char *)&inaddr, INADDRSZ);
733 cp += INT32SZ;
734 fprintf(file, "\t%s %s ( ",
735 inet_ntoa(inaddr),
736 deproto((int) *cp));
737 cp += sizeof (u_char);
738 n = 0;
739 lcnt = 0;
740 while (cp < cp1 + dlen) {
741 c = *cp++;
742 do {
743 if (c & 0200) {
744 if (lcnt == 0) {
745 fputs("\n\t\t\t", file);
746 lcnt = 5;
747 }
748 fputs(dewks(n), file);
749 putc(' ', file);
750 lcnt--;
751 }
752 c <<= 1;
753 } while (++n & 07);
754 }
755 putc(')', file);
756 break;
757
758 case T_KEY:
759 putc('\t', file);
760 keyflags = _getshort(cp);
761 cp += 2;
762 fprintf(file,"0x%04x", keyflags ); /* flags */
763 fprintf(file," %u", *cp++); /* protocol */
764 fprintf(file," %u (", *cp++); /* algorithm */
765
766 n = b64_ntop(cp, (cp1 + dlen) - cp,
767 base64_key, sizeof base64_key);
768 for (c = 0; c < n; ++c) {
769 if (0 == (c & 0x3F))
770 fprintf(file, "\n\t");
771 putc(base64_key[c], file); /* public key data */
772 }
773
774 fprintf(file, " )");
775 if (n < 0)
776 fprintf(file, "\t; BAD BASE64");
777 fflush(file);
778 cp = cp1 + dlen;
779 break;
780
781 case T_SIG:
782 type = _getshort((u_char*)cp);
783 cp += INT16SZ;
784 fprintf(file, " %s", p_type(type));
785 fprintf(file, "\t%d", *cp++); /* algorithm */
786 /* Check label value and print error if wrong. */
787 n = *cp++;
788 c = dn_count_labels (rrname);
789 if (n != c)
790 fprintf(file, "\t; LABELS WRONG (%d should be %d)\n\t",
791 n, c);
792 /* orig ttl */
793 n = _getlong((u_char*)cp);
794 if (n != tmpttl)
795 fprintf(file, " %u", n);
796 cp += INT32SZ;
797 /* sig expire */
798 fprintf(file, " (\n\t%s",
799 __p_secstodate(_getlong((u_char*)cp)));
800 cp += INT32SZ;
801 /* time signed */
802 fprintf(file, " %s", __p_secstodate(_getlong((u_char*)cp)));
803 cp += INT32SZ;
804 /* sig footprint */
805 fprintf(file," %u ", _getshort((u_char*)cp));
806 cp += INT16SZ;
807 /* signer's name */
808 cp = p_fqname(cp, msg, file);
809 n = b64_ntop(cp, (cp1 + dlen) - cp,
810 base64_key, sizeof base64_key);
811 for (c = 0; c < n; c++) {
812 if (0 == (c & 0x3F))
813 fprintf (file, "\n\t");
814 putc(base64_key[c], file); /* signature */
815 }
816 /* Clean up... */
817 fprintf(file, " )");
818 if (n < 0)
819 fprintf(file, "\t; BAD BASE64");
820 fflush(file);
821 cp = cp1+dlen;
822 break;
823
824#ifdef ALLOW_T_UNSPEC
825 case T_UNSPEC:
826 {
827 int NumBytes = 8;
828 u_char *DataPtr;
829 int i;
830
831 if (dlen < NumBytes) NumBytes = dlen;
832 fprintf(file, "\tFirst %d bytes of hex data:",
833 NumBytes);
834 for (i = 0, DataPtr = cp; i < NumBytes; i++, DataPtr++)
835 fprintf(file, " %x", *DataPtr);
836 cp += dlen;
837 }
838 break;
839#endif /* ALLOW_T_UNSPEC */
840
841 default:
842 fprintf(file, "\t?%d?", type);
843 cp += dlen;
844 }
845#if 0
846 fprintf(file, "\t; dlen=%d, ttl %s\n", dlen, __p_time(tmpttl));
847#else
848 putc('\n', file);
849#endif
850 if (cp - cp1 != dlen) {
851 fprintf(file, ";; packet size error (found %ld, dlen was %d)\n",
852 (long)(cp - cp1), dlen);
853 cp = NULL;
854 }
855 return (cp);
856}
857
858/*
859 * Names of RR classes and qclasses. Classes and qclasses are the same, except
860 * that C_ANY is a qclass but not a class. (You can ask for records of class
861 * C_ANY, but you can't have any records of that class in the database.)
862 */
863const struct res_sym __p_class_syms[] = {
864 {C_IN, "IN"},
865 {C_CHAOS, "CHAOS"},
866 {C_HS, "HS"},
867 {C_HS, "HESIOD"},
868 {C_ANY, "ANY"},
869 {C_IN, (char *)0}
870};
871
872/*
873 * Names of RR types and qtypes. Types and qtypes are the same, except
874 * that T_ANY is a qtype but not a type. (You can ask for records of type
875 * T_ANY, but you can't have any records of that type in the database.)
876 */
877const struct res_sym __p_type_syms[] = {
878 {T_A, "A", "address"},
879 {T_NS, "NS", "name server"},
880 {T_MD, "MD", "mail destination (deprecated)"},
881 {T_MF, "MF", "mail forwarder (deprecated)"},
882 {T_CNAME, "CNAME", "canonical name"},
883 {T_SOA, "SOA", "start of authority"},
884 {T_MB, "MB", "mailbox"},
885 {T_MG, "MG", "mail group member"},
886 {T_MR, "MR", "mail rename"},
887 {T_NULL, "NULL", "null"},
888 {T_WKS, "WKS", "well-known service (deprecated)"},
889 {T_PTR, "PTR", "domain name pointer"},
890 {T_HINFO, "HINFO", "host information"},
891 {T_MINFO, "MINFO", "mailbox information"},
892 {T_MX, "MX", "mail exchanger"},
893 {T_TXT, "TXT", "text"},
894 {T_RP, "RP", "responsible person"},
895 {T_AFSDB, "AFSDB", "DCE or AFS server"},
896 {T_X25, "X25", "X25 address"},
897 {T_ISDN, "ISDN", "ISDN address"},
898 {T_RT, "RT", "router"},
899 {T_NSAP, "NSAP", "nsap address"},
900 {T_NSAP_PTR, "NSAP_PTR", "domain name pointer"},
901 {T_SIG, "SIG", "signature"},
902 {T_KEY, "KEY", "key"},
903 {T_PX, "PX", "mapping information"},
904 {T_GPOS, "GPOS", "geographical position (withdrawn)"},
905 {T_AAAA, "AAAA", "IPv6 address"},
906 {T_LOC, "LOC", "location"},
907 {T_NXT, "NXT", "next valid name (unimplemented)"},
908 {T_EID, "EID", "endpoint identifier (unimplemented)"},
909 {T_NIMLOC, "NIMLOC", "NIMROD locator (unimplemented)"},
910 {T_SRV, "SRV", "server selection"},
911 {T_ATMA, "ATMA", "ATM address (unimplemented)"},
912 {T_IXFR, "IXFR", "incremental zone transfer"},
913 {T_AXFR, "AXFR", "zone transfer"},
914 {T_MAILB, "MAILB", "mailbox-related data (deprecated)"},
915 {T_MAILA, "MAILA", "mail agent (deprecated)"},
916 {T_UINFO, "UINFO", "user information (nonstandard)"},
917 {T_UID, "UID", "user ID (nonstandard)"},
918 {T_GID, "GID", "group ID (nonstandard)"},
919 {T_NAPTR, "NAPTR", "URN Naming Authority"},
920#ifdef ALLOW_T_UNSPEC
921 {T_UNSPEC, "UNSPEC", "unspecified data (nonstandard)"},
922#endif /* ALLOW_T_UNSPEC */
923 {T_ANY, "ANY", "\"any\""},
924 {0, NULL, NULL}
925};
926
927int
928__sym_ston(syms, name, success)
929 const struct res_sym *syms;
930 char *name;
931 int *success;
932{
933 for (; syms->name != 0; syms++) {
934 if (strcasecmp (name, syms->name) == 0) {
935 if (success)
936 *success = 1;
937 return (syms->number);
938 }
939 }
940 if (success)
941 *success = 0;
942 return (syms->number); /* The default value. */
943}
944
945const char *
946__sym_ntos(syms, number, success)
947 const struct res_sym *syms;
948 int number;
949 int *success;
950{
951 static char unname[20];
952
953 for (; syms->name != 0; syms++) {
954 if (number == syms->number) {
955 if (success)
956 *success = 1;
957 return (syms->name);
958 }
959 }
960
961 sprintf (unname, "%d", number);
962 if (success)
963 *success = 0;
964 return (unname);
965}
966
967
968const char *
969__sym_ntop(syms, number, success)
970 const struct res_sym *syms;
971 int number;
972 int *success;
973{
974 static char unname[20];
975
976 for (; syms->name != 0; syms++) {
977 if (number == syms->number) {
978 if (success)
979 *success = 1;
980 return (syms->humanname);
981 }
982 }
983 sprintf(unname, "%d", number);
984 if (success)
985 *success = 0;
986 return (unname);
987}
988
989/*
990 * Return a string for the type
991 */
992const char *
993__p_type(type)
994 int type;
995{
996 return (__sym_ntos (__p_type_syms, type, (int *)0));
997}
998
999/*
1000 * Return a mnemonic for class
1001 */
1002const char *
1003__p_class(class)
1004 int class;
1005{
1006 return (__sym_ntos (__p_class_syms, class, (int *)0));
1007}
1008
1009/*
1010 * Return a mnemonic for an option
1011 */
1012const char *
1013__p_option(option)
1014 u_long option;
1015{
1016 static char nbuf[40];
1017
1018 switch (option) {
1019 case RES_INIT: return "init";
1020 case RES_DEBUG: return "debug";
1021 case RES_AAONLY: return "aaonly(unimpl)";
1022 case RES_USEVC: return "usevc";
1023 case RES_PRIMARY: return "primry(unimpl)";
1024 case RES_IGNTC: return "igntc";
1025 case RES_RECURSE: return "recurs";
1026 case RES_DEFNAMES: return "defnam";
1027 case RES_STAYOPEN: return "styopn";
1028 case RES_DNSRCH: return "dnsrch";
1029 case RES_INSECURE1: return "insecure1";
1030 case RES_INSECURE2: return "insecure2";
1031 default: sprintf(nbuf, "?0x%lx?", (u_long)option);
1032 return (nbuf);
1033 }
1034}
1035
1036/*
1037 * Return a mnemonic for a time to live
1038 */
1039const char *
1040p_time(value)
1041 u_int32_t value;
1042{
1043 static char nbuf[40];
1044 int secs, mins, hours, days;
1045 register char *p;
1046
1047 if (value == 0) {
1048 strcpy(nbuf, "0 secs");
1049 return (nbuf);
1050 }
1051
1052 secs = value % 60;
1053 value /= 60;
1054 mins = value % 60;
1055 value /= 60;
1056 hours = value % 24;
1057 value /= 24;
1058 days = value;
1059 value = 0;
1060
1061#define PLURALIZE(x) x, (x == 1) ? "" : "s"
1062 p = nbuf;
1063 if (days) {
1064 (void)sprintf(p, "%d day%s", PLURALIZE(days));
1065 while (*++p);
1066 }
1067 if (hours) {
1068 if (days)
1069 *p++ = ' ';
1070 (void)sprintf(p, "%d hour%s", PLURALIZE(hours));
1071 while (*++p);
1072 }
1073 if (mins) {
1074 if (days || hours)
1075 *p++ = ' ';
1076 (void)sprintf(p, "%d min%s", PLURALIZE(mins));
1077 while (*++p);
1078 }
1079 if (secs || ! (days || hours || mins)) {
1080 if (days || hours || mins)
1081 *p++ = ' ';
1082 (void)sprintf(p, "%d sec%s", PLURALIZE(secs));
1083 }
1084 return (nbuf);
1085}
1086
1087/*
1088 * routines to convert between on-the-wire RR format and zone file format.
1089 * Does not contain conversion to/from decimal degrees; divide or multiply
1090 * by 60*60*1000 for that.
1091 */
1092
1093static unsigned int poweroften[10] = {1, 10, 100, 1000, 10000, 100000,
1094 1000000,10000000,100000000,1000000000};
1095
1096/* takes an XeY precision/size value, returns a string representation. */
1097static const char *
1098precsize_ntoa(prec)
1099 u_int8_t prec;
1100{
1101 static char retbuf[sizeof "90000000.00"];
1102 unsigned long val;
1103 int mantissa, exponent;
1104
1105 mantissa = (int)((prec >> 4) & 0x0f) % 10;
1106 exponent = (int)((prec >> 0) & 0x0f) % 10;
1107
1108 val = mantissa * poweroften[exponent];
1109
1110 (void) sprintf(retbuf, "%ld.%.2ld", val/100, val%100);
1111 return (retbuf);
1112}
1113
1114/* converts ascii size/precision X * 10**Y(cm) to 0xXY. moves pointer. */
1115static u_int8_t
1116precsize_aton(strptr)
1117 char **strptr;
1118{
1119 unsigned int mval = 0, cmval = 0;
1120 u_int8_t retval = 0;
1121 register char *cp;
1122 register int exponent;
1123 register int mantissa;
1124
1125 cp = *strptr;
1126
1127 while (isdigit(*cp))
1128 mval = mval * 10 + (*cp++ - '0');
1129
1130 if (*cp == '.') { /* centimeters */
1131 cp++;
1132 if (isdigit(*cp)) {
1133 cmval = (*cp++ - '0') * 10;
1134 if (isdigit(*cp)) {
1135 cmval += (*cp++ - '0');
1136 }
1137 }
1138 }
1139 cmval = (mval * 100) + cmval;
1140
1141 for (exponent = 0; exponent < 9; exponent++)
1142 if (cmval < poweroften[exponent+1])
1143 break;
1144
1145 mantissa = cmval / poweroften[exponent];
1146 if (mantissa > 9)
1147 mantissa = 9;
1148
1149 retval = (mantissa << 4) | exponent;
1150
1151 *strptr = cp;
1152
1153 return (retval);
1154}
1155
1156/* converts ascii lat/lon to unsigned encoded 32-bit number. moves pointer. */
1157static u_int32_t
1158latlon2ul(latlonstrptr,which)
1159 char **latlonstrptr;
1160 int *which;
1161{
1162 register char *cp;
1163 u_int32_t retval;
1164 int deg = 0, min = 0, secs = 0, secsfrac = 0;
1165
1166 cp = *latlonstrptr;
1167
1168 while (isdigit(*cp))
1169 deg = deg * 10 + (*cp++ - '0');
1170
1171 while (isspace(*cp))
1172 cp++;
1173
1174 if (!(isdigit(*cp)))
1175 goto fndhemi;
1176
1177 while (isdigit(*cp))
1178 min = min * 10 + (*cp++ - '0');
1179
1180 while (isspace(*cp))
1181 cp++;
1182
1183 if (!(isdigit(*cp)))
1184 goto fndhemi;
1185
1186 while (isdigit(*cp))
1187 secs = secs * 10 + (*cp++ - '0');
1188
1189 if (*cp == '.') { /* decimal seconds */
1190 cp++;
1191 if (isdigit(*cp)) {
1192 secsfrac = (*cp++ - '0') * 100;
1193 if (isdigit(*cp)) {
1194 secsfrac += (*cp++ - '0') * 10;
1195 if (isdigit(*cp)) {
1196 secsfrac += (*cp++ - '0');
1197 }
1198 }
1199 }
1200 }
1201
1202 while (!isspace(*cp)) /* if any trailing garbage */
1203 cp++;
1204
1205 while (isspace(*cp))
1206 cp++;
1207
1208 fndhemi:
1209 switch (*cp) {
1210 case 'N': case 'n':
1211 case 'E': case 'e':
1212 retval = ((unsigned)1<<31)
1213 + (((((deg * 60) + min) * 60) + secs) * 1000)
1214 + secsfrac;
1215 break;
1216 case 'S': case 's':
1217 case 'W': case 'w':
1218 retval = ((unsigned)1<<31)
1219 - (((((deg * 60) + min) * 60) + secs) * 1000)
1220 - secsfrac;
1221 break;
1222 default:
1223 retval = 0; /* invalid value -- indicates error */
1224 break;
1225 }
1226
1227 switch (*cp) {
1228 case 'N': case 'n':
1229 case 'S': case 's':
1230 *which = 1; /* latitude */
1231 break;
1232 case 'E': case 'e':
1233 case 'W': case 'w':
1234 *which = 2; /* longitude */
1235 break;
1236 default:
1237 *which = 0; /* error */
1238 break;
1239 }
1240
1241 cp++; /* skip the hemisphere */
1242
1243 while (!isspace(*cp)) /* if any trailing garbage */
1244 cp++;
1245
1246 while (isspace(*cp)) /* move to next field */
1247 cp++;
1248
1249 *latlonstrptr = cp;
1250
1251 return (retval);
1252}
1253
1254/* converts a zone file representation in a string to an RDATA on-the-wire
1255 * representation. */
1256int
1257loc_aton(ascii, binary)
1258 const char *ascii;
1259 u_char *binary;
1260{
1261 const char *maxcp;
1262 u_char *bcp;
1263 char *cp;
1264
1265 u_int32_t latit = 0, longit = 0, alt = 0;
1266 u_int32_t lltemp1 = 0, lltemp2 = 0;
1267 int altmeters = 0, altfrac = 0, altsign = 1;
1268 u_int8_t hp = 0x16; /* default = 1e6 cm = 10000.00m = 10km */
1269 u_int8_t vp = 0x13; /* default = 1e3 cm = 10.00m */
1270 u_int8_t siz = 0x12; /* default = 1e2 cm = 1.00m */
1271 int which1 = 0, which2 = 0;
1272
1273 cp = (char *)ascii;
1274 maxcp = cp + strlen(ascii);
1275
1276 lltemp1 = latlon2ul(&cp, &which1);
1277
1278 lltemp2 = latlon2ul(&cp, &which2);
1279
1280 switch (which1 + which2) {
1281 case 3: /* 1 + 2, the only valid combination */
1282 if ((which1 == 1) && (which2 == 2)) { /* normal case */
1283 latit = lltemp1;
1284 longit = lltemp2;
1285 } else if ((which1 == 2) && (which2 == 1)) { /* reversed */
1286 longit = lltemp1;
1287 latit = lltemp2;
1288 } else { /* some kind of brokenness */
1289 return (0);
1290 }
1291 break;
1292 default: /* we didn't get one of each */
1293 return (0);
1294 }
1295
1296 /* altitude */
1297 if (*cp == '-') {
1298 altsign = -1;
1299 cp++;
1300 }
1301
1302 if (*cp == '+')
1303 cp++;
1304
1305 while (isdigit(*cp))
1306 altmeters = altmeters * 10 + (*cp++ - '0');
1307
1308 if (*cp == '.') { /* decimal meters */
1309 cp++;
1310 if (isdigit(*cp)) {
1311 altfrac = (*cp++ - '0') * 10;
1312 if (isdigit(*cp)) {
1313 altfrac += (*cp++ - '0');
1314 }
1315 }
1316 }
1317
1318 alt = (10000000 + (altsign * (altmeters * 100 + altfrac)));
1319
1320 while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */
1321 cp++;
1322
1323 while (isspace(*cp) && (cp < maxcp))
1324 cp++;
1325
1326 if (cp >= maxcp)
1327 goto defaults;
1328
1329 siz = precsize_aton(&cp);
1330
1331 while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */
1332 cp++;
1333
1334 while (isspace(*cp) && (cp < maxcp))
1335 cp++;
1336
1337 if (cp >= maxcp)
1338 goto defaults;
1339
1340 hp = precsize_aton(&cp);
1341
1342 while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */
1343 cp++;
1344
1345 while (isspace(*cp) && (cp < maxcp))
1346 cp++;
1347
1348 if (cp >= maxcp)
1349 goto defaults;
1350
1351 vp = precsize_aton(&cp);
1352
1353 defaults:
1354
1355 bcp = binary;
1356 *bcp++ = (u_int8_t) 0; /* version byte */
1357 *bcp++ = siz;
1358 *bcp++ = hp;
1359 *bcp++ = vp;
1360 PUTLONG(latit,bcp);
1361 PUTLONG(longit,bcp);
1362 PUTLONG(alt,bcp);
1363
1364 return (16); /* size of RR in octets */
1365}
1366
1367/* takes an on-the-wire LOC RR and formats it in a human readable format. */
1368const char *
1369loc_ntoa(binary, ascii)
1370 const u_char *binary;
1371 char *ascii;
1372{
1373 static char *error = "?";
1374 register const u_char *cp = binary;
1375
1376 int latdeg, latmin, latsec, latsecfrac;
1377 int longdeg, longmin, longsec, longsecfrac;
1378 char northsouth, eastwest;
1379 int altmeters, altfrac, altsign;
1380
1381 const int referencealt = 100000 * 100;
1382
1383 int32_t latval, longval, altval;
1384 u_int32_t templ;
1385 u_int8_t sizeval, hpval, vpval, versionval;
1386
1387 char *sizestr, *hpstr, *vpstr;
1388
1389 versionval = *cp++;
1390
1391 if (versionval) {
1392 sprintf(ascii, "; error: unknown LOC RR version");
1393 return (ascii);
1394 }
1395
1396 sizeval = *cp++;
1397
1398 hpval = *cp++;
1399 vpval = *cp++;
1400
1401 GETLONG(templ, cp);
1402 latval = (templ - ((unsigned)1<<31));
1403
1404 GETLONG(templ, cp);
1405 longval = (templ - ((unsigned)1<<31));
1406
1407 GETLONG(templ, cp);
1408 if (templ < referencealt) { /* below WGS 84 spheroid */
1409 altval = referencealt - templ;
1410 altsign = -1;
1411 } else {
1412 altval = templ - referencealt;
1413 altsign = 1;
1414 }
1415
1416 if (latval < 0) {
1417 northsouth = 'S';
1418 latval = -latval;
1419 } else
1420 northsouth = 'N';
1421
1422 latsecfrac = latval % 1000;
1423 latval = latval / 1000;
1424 latsec = latval % 60;
1425 latval = latval / 60;
1426 latmin = latval % 60;
1427 latval = latval / 60;
1428 latdeg = latval;
1429
1430 if (longval < 0) {
1431 eastwest = 'W';
1432 longval = -longval;
1433 } else
1434 eastwest = 'E';
1435
1436 longsecfrac = longval % 1000;
1437 longval = longval / 1000;
1438 longsec = longval % 60;
1439 longval = longval / 60;
1440 longmin = longval % 60;
1441 longval = longval / 60;
1442 longdeg = longval;
1443
1444 altfrac = altval % 100;
1445 altmeters = (altval / 100) * altsign;
1446
1447 if ((sizestr = strdup(precsize_ntoa(sizeval))) == NULL)
1448 sizestr = error;
1449 if ((hpstr = strdup(precsize_ntoa(hpval))) == NULL)
1450 hpstr = error;
1451 if ((vpstr = strdup(precsize_ntoa(vpval))) == NULL)
1452 vpstr = error;
1453
1454 sprintf(ascii,
1455 "%d %.2d %.2d.%.3d %c %d %.2d %.2d.%.3d %c %d.%.2dm %sm %sm %sm",
1456 latdeg, latmin, latsec, latsecfrac, northsouth,
1457 longdeg, longmin, longsec, longsecfrac, eastwest,
1458 altmeters, altfrac, sizestr, hpstr, vpstr);
1459
1460 if (sizestr != error)
1461 free(sizestr);
1462 if (hpstr != error)
1463 free(hpstr);
1464 if (vpstr != error)
1465 free(vpstr);
1466
1467 return (ascii);
1468}
1469
1470
1471/* Return the number of DNS hierarchy levels in the name. */
1472int
1473__dn_count_labels(name)
1474 char *name;
1475{
1476 int i, len, count;
1477
1478 len = strlen(name);
1479
1480 for(i = 0, count = 0; i < len; i++) {
1481 if (name[i] == '.')
1482 count++;
1483 }
1484
1485 /* don't count initial wildcard */
1486 if (name[0] == '*')
1487 if (count)
1488 count--;
1489
1490 /* don't count the null label for root. */
1491 /* if terminating '.' not found, must adjust */
1492 /* count to include last label */
1493 if (len > 0 && name[len-1] != '.')
1494 count++;
1495 return (count);
1496}
1497
1498
1499/*
1500 * Make dates expressed in seconds-since-Jan-1-1970 easy to read.
1501 * SIG records are required to be printed like this, by the Secure DNS RFC.
1502 */
1503char *
1504__p_secstodate (secs)
1505 unsigned long secs;
1506{
1507 static char output[15]; /* YYYYMMDDHHMMSS and null */
1508 time_t clock = secs;
1509 struct tm *time;
1510
1511 time = gmtime(&clock);
1512 time->tm_year += 1900;
1513 time->tm_mon += 1;
1514 sprintf(output, "%04d%02d%02d%02d%02d%02d",
1515 time->tm_year, time->tm_mon, time->tm_mday,
1516 time->tm_hour, time->tm_min, time->tm_sec);
1517 return (output);
1518}
diff --git a/src/lib/libc/net/res_init.c b/src/lib/libc/net/res_init.c
new file mode 100644
index 0000000000..df176b7fa1
--- /dev/null
+++ b/src/lib/libc/net/res_init.c
@@ -0,0 +1,518 @@
1/* $OpenBSD: res_init.c,v 1.16 1998/03/16 05:07:01 millert Exp $ */
2
3/*
4 * ++Copyright++ 1985, 1989, 1993
5 * -
6 * Copyright (c) 1985, 1989, 1993
7 * The Regents of the University of California. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by the University of
20 * California, Berkeley and its contributors.
21 * 4. Neither the name of the University nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 * -
37 * Portions Copyright (c) 1993 by Digital Equipment Corporation.
38 *
39 * Permission to use, copy, modify, and distribute this software for any
40 * purpose with or without fee is hereby granted, provided that the above
41 * copyright notice and this permission notice appear in all copies, and that
42 * the name of Digital Equipment Corporation not be used in advertising or
43 * publicity pertaining to distribution of the document or software without
44 * specific, written prior permission.
45 *
46 * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
47 * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
48 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
49 * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
50 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
51 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
52 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
53 * SOFTWARE.
54 * -
55 * --Copyright--
56 */
57
58#if defined(LIBC_SCCS) && !defined(lint)
59#if 0
60static char sccsid[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93";
61static char rcsid[] = "$From: res_init.c,v 8.7 1996/09/28 06:51:07 vixie Exp $";
62#else
63static char rcsid[] = "$OpenBSD: res_init.c,v 1.16 1998/03/16 05:07:01 millert Exp $";
64#endif
65#endif /* LIBC_SCCS and not lint */
66
67#include <sys/types.h>
68#include <sys/param.h>
69#include <sys/socket.h>
70#include <sys/time.h>
71#include <netinet/in.h>
72#include <arpa/inet.h>
73#include <arpa/nameser.h>
74
75#include <stdio.h>
76#include <ctype.h>
77#include <resolv.h>
78#include <unistd.h>
79#include <stdlib.h>
80#include <string.h>
81
82/*-------------------------------------- info about "sortlist" --------------
83 * Marc Majka 1994/04/16
84 * Allan Nathanson 1994/10/29 (BIND 4.9.3.x)
85 *
86 * NetInfo resolver configuration directory support.
87 *
88 * Allow a NetInfo directory to be created in the hierarchy which
89 * contains the same information as the resolver configuration file.
90 *
91 * - The local domain name is stored as the value of the "domain" property.
92 * - The Internet address(es) of the name server(s) are stored as values
93 * of the "nameserver" property.
94 * - The name server addresses are stored as values of the "nameserver"
95 * property.
96 * - The search list for host-name lookup is stored as values of the
97 * "search" property.
98 * - The sortlist comprised of IP address netmask pairs are stored as
99 * values of the "sortlist" property. The IP address and optional netmask
100 * should be seperated by a slash (/) or ampersand (&) character.
101 * - Internal resolver variables can be set from the value of the "options"
102 * property.
103 */
104
105static void res_setoptions __P((char *, char *));
106
107#ifdef RESOLVSORT
108static const char sort_mask[] = "/&";
109#define ISSORTMASK(ch) (strchr(sort_mask, ch) != NULL)
110static u_int32_t net_mask __P((struct in_addr));
111#endif
112
113/*
114 * Resolver state default settings.
115 */
116
117struct __res_state _res
118# if defined(__BIND_RES_TEXT)
119 = { RES_TIMEOUT, } /* Motorola, et al. */
120# endif
121 ;
122
123/*
124 * Set up default settings. If the configuration file exist, the values
125 * there will have precedence. Otherwise, the server address is set to
126 * INADDR_ANY and the default domain name comes from the gethostname().
127 *
128 * An interrim version of this code (BIND 4.9, pre-4.4BSD) used 127.0.0.1
129 * rather than INADDR_ANY ("0.0.0.0") as the default name server address
130 * since it was noted that INADDR_ANY actually meant ``the first interface
131 * you "ifconfig"'d at boot time'' and if this was a SLIP or PPP interface,
132 * it had to be "up" in order for you to reach your own name server. It
133 * was later decided that since the recommended practice is to always
134 * install local static routes through 127.0.0.1 for all your network
135 * interfaces, that we could solve this problem without a code change.
136 *
137 * The configuration file should always be used, since it is the only way
138 * to specify a default domain. If you are running a server on your local
139 * machine, you should say "nameserver 0.0.0.0" or "nameserver 127.0.0.1"
140 * in the configuration file.
141 *
142 * Return 0 if completes successfully, -1 on error
143 */
144int
145res_init()
146{
147 register FILE *fp;
148 register char *cp, **pp;
149 register int n;
150 char buf[BUFSIZ];
151 int nserv = 0; /* number of nameserver records read from file */
152 int haveenv = 0;
153 int havesearch = 0;
154 size_t len;
155#ifdef RESOLVSORT
156 int nsort = 0;
157 char *net;
158#endif
159#ifndef RFC1535
160 int dots;
161#endif
162
163 /*
164 * These three fields used to be statically initialized. This made
165 * it hard to use this code in a shared library. It is necessary,
166 * now that we're doing dynamic initialization here, that we preserve
167 * the old semantics: if an application modifies one of these three
168 * fields of _res before res_init() is called, res_init() will not
169 * alter them. Of course, if an application is setting them to
170 * _zero_ before calling res_init(), hoping to override what used
171 * to be the static default, we can't detect it and unexpected results
172 * will follow. Zero for any of these fields would make no sense,
173 * so one can safely assume that the applications were already getting
174 * unexpected results.
175 *
176 * _res.options is tricky since some apps were known to diddle the bits
177 * before res_init() was first called. We can't replicate that semantic
178 * with dynamic initialization (they may have turned bits off that are
179 * set in RES_DEFAULT). Our solution is to declare such applications
180 * "broken". They could fool us by setting RES_INIT but none do (yet).
181 */
182 if (!_res.retrans)
183 _res.retrans = RES_TIMEOUT;
184 if (!_res.retry)
185 _res.retry = 4;
186 if (!(_res.options & RES_INIT))
187 _res.options = RES_DEFAULT;
188
189#ifdef USELOOPBACK
190 _res.nsaddr.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1);
191#else
192 _res.nsaddr.sin_addr.s_addr = INADDR_ANY;
193#endif
194 _res.nsaddr.sin_family = AF_INET;
195 _res.nsaddr.sin_port = htons(NAMESERVER_PORT);
196 _res.nscount = 1;
197 _res.ndots = 1;
198 _res.pfcode = 0;
199 strncpy(_res.lookups, "f", sizeof _res.lookups);
200
201 /* Allow user to override the local domain definition */
202 if (issetugid() == 0 && (cp = getenv("LOCALDOMAIN")) != NULL) {
203 (void)strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1);
204 _res.defdname[sizeof(_res.defdname) - 1] = '\0';
205 haveenv++;
206
207 /*
208 * Set search list to be blank-separated strings
209 * from rest of env value. Permits users of LOCALDOMAIN
210 * to still have a search list, and anyone to set the
211 * one that they want to use as an individual (even more
212 * important now that the rfc1535 stuff restricts searches)
213 */
214 cp = _res.defdname;
215 pp = _res.dnsrch;
216 *pp++ = cp;
217 for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) {
218 if (*cp == '\n') /* silly backwards compat */
219 break;
220 else if (*cp == ' ' || *cp == '\t') {
221 *cp = 0;
222 n = 1;
223 } else if (n) {
224 *pp++ = cp;
225 n = 0;
226 havesearch = 1;
227 }
228 }
229 /* null terminate last domain if there are excess */
230 while (*cp != '\0' && *cp != ' ' && *cp != '\t' && *cp != '\n')
231 cp++;
232 *cp = '\0';
233 *pp++ = 0;
234 }
235
236#define MATCH(line, name) \
237 (!strncmp(line, name, sizeof(name) - 1) && \
238 (line[sizeof(name) - 1] == ' ' || \
239 line[sizeof(name) - 1] == '\t'))
240
241 if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) {
242 strncpy(_res.lookups, "bf", sizeof _res.lookups);
243
244 /* read the config file */
245 buf[0] = '\0';
246 while ((cp = fgetln(fp, &len)) != NULL) {
247 /* skip lines that are too long or zero length */
248 if (len >= sizeof(buf) || len == 0)
249 continue;
250 (void)memcpy(buf, cp, len);
251 buf[len] = '\0';
252 /* skip comments */
253 if ((cp = strpbrk(buf, ";#")) != NULL)
254 *cp = '\0';
255 if (buf[0] == '\0')
256 continue;
257 /* read default domain name */
258 if (MATCH(buf, "domain")) {
259 if (haveenv) /* skip if have from environ */
260 continue;
261 cp = buf + sizeof("domain") - 1;
262 while (*cp == ' ' || *cp == '\t')
263 cp++;
264 if ((*cp == '\0') || (*cp == '\n'))
265 continue;
266 strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1);
267 _res.defdname[sizeof(_res.defdname) - 1] = '\0';
268 if ((cp = strpbrk(_res.defdname, " \t\n")) != NULL)
269 *cp = '\0';
270 havesearch = 0;
271 continue;
272 }
273 /* lookup types */
274 if (MATCH(buf, "lookup")) {
275 char *sp = NULL;
276
277 bzero(_res.lookups, sizeof _res.lookups);
278 cp = buf + sizeof("lookup") - 1;
279 for (n = 0;; cp++) {
280 if (n == MAXDNSLUS)
281 break;
282 if ((*cp == '\0') || (*cp == '\n')) {
283 if (sp) {
284 if (*sp=='y' || *sp=='b' || *sp=='f')
285 _res.lookups[n++] = *sp;
286 sp = NULL;
287 }
288 break;
289 } else if ((*cp == ' ') || (*cp == '\t') || (*cp == ',')) {
290 if (sp) {
291 if (*sp=='y' || *sp=='b' || *sp=='f')
292 _res.lookups[n++] = *sp;
293 sp = NULL;
294 }
295 } else if (sp == NULL)
296 sp = cp;
297 }
298 continue;
299 }
300 /* set search list */
301 if (MATCH(buf, "search")) {
302 if (haveenv) /* skip if have from environ */
303 continue;
304 cp = buf + sizeof("search") - 1;
305 while (*cp == ' ' || *cp == '\t')
306 cp++;
307 if ((*cp == '\0') || (*cp == '\n'))
308 continue;
309 strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1);
310 _res.defdname[sizeof(_res.defdname) - 1] = '\0';
311 if ((cp = strchr(_res.defdname, '\n')) != NULL)
312 *cp = '\0';
313 /*
314 * Set search list to be blank-separated strings
315 * on rest of line.
316 */
317 cp = _res.defdname;
318 pp = _res.dnsrch;
319 *pp++ = cp;
320 for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) {
321 if (*cp == ' ' || *cp == '\t') {
322 *cp = 0;
323 n = 1;
324 } else if (n) {
325 *pp++ = cp;
326 n = 0;
327 }
328 }
329 /* null terminate last domain if there are excess */
330 while (*cp != '\0' && *cp != ' ' && *cp != '\t')
331 cp++;
332 *cp = '\0';
333 *pp++ = 0;
334 havesearch = 1;
335 continue;
336 }
337 /* read nameservers to query */
338 if (MATCH(buf, "nameserver") && nserv < MAXNS) {
339 struct in_addr a;
340
341 cp = buf + sizeof("nameserver") - 1;
342 while (*cp == ' ' || *cp == '\t')
343 cp++;
344 if ((*cp != '\0') && (*cp != '\n') && inet_aton(cp, &a)) {
345 _res.nsaddr_list[nserv].sin_addr = a;
346 _res.nsaddr_list[nserv].sin_family = AF_INET;
347 _res.nsaddr_list[nserv].sin_port =
348 htons(NAMESERVER_PORT);
349 nserv++;
350 }
351 continue;
352 }
353#ifdef RESOLVSORT
354 if (MATCH(buf, "sortlist")) {
355 struct in_addr a;
356
357 cp = buf + sizeof("sortlist") - 1;
358 while (nsort < MAXRESOLVSORT) {
359 while (*cp == ' ' || *cp == '\t')
360 cp++;
361 if (*cp == '\0' || *cp == '\n' || *cp == ';')
362 break;
363 net = cp;
364 while (*cp && !ISSORTMASK(*cp) && *cp != ';' &&
365 isascii(*cp) && !isspace(*cp))
366 cp++;
367 n = *cp;
368 *cp = 0;
369 if (inet_aton(net, &a)) {
370 _res.sort_list[nsort].addr = a;
371 if (ISSORTMASK(n)) {
372 *cp++ = n;
373 net = cp;
374 while (*cp && *cp != ';' &&
375 isascii(*cp) && !isspace(*cp))
376 cp++;
377 n = *cp;
378 *cp = 0;
379 if (inet_aton(net, &a)) {
380 _res.sort_list[nsort].mask = a.s_addr;
381 } else {
382 _res.sort_list[nsort].mask =
383 net_mask(_res.sort_list[nsort].addr);
384 }
385 } else {
386 _res.sort_list[nsort].mask =
387 net_mask(_res.sort_list[nsort].addr);
388 }
389 nsort++;
390 }
391 *cp = n;
392 }
393 continue;
394 }
395#endif
396 if (MATCH(buf, "options")) {
397 res_setoptions(buf + sizeof("options") - 1, "conf");
398 continue;
399 }
400 }
401 if (nserv > 1)
402 _res.nscount = nserv;
403#ifdef RESOLVSORT
404 _res.nsort = nsort;
405#endif
406 (void) fclose(fp);
407 }
408 if (_res.defdname[0] == 0 &&
409 gethostname(buf, sizeof(_res.defdname) - 1) == 0 &&
410 (cp = strchr(buf, '.')) != NULL)
411 {
412 strncpy(_res.defdname, cp + 1,
413 sizeof(_res.defdname) - 1);
414 _res.defdname[sizeof(_res.defdname) - 1] = '\0';
415 }
416
417 /* find components of local domain that might be searched */
418 if (havesearch == 0) {
419 pp = _res.dnsrch;
420 *pp++ = _res.defdname;
421 *pp = NULL;
422
423#ifndef RFC1535
424 dots = 0;
425 for (cp = _res.defdname; *cp; cp++)
426 dots += (*cp == '.');
427
428 cp = _res.defdname;
429 while (pp < _res.dnsrch + MAXDFLSRCH) {
430 if (dots < LOCALDOMAINPARTS)
431 break;
432 cp = strchr(cp, '.') + 1; /* we know there is one */
433 *pp++ = cp;
434 dots--;
435 }
436 *pp = NULL;
437#ifdef DEBUG
438 if (_res.options & RES_DEBUG) {
439 printf(";; res_init()... default dnsrch list:\n");
440 for (pp = _res.dnsrch; *pp; pp++)
441 printf(";;\t%s\n", *pp);
442 printf(";;\t..END..\n");
443 }
444#endif /* DEBUG */
445#endif /* !RFC1535 */
446 }
447
448 if (issetugid())
449 _res.options |= RES_NOALIASES;
450 else if ((cp = getenv("RES_OPTIONS")) != NULL)
451 res_setoptions(cp, "env");
452 _res.options |= RES_INIT;
453 return (0);
454}
455
456/* ARGSUSED */
457static void
458res_setoptions(options, source)
459 char *options, *source;
460{
461 char *cp = options;
462 int i;
463
464#ifdef DEBUG
465 if (_res.options & RES_DEBUG)
466 printf(";; res_setoptions(\"%s\", \"%s\")...\n",
467 options, source);
468#endif
469 while (*cp) {
470 /* skip leading and inner runs of spaces */
471 while (*cp == ' ' || *cp == '\t')
472 cp++;
473 /* search for and process individual options */
474 if (!strncmp(cp, "ndots:", sizeof("ndots:") - 1)) {
475 i = atoi(cp + sizeof("ndots:") - 1);
476 if (i <= RES_MAXNDOTS)
477 _res.ndots = i;
478 else
479 _res.ndots = RES_MAXNDOTS;
480#ifdef DEBUG
481 if (_res.options & RES_DEBUG)
482 printf(";;\tndots=%d\n", _res.ndots);
483#endif
484 } else if (!strncmp(cp, "debug", sizeof("debug") - 1)) {
485#ifdef DEBUG
486 if (!(_res.options & RES_DEBUG)) {
487 printf(";; res_setoptions(\"%s\", \"%s\")..\n",
488 options, source);
489 _res.options |= RES_DEBUG;
490 }
491 printf(";;\tdebug\n");
492#endif
493 } else if (!strncmp(cp, "inet6", sizeof("inet6") - 1)) {
494 _res.options |= RES_USE_INET6;
495 } else {
496 /* XXX - print a warning here? */
497 }
498 /* skip to next run of spaces */
499 while (*cp && *cp != ' ' && *cp != '\t')
500 cp++;
501 }
502}
503
504#ifdef RESOLVSORT
505/* XXX - should really support CIDR which means explicit masks always. */
506static u_int32_t
507net_mask(in) /* XXX - should really use system's version of this */
508 struct in_addr in;
509{
510 register u_int32_t i = ntohl(in.s_addr);
511
512 if (IN_CLASSA(i))
513 return (htonl(IN_CLASSA_NET));
514 else if (IN_CLASSB(i))
515 return (htonl(IN_CLASSB_NET));
516 return (htonl(IN_CLASSC_NET));
517}
518#endif
diff --git a/src/lib/libc/net/res_mkquery.c b/src/lib/libc/net/res_mkquery.c
new file mode 100644
index 0000000000..3e7e2ae5d3
--- /dev/null
+++ b/src/lib/libc/net/res_mkquery.c
@@ -0,0 +1,195 @@
1/* $OpenBSD: res_mkquery.c,v 1.8 1997/04/13 22:37:21 provos Exp $ */
2
3/*
4 * ++Copyright++ 1985, 1993
5 * -
6 * Copyright (c) 1985, 1993
7 * The Regents of the University of California. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by the University of
20 * California, Berkeley and its contributors.
21 * 4. Neither the name of the University nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 * -
37 * Portions Copyright (c) 1993 by Digital Equipment Corporation.
38 *
39 * Permission to use, copy, modify, and distribute this software for any
40 * purpose with or without fee is hereby granted, provided that the above
41 * copyright notice and this permission notice appear in all copies, and that
42 * the name of Digital Equipment Corporation not be used in advertising or
43 * publicity pertaining to distribution of the document or software without
44 * specific, written prior permission.
45 *
46 * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
47 * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
48 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
49 * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
50 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
51 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
52 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
53 * SOFTWARE.
54 * -
55 * --Copyright--
56 */
57
58#if defined(LIBC_SCCS) && !defined(lint)
59#if 0
60static char sccsid[] = "@(#)res_mkquery.c 8.1 (Berkeley) 6/4/93";
61static char rcsid[] = "$From: res_mkquery.c,v 8.5 1996/08/27 08:33:28 vixie Exp $";
62#else
63static char rcsid[] = "$OpenBSD: res_mkquery.c,v 1.8 1997/04/13 22:37:21 provos Exp $";
64#endif
65#endif /* LIBC_SCCS and not lint */
66
67#include <sys/types.h>
68#include <sys/param.h>
69#include <netinet/in.h>
70#include <arpa/nameser.h>
71
72#include <stdio.h>
73#include <netdb.h>
74#include <resolv.h>
75#include <string.h>
76
77/*
78 * Form all types of queries.
79 * Returns the size of the result or -1.
80 */
81/* ARGSUSED */
82int
83res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
84 int op; /* opcode of query */
85 const char *dname; /* domain name */
86 int class, type; /* class and type of query */
87 const u_char *data; /* resource record data */
88 int datalen; /* length of data */
89 const u_char *newrr_in; /* new rr for modify or append */
90 u_char *buf; /* buffer to put query */
91 int buflen; /* size of buffer */
92{
93 register HEADER *hp;
94 register u_char *cp;
95 register int n;
96 u_char *dnptrs[20], **dpp, **lastdnptr;
97
98 if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
99 h_errno = NETDB_INTERNAL;
100 return (-1);
101 }
102#ifdef DEBUG
103 if (_res.options & RES_DEBUG)
104 printf(";; res_mkquery(%d, %s, %d, %d)\n",
105 op, dname, class, type);
106#endif
107 /*
108 * Initialize header fields.
109 *
110 * A special random number generator is used to create non predictable
111 * and non repeating ids over a long period. It also avoids reuse
112 * by switching between two distinct number cycles.
113 */
114
115 if ((buf == NULL) || (buflen < HFIXEDSZ))
116 return (-1);
117 bzero(buf, HFIXEDSZ);
118 hp = (HEADER *) buf;
119 _res.id = res_randomid();
120 hp->id = htons(_res.id);
121 hp->opcode = op;
122 hp->rd = (_res.options & RES_RECURSE) != 0;
123 hp->rcode = NOERROR;
124 cp = buf + HFIXEDSZ;
125 buflen -= HFIXEDSZ;
126 dpp = dnptrs;
127 *dpp++ = buf;
128 *dpp++ = NULL;
129 lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0];
130 /*
131 * perform opcode specific processing
132 */
133 switch (op) {
134 case QUERY: /*FALLTHROUGH*/
135 case NS_NOTIFY_OP:
136 if ((buflen -= QFIXEDSZ) < 0)
137 return (-1);
138 if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
139 return (-1);
140 cp += n;
141 buflen -= n;
142 __putshort(type, cp);
143 cp += INT16SZ;
144 __putshort(class, cp);
145 cp += INT16SZ;
146 hp->qdcount = htons(1);
147 if (op == QUERY || data == NULL)
148 break;
149 /*
150 * Make an additional record for completion domain.
151 */
152 buflen -= RRFIXEDSZ;
153 n = dn_comp((char *)data, cp, buflen, dnptrs, lastdnptr);
154 if (n < 0)
155 return (-1);
156 cp += n;
157 buflen -= n;
158 __putshort(T_NULL, cp);
159 cp += INT16SZ;
160 __putshort(class, cp);
161 cp += INT16SZ;
162 __putlong(0, cp);
163 cp += INT32SZ;
164 __putshort(0, cp);
165 cp += INT16SZ;
166 hp->arcount = htons(1);
167 break;
168
169 case IQUERY:
170 /*
171 * Initialize answer section
172 */
173 if (buflen < 1 + RRFIXEDSZ + datalen)
174 return (-1);
175 *cp++ = '\0'; /* no domain name */
176 __putshort(type, cp);
177 cp += INT16SZ;
178 __putshort(class, cp);
179 cp += INT16SZ;
180 __putlong(0, cp);
181 cp += INT32SZ;
182 __putshort(datalen, cp);
183 cp += INT16SZ;
184 if (datalen) {
185 bcopy(data, cp, datalen);
186 cp += datalen;
187 }
188 hp->ancount = htons(1);
189 break;
190
191 default:
192 return (-1);
193 }
194 return (cp - buf);
195}
diff --git a/src/lib/libc/net/res_query.c b/src/lib/libc/net/res_query.c
new file mode 100644
index 0000000000..a08897b45a
--- /dev/null
+++ b/src/lib/libc/net/res_query.c
@@ -0,0 +1,398 @@
1/* $OpenBSD: res_query.c,v 1.12 1998/08/31 18:15:29 deraadt Exp $ */
2
3/*
4 * ++Copyright++ 1988, 1993
5 * -
6 * Copyright (c) 1988, 1993
7 * The Regents of the University of California. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by the University of
20 * California, Berkeley and its contributors.
21 * 4. Neither the name of the University nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 * -
37 * Portions Copyright (c) 1993 by Digital Equipment Corporation.
38 *
39 * Permission to use, copy, modify, and distribute this software for any
40 * purpose with or without fee is hereby granted, provided that the above
41 * copyright notice and this permission notice appear in all copies, and that
42 * the name of Digital Equipment Corporation not be used in advertising or
43 * publicity pertaining to distribution of the document or software without
44 * specific, written prior permission.
45 *
46 * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
47 * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
48 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
49 * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
50 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
51 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
52 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
53 * SOFTWARE.
54 * -
55 * --Copyright--
56 */
57
58#if defined(LIBC_SCCS) && !defined(lint)
59#if 0
60static char sccsid[] = "@(#)res_query.c 8.1 (Berkeley) 6/4/93";
61static char rcsid[] = "$From: res_query.c,v 8.9 1996/09/22 00:13:28 vixie Exp $";
62#else
63static char rcsid[] = "$OpenBSD: res_query.c,v 1.12 1998/08/31 18:15:29 deraadt Exp $";
64#endif
65#endif /* LIBC_SCCS and not lint */
66
67#include <sys/types.h>
68#include <sys/param.h>
69#include <netinet/in.h>
70#include <arpa/inet.h>
71#include <arpa/nameser.h>
72
73#include <stdio.h>
74#include <netdb.h>
75#include <resolv.h>
76#include <ctype.h>
77#include <errno.h>
78#include <stdlib.h>
79#include <string.h>
80#include <unistd.h>
81
82#if PACKETSZ > 1024
83#define MAXPACKET PACKETSZ
84#else
85#define MAXPACKET 1024
86#endif
87
88const char *hostalias __P((const char *));
89int h_errno;
90
91/*
92 * Formulate a normal query, send, and await answer.
93 * Returned answer is placed in supplied buffer "answer".
94 * Perform preliminary check of answer, returning success only
95 * if no error is indicated and the answer count is nonzero.
96 * Return the size of the response on success, -1 on error.
97 * Error number is left in h_errno.
98 *
99 * Caller must parse answer and determine whether it answers the question.
100 */
101int
102res_query(name, class, type, answer, anslen)
103 const char *name; /* domain name */
104 int class, type; /* class and type of query */
105 u_char *answer; /* buffer to put answer */
106 int anslen; /* size of answer buffer */
107{
108 u_char buf[MAXPACKET];
109 register HEADER *hp = (HEADER *) answer;
110 int n;
111
112 hp->rcode = NOERROR; /* default */
113
114 if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
115 h_errno = NETDB_INTERNAL;
116 return (-1);
117 }
118#ifdef DEBUG
119 if (_res.options & RES_DEBUG)
120 printf(";; res_query(%s, %d, %d)\n", name, class, type);
121#endif
122
123 n = res_mkquery(QUERY, name, class, type, NULL, 0, NULL,
124 buf, sizeof(buf));
125 if (n <= 0) {
126#ifdef DEBUG
127 if (_res.options & RES_DEBUG)
128 printf(";; res_query: mkquery failed\n");
129#endif
130 h_errno = NO_RECOVERY;
131 return (n);
132 }
133 n = res_send(buf, n, answer, anslen);
134 if (n < 0) {
135#ifdef DEBUG
136 if (_res.options & RES_DEBUG)
137 printf(";; res_query: send error\n");
138#endif
139 h_errno = TRY_AGAIN;
140 return (n);
141 }
142
143 if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) {
144#ifdef DEBUG
145 if (_res.options & RES_DEBUG)
146 printf(";; rcode = %d, ancount=%d\n", hp->rcode,
147 ntohs(hp->ancount));
148#endif
149 switch (hp->rcode) {
150 case NXDOMAIN:
151 h_errno = HOST_NOT_FOUND;
152 break;
153 case SERVFAIL:
154 h_errno = TRY_AGAIN;
155 break;
156 case NOERROR:
157 h_errno = NO_DATA;
158 break;
159 case FORMERR:
160 case NOTIMP:
161 case REFUSED:
162 default:
163 h_errno = NO_RECOVERY;
164 break;
165 }
166 return (-1);
167 }
168 return (n);
169}
170
171/*
172 * Formulate a normal query, send, and retrieve answer in supplied buffer.
173 * Return the size of the response on success, -1 on error.
174 * If enabled, implement search rules until answer or unrecoverable failure
175 * is detected. Error code, if any, is left in h_errno.
176 */
177int
178res_search(name, class, type, answer, anslen)
179 const char *name; /* domain name */
180 int class, type; /* class and type of query */
181 u_char *answer; /* buffer to put answer */
182 int anslen; /* size of answer */
183{
184 register const char *cp, * const *domain;
185 HEADER *hp = (HEADER *) answer;
186 u_int dots;
187 int trailing_dot, ret, saved_herrno;
188 int got_nodata = 0, got_servfail = 0, tried_as_is = 0;
189
190 if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
191 h_errno = NETDB_INTERNAL;
192 return (-1);
193 }
194 errno = 0;
195 h_errno = HOST_NOT_FOUND; /* default, if we never query */
196 dots = 0;
197 for (cp = name; *cp; cp++)
198 dots += (*cp == '.');
199 trailing_dot = 0;
200 if (cp > name && *--cp == '.')
201 trailing_dot++;
202
203 /*
204 * if there aren't any dots, it could be a user-level alias
205 */
206 if (!dots && (cp = __hostalias(name)) != NULL)
207 return (res_query(cp, class, type, answer, anslen));
208
209 /*
210 * If there are dots in the name already, let's just give it a try
211 * 'as is'. The threshold can be set with the "ndots" option.
212 */
213 saved_herrno = -1;
214 if (dots >= _res.ndots) {
215 ret = res_querydomain(name, NULL, class, type, answer, anslen);
216 if (ret > 0)
217 return (ret);
218 saved_herrno = h_errno;
219 tried_as_is++;
220 }
221
222 /*
223 * We do at least one level of search if
224 * - there is no dot and RES_DEFNAME is set, or
225 * - there is at least one dot, there is no trailing dot,
226 * and RES_DNSRCH is set.
227 */
228 if ((!dots && (_res.options & RES_DEFNAMES)) ||
229 (dots && !trailing_dot && (_res.options & RES_DNSRCH))) {
230 int done = 0;
231
232 for (domain = (const char * const *)_res.dnsrch;
233 *domain && !done;
234 domain++) {
235
236 ret = res_querydomain(name, *domain, class, type,
237 answer, anslen);
238 if (ret > 0)
239 return (ret);
240
241 /*
242 * If no server present, give up.
243 * If name isn't found in this domain,
244 * keep trying higher domains in the search list
245 * (if that's enabled).
246 * On a NO_DATA error, keep trying, otherwise
247 * a wildcard entry of another type could keep us
248 * from finding this entry higher in the domain.
249 * If we get some other error (negative answer or
250 * server failure), then stop searching up,
251 * but try the input name below in case it's
252 * fully-qualified.
253 */
254 if (errno == ECONNREFUSED) {
255 h_errno = TRY_AGAIN;
256 return (-1);
257 }
258
259 switch (h_errno) {
260 case NO_DATA:
261 got_nodata++;
262 /* FALLTHROUGH */
263 case HOST_NOT_FOUND:
264 /* keep trying */
265 break;
266 case TRY_AGAIN:
267 if (hp->rcode == SERVFAIL) {
268 /* try next search element, if any */
269 got_servfail++;
270 break;
271 }
272 /* FALLTHROUGH */
273 default:
274 /* anything else implies that we're done */
275 done++;
276 }
277
278 /* if we got here for some reason other than DNSRCH,
279 * we only wanted one iteration of the loop, so stop.
280 */
281 if (!(_res.options & RES_DNSRCH))
282 done++;
283 }
284 }
285
286 /* if we have not already tried the name "as is", do that now.
287 * note that we do this regardless of how many dots were in the
288 * name or whether it ends with a dot.
289 */
290 if (!tried_as_is) {
291 ret = res_querydomain(name, NULL, class, type, answer, anslen);
292 if (ret > 0)
293 return (ret);
294 }
295
296 /* if we got here, we didn't satisfy the search.
297 * if we did an initial full query, return that query's h_errno
298 * (note that we wouldn't be here if that query had succeeded).
299 * else if we ever got a nodata, send that back as the reason.
300 * else send back meaningless h_errno, that being the one from
301 * the last DNSRCH we did.
302 */
303 if (saved_herrno != -1)
304 h_errno = saved_herrno;
305 else if (got_nodata)
306 h_errno = NO_DATA;
307 else if (got_servfail)
308 h_errno = TRY_AGAIN;
309 return (-1);
310}
311
312/*
313 * Perform a call on res_query on the concatenation of name and domain,
314 * removing a trailing dot from name if domain is NULL.
315 */
316int
317res_querydomain(name, domain, class, type, answer, anslen)
318 const char *name, *domain;
319 int class, type; /* class and type of query */
320 u_char *answer; /* buffer to put answer */
321 int anslen; /* size of answer */
322{
323 char nbuf[MAXDNAME*2+1];
324 const char *longname = nbuf;
325 int n;
326
327 if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
328 h_errno = NETDB_INTERNAL;
329 return (-1);
330 }
331#ifdef DEBUG
332 if (_res.options & RES_DEBUG)
333 printf(";; res_querydomain(%s, %s, %d, %d)\n",
334 name, domain?domain:"<Nil>", class, type);
335#endif
336 if (domain == NULL) {
337 /*
338 * Check for trailing '.';
339 * copy without '.' if present.
340 */
341 n = strlen(name) - 1;
342 if (n != (0 - 1) && name[n] == '.' && n < sizeof(nbuf) - 1) {
343 bcopy(name, nbuf, n);
344 nbuf[n] = '\0';
345 } else
346 longname = name;
347 } else
348 sprintf(nbuf, "%.*s.%.*s", MAXDNAME, name, MAXDNAME, domain);
349
350 return (res_query(longname, class, type, answer, anslen));
351}
352
353const char *
354hostalias(name)
355 register const char *name;
356{
357 register char *cp1, *cp2;
358 FILE *fp;
359 char *file;
360 char buf[BUFSIZ];
361 static char abuf[MAXDNAME];
362 size_t len;
363
364 if (_res.options & RES_NOALIASES)
365 return (NULL);
366 file = getenv("HOSTALIASES");
367 if (issetugid() != 0 || file == NULL || (fp = fopen(file, "r")) == NULL)
368 return (NULL);
369 setbuf(fp, NULL);
370 while ((cp1 = fgetln(fp, &len)) != NULL) {
371 if (cp1[len-1] == '\n')
372 len--;
373 if (len >= sizeof(buf) || len == 0)
374 continue;
375 (void)memcpy(buf, cp1, len);
376 buf[len] = '\0';
377
378 for (cp1 = buf; *cp1 && !isspace(*cp1); ++cp1)
379 ;
380 if (!*cp1)
381 break;
382 *cp1 = '\0';
383 if (!strcasecmp(buf, name)) {
384 while (isspace(*++cp1))
385 ;
386 if (!*cp1)
387 break;
388 for (cp2 = cp1 + 1; *cp2 && !isspace(*cp2); ++cp2)
389 ;
390 strncpy(abuf, cp1, sizeof(abuf) - 1);
391 abuf[sizeof(abuf) - 1] = *cp2 = '\0';
392 fclose(fp);
393 return (abuf);
394 }
395 }
396 fclose(fp);
397 return (NULL);
398}
diff --git a/src/lib/libc/net/res_random.c b/src/lib/libc/net/res_random.c
new file mode 100644
index 0000000000..bd32a50c33
--- /dev/null
+++ b/src/lib/libc/net/res_random.c
@@ -0,0 +1,233 @@
1/* $OpenBSD: res_random.c,v 1.7 1997/07/25 20:30:08 mickey Exp $ */
2
3/*
4 * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
5 * All rights reserved.
6 *
7 * Theo de Raadt <deraadt@openbsd.org> came up with the idea of using
8 * such a mathematical system to generate more random (yet non-repeating)
9 * ids to solve the resolver/named problem. But Niels designed the
10 * actual system based on the constraints.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. All advertising materials mentioning features or use of this software
21 * must display the following acknowledgement:
22 * This product includes software developed by Niels Provos.
23 * 4. The name of the author may not be used to endorse or promote products
24 * derived from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
27 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
28 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
30 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
31 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 */
37
38/*
39 * seed = random 15bit
40 * n = prime, g0 = generator to n,
41 * j = random so that gcd(j,n-1) == 1
42 * g = g0^j mod n will be a generator again.
43 *
44 * X[0] = random seed.
45 * X[n] = a*X[n-1]+b mod m is a Linear Congruential Generator
46 * with a = 7^(even random) mod m,
47 * b = random with gcd(b,m) == 1
48 * m = 31104 and a maximal period of m-1.
49 *
50 * The transaction id is determined by:
51 * id[n] = seed xor (g^X[n] mod n)
52 *
53 * Effectivly the id is restricted to the lower 15 bits, thus
54 * yielding two different cycles by toggling the msb on and off.
55 * This avoids reuse issues caused by reseeding.
56 *
57 * The 16 bit space is very small and brute force attempts are
58 * entirly feasible, we skip a random number of transaction ids
59 * so that an attacker will not get sequential ids.
60 */
61
62#include <sys/types.h>
63#include <netinet/in.h>
64#include <sys/time.h>
65#include <resolv.h>
66
67#include <unistd.h>
68#include <stdlib.h>
69#include <string.h>
70
71#define RU_OUT 180 /* Time after wich will be reseeded */
72#define RU_MAX 30000 /* Uniq cycle, avoid blackjack prediction */
73#define RU_GEN 2 /* Starting generator */
74#define RU_N 32749 /* RU_N-1 = 2*2*3*2729 */
75#define RU_AGEN 7 /* determine ru_a as RU_AGEN^(2*rand) */
76#define RU_M 31104 /* RU_M = 2^7*3^5 - don't change */
77
78#define PFAC_N 3
79const static u_int16_t pfacts[PFAC_N] = {
80 2,
81 3,
82 2729
83};
84
85static u_int16_t ru_x;
86static u_int16_t ru_seed;
87static u_int16_t ru_a, ru_b;
88static u_int16_t ru_g;
89static u_int16_t ru_counter = 0;
90static u_int16_t ru_msb = 0;
91static long ru_reseed;
92static u_int32_t tmp; /* Storage for unused random */
93static struct timeval tv;
94
95static u_int16_t pmod __P((u_int16_t, u_int16_t, u_int16_t));
96static void res_initid __P((void));
97
98/*
99 * Do a fast modular exponation, returned value will be in the range
100 * of 0 - (mod-1)
101 */
102
103#ifdef __STDC__
104static u_int16_t
105pmod(u_int16_t gen, u_int16_t exp, u_int16_t mod)
106#else
107static u_int16_t
108pmod(gen, exp, mod)
109 u_int16_t gen, exp, mod;
110#endif
111{
112 u_int16_t s, t, u;
113
114 s = 1;
115 t = gen;
116 u = exp;
117
118 while (u) {
119 if (u & 1)
120 s = (s*t) % mod;
121 u >>= 1;
122 t = (t*t) % mod;
123 }
124 return (s);
125}
126
127/*
128 * Initalizes the seed and chooses a suitable generator. Also toggles
129 * the msb flag. The msb flag is used to generate two distinct
130 * cycles of random numbers and thus avoiding reuse of ids.
131 *
132 * This function is called from res_randomid() when needed, an
133 * application does not have to worry about it.
134 */
135static void
136res_initid()
137{
138 u_int16_t j, i;
139 int noprime = 1;
140
141 tmp = arc4random();
142 ru_x = (tmp & 0xFFFF) % RU_M;
143
144 /* 15 bits of random seed */
145 ru_seed = (tmp >> 16) & 0x7FFF;
146
147 tmp = arc4random();
148
149 /* Determine the LCG we use */
150 ru_b = (tmp & 0xfffe) | 1;
151 ru_a = pmod(RU_AGEN, (tmp >> 16) & 0xfffe, RU_M);
152 while (ru_b % 3 == 0)
153 ru_b += 2;
154
155 tmp = arc4random();
156 j = tmp % RU_N;
157 tmp = tmp >> 16;
158
159 /*
160 * Do a fast gcd(j,RU_N-1), so we can find a j with
161 * gcd(j, RU_N-1) == 1, giving a new generator for
162 * RU_GEN^j mod RU_N
163 */
164
165 while (noprime) {
166 for (i=0; i<PFAC_N; i++)
167 if (j%pfacts[i] == 0)
168 break;
169
170 if (i>=PFAC_N)
171 noprime = 0;
172 else
173 j = (j+1) % RU_N;
174 }
175
176 ru_g = pmod(RU_GEN,j,RU_N);
177 ru_counter = 0;
178
179 gettimeofday(&tv, NULL);
180 ru_reseed = tv.tv_sec + RU_OUT;
181 ru_msb = ru_msb == 0x8000 ? 0 : 0x8000;
182}
183
184u_int
185res_randomid()
186{
187 int i, n;
188
189 gettimeofday(&tv, NULL);
190 if (ru_counter >= RU_MAX || tv.tv_sec > ru_reseed)
191 res_initid();
192
193 if (!tmp)
194 tmp = arc4random();
195
196 /* Skip a random number of ids */
197 n = tmp & 0x7; tmp = tmp >> 3;
198 if (ru_counter + n >= RU_MAX)
199 res_initid();
200
201 for (i=0; i<=n; i++)
202 /* Linear Congruential Generator */
203 ru_x = (ru_a*ru_x + ru_b) % RU_M;
204
205 ru_counter += i;
206
207 return (ru_seed ^ pmod(ru_g,ru_x,RU_N)) | ru_msb;
208}
209
210#if 0
211void
212main(int argc, char **argv)
213{
214 int i, n;
215 u_int16_t wert;
216
217 res_initid();
218
219 printf("Generator: %d\n", ru_g);
220 printf("Seed: %d\n", ru_seed);
221 printf("Reseed at %ld\n", ru_reseed);
222 printf("Ru_X: %d\n", ru_x);
223 printf("Ru_A: %d\n", ru_a);
224 printf("Ru_B: %d\n", ru_b);
225
226 n = atoi(argv[1]);
227 for (i=0;i<n;i++) {
228 wert = res_randomid();
229 printf("%06d\n", wert);
230 }
231}
232#endif
233
diff --git a/src/lib/libc/net/res_send.c b/src/lib/libc/net/res_send.c
new file mode 100644
index 0000000000..0cda3510eb
--- /dev/null
+++ b/src/lib/libc/net/res_send.c
@@ -0,0 +1,780 @@
1/* $OpenBSD: res_send.c,v 1.8 1998/03/19 00:30:08 millert Exp $ */
2
3/*
4 * ++Copyright++ 1985, 1989, 1993
5 * -
6 * Copyright (c) 1985, 1989, 1993
7 * The Regents of the University of California. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by the University of
20 * California, Berkeley and its contributors.
21 * 4. Neither the name of the University nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 * -
37 * Portions Copyright (c) 1993 by Digital Equipment Corporation.
38 *
39 * Permission to use, copy, modify, and distribute this software for any
40 * purpose with or without fee is hereby granted, provided that the above
41 * copyright notice and this permission notice appear in all copies, and that
42 * the name of Digital Equipment Corporation not be used in advertising or
43 * publicity pertaining to distribution of the document or software without
44 * specific, written prior permission.
45 *
46 * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
47 * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
48 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
49 * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
50 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
51 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
52 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
53 * SOFTWARE.
54 * -
55 * --Copyright--
56 */
57
58#if defined(LIBC_SCCS) && !defined(lint)
59#if 0
60static char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93";
61static char rcsid[] = "$From: res_send.c,v 8.12 1996/10/08 04:51:06 vixie Exp $";
62#else
63static char rcsid[] = "$OpenBSD: res_send.c,v 1.8 1998/03/19 00:30:08 millert Exp $";
64#endif
65#endif /* LIBC_SCCS and not lint */
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
74/*
75 * Send query to name server and wait for reply.
76 */
77
78#include <sys/types.h>
79#include <sys/param.h>
80#include <sys/time.h>
81#include <sys/socket.h>
82#include <sys/uio.h>
83#include <netinet/in.h>
84#include <arpa/nameser.h>
85#include <arpa/inet.h>
86
87#include <stdio.h>
88#include <netdb.h>
89#include <errno.h>
90#include <resolv.h>
91#include <stdlib.h>
92#include <string.h>
93#include <unistd.h>
94
95static int s = -1; /* socket used for communications */
96static int connected = 0; /* is the socket connected */
97static int vc = 0; /* is the socket a virtual ciruit? */
98
99#ifndef FD_SET
100/* XXX - should be in portability.h */
101#define NFDBITS 32
102#define FD_SETSIZE 32
103#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
104#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
105#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
106#define FD_ZERO(p) bzero((char *)(p), sizeof(*(p)))
107#endif
108
109#define CAN_RECONNECT 1
110
111#ifndef DEBUG
112# define Dprint(cond, args) /*empty*/
113# define DprintQ(cond, args, query, size) /*empty*/
114# define Aerror(file, string, error, address) /*empty*/
115# define Perror(file, string, error) /*empty*/
116#else
117# define Dprint(cond, args) if (cond) {fprintf args;} else {}
118# define DprintQ(cond, args, query, size) if (cond) {\
119 fprintf args;\
120 __fp_nquery(query, size, stdout);\
121 } else {}
122 static void
123 Aerror(file, string, error, address)
124 FILE *file;
125 char *string;
126 int error;
127 struct sockaddr_in address;
128 {
129 int save = errno;
130
131 if (_res.options & RES_DEBUG) {
132 fprintf(file, "res_send: %s ([%s].%u): %s\n",
133 string,
134 inet_ntoa(address.sin_addr),
135 ntohs(address.sin_port),
136 strerror(error));
137 }
138 errno = save;
139 }
140 static void
141 Perror(file, string, error)
142 FILE *file;
143 char *string;
144 int error;
145 {
146 int save = errno;
147
148 if (_res.options & RES_DEBUG) {
149 fprintf(file, "res_send: %s: %s\n",
150 string, strerror(error));
151 }
152 errno = save;
153 }
154#endif
155
156static res_send_qhook Qhook = NULL;
157static res_send_rhook Rhook = NULL;
158
159void
160res_send_setqhook(hook)
161 res_send_qhook hook;
162{
163
164 Qhook = hook;
165}
166
167void
168res_send_setrhook(hook)
169 res_send_rhook hook;
170{
171
172 Rhook = hook;
173}
174
175/* int
176 * res_isourserver(ina)
177 * looks up "ina" in _res.ns_addr_list[]
178 * returns:
179 * 0 : not found
180 * >0 : found
181 * author:
182 * paul vixie, 29may94
183 */
184int
185res_isourserver(inp)
186 const struct sockaddr_in *inp;
187{
188 struct sockaddr_in ina;
189 register int ns, ret;
190
191 ina = *inp;
192 ret = 0;
193 for (ns = 0; ns < _res.nscount; ns++) {
194 register const struct sockaddr_in *srv = &_res.nsaddr_list[ns];
195
196 if (srv->sin_family == ina.sin_family &&
197 srv->sin_port == ina.sin_port &&
198 (srv->sin_addr.s_addr == INADDR_ANY ||
199 srv->sin_addr.s_addr == ina.sin_addr.s_addr)) {
200 ret++;
201 break;
202 }
203 }
204 return (ret);
205}
206
207/* int
208 * res_nameinquery(name, type, class, buf, eom)
209 * look for (name,type,class) in the query section of packet (buf,eom)
210 * returns:
211 * -1 : format error
212 * 0 : not found
213 * >0 : found
214 * author:
215 * paul vixie, 29may94
216 */
217int
218res_nameinquery(name, type, class, buf, eom)
219 const char *name;
220 register int type, class;
221 const u_char *buf, *eom;
222{
223 register const u_char *cp = buf + HFIXEDSZ;
224 int qdcount = ntohs(((HEADER*)buf)->qdcount);
225
226 while (qdcount-- > 0) {
227 char tname[MAXDNAME+1];
228 register int n, ttype, tclass;
229
230 n = dn_expand(buf, eom, cp, tname, sizeof tname);
231 if (n < 0)
232 return (-1);
233 cp += n;
234 ttype = _getshort(cp); cp += INT16SZ;
235 tclass = _getshort(cp); cp += INT16SZ;
236 if (ttype == type &&
237 tclass == class &&
238 strcasecmp(tname, name) == 0)
239 return (1);
240 }
241 return (0);
242}
243
244/* int
245 * res_queriesmatch(buf1, eom1, buf2, eom2)
246 * is there a 1:1 mapping of (name,type,class)
247 * in (buf1,eom1) and (buf2,eom2)?
248 * returns:
249 * -1 : format error
250 * 0 : not a 1:1 mapping
251 * >0 : is a 1:1 mapping
252 * author:
253 * paul vixie, 29may94
254 */
255int
256res_queriesmatch(buf1, eom1, buf2, eom2)
257 const u_char *buf1, *eom1;
258 const u_char *buf2, *eom2;
259{
260 register const u_char *cp = buf1 + HFIXEDSZ;
261 int qdcount = ntohs(((HEADER*)buf1)->qdcount);
262
263 if (qdcount != ntohs(((HEADER*)buf2)->qdcount))
264 return (0);
265 while (qdcount-- > 0) {
266 char tname[MAXDNAME+1];
267 register int n, ttype, tclass;
268
269 n = dn_expand(buf1, eom1, cp, tname, sizeof tname);
270 if (n < 0)
271 return (-1);
272 cp += n;
273 ttype = _getshort(cp); cp += INT16SZ;
274 tclass = _getshort(cp); cp += INT16SZ;
275 if (!res_nameinquery(tname, ttype, tclass, buf2, eom2))
276 return (0);
277 }
278 return (1);
279}
280
281int
282res_send(buf, buflen, ans, anssiz)
283 const u_char *buf;
284 int buflen;
285 u_char *ans;
286 int anssiz;
287{
288 HEADER *hp = (HEADER *) buf;
289 HEADER *anhp = (HEADER *) ans;
290 int gotsomewhere, connreset, terrno, try, v_circuit, resplen, ns;
291 register int n;
292 u_int badns; /* XXX NSMAX can't exceed #/bits in this var */
293
294 if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
295 /* errno should have been set by res_init() in this case. */
296 return (-1);
297 }
298 DprintQ((_res.options & RES_DEBUG) || (_res.pfcode & RES_PRF_QUERY),
299 (stdout, ";; res_send()\n"), buf, buflen);
300 v_circuit = (_res.options & RES_USEVC) || buflen > PACKETSZ;
301 gotsomewhere = 0;
302 connreset = 0;
303 terrno = ETIMEDOUT;
304 badns = 0;
305
306 /*
307 * Send request, RETRY times, or until successful
308 */
309 for (try = 0; try < _res.retry; try++) {
310 for (ns = 0; ns < _res.nscount; ns++) {
311 struct sockaddr_in *nsap = &_res.nsaddr_list[ns];
312 same_ns:
313 if (badns & (1 << ns)) {
314 res_close();
315 goto next_ns;
316 }
317
318 if (Qhook) {
319 int done = 0, loops = 0;
320
321 do {
322 res_sendhookact act;
323
324 act = (*Qhook)(&nsap, &buf, &buflen,
325 ans, anssiz, &resplen);
326 switch (act) {
327 case res_goahead:
328 done = 1;
329 break;
330 case res_nextns:
331 res_close();
332 goto next_ns;
333 case res_done:
334 return (resplen);
335 case res_modified:
336 /* give the hook another try */
337 if (++loops < 42) /*doug adams*/
338 break;
339 /*FALLTHROUGH*/
340 case res_error:
341 /*FALLTHROUGH*/
342 default:
343 return (-1);
344 }
345 } while (!done);
346 }
347
348 Dprint(_res.options & RES_DEBUG,
349 (stdout, ";; Querying server (# %d) address = %s\n",
350 ns + 1, inet_ntoa(nsap->sin_addr)));
351
352 if (v_circuit) {
353 int truncated;
354 struct iovec iov[2];
355 u_short len;
356 u_char *cp;
357
358 /*
359 * Use virtual circuit;
360 * at most one attempt per server.
361 */
362 try = _res.retry;
363 truncated = 0;
364 if ((s < 0) || (!vc)) {
365 if (s >= 0)
366 res_close();
367
368 s = socket(PF_INET, SOCK_STREAM, 0);
369 if (s < 0) {
370 terrno = errno;
371 Perror(stderr, "socket(vc)", errno);
372 return (-1);
373 }
374 errno = 0;
375 if (connect(s, (struct sockaddr *)nsap,
376 sizeof(struct sockaddr)) < 0) {
377 terrno = errno;
378 Aerror(stderr, "connect/vc",
379 errno, *nsap);
380 badns |= (1 << ns);
381 res_close();
382 goto next_ns;
383 }
384 vc = 1;
385 }
386 /*
387 * Send length & message
388 */
389 putshort((u_short)buflen, (u_char*)&len);
390 iov[0].iov_base = (caddr_t)&len;
391 iov[0].iov_len = INT16SZ;
392 iov[1].iov_base = (caddr_t)buf;
393 iov[1].iov_len = buflen;
394 if (writev(s, iov, 2) != (INT16SZ + buflen)) {
395 terrno = errno;
396 Perror(stderr, "write failed", errno);
397 badns |= (1 << ns);
398 res_close();
399 goto next_ns;
400 }
401 /*
402 * Receive length & response
403 */
404read_len:
405 cp = ans;
406 len = INT16SZ;
407 while ((n = read(s, (char *)cp, (int)len)) > 0) {
408 cp += n;
409 if ((len -= n) <= 0)
410 break;
411 }
412 if (n <= 0) {
413 terrno = errno;
414 Perror(stderr, "read failed", errno);
415 res_close();
416 /*
417 * A long running process might get its TCP
418 * connection reset if the remote server was
419 * restarted. Requery the server instead of
420 * trying a new one. When there is only one
421 * server, this means that a query might work
422 * instead of failing. We only allow one reset
423 * per query to prevent looping.
424 */
425 if (terrno == ECONNRESET && !connreset) {
426 connreset = 1;
427 res_close();
428 goto same_ns;
429 }
430 res_close();
431 goto next_ns;
432 }
433 resplen = _getshort(ans);
434 if (resplen > anssiz) {
435 Dprint(_res.options & RES_DEBUG,
436 (stdout, ";; response truncated\n")
437 );
438 truncated = 1;
439 len = anssiz;
440 } else
441 len = resplen;
442 cp = ans;
443 while (len != 0 &&
444 (n = read(s, (char *)cp, (int)len)) > 0) {
445 cp += n;
446 len -= n;
447 }
448 if (n <= 0) {
449 terrno = errno;
450 Perror(stderr, "read(vc)", errno);
451 res_close();
452 goto next_ns;
453 }
454 if (truncated) {
455 /*
456 * Flush rest of answer
457 * so connection stays in synch.
458 */
459 anhp->tc = 1;
460 len = resplen - anssiz;
461 while (len != 0) {
462 char junk[PACKETSZ];
463
464 n = (len > sizeof(junk)
465 ? sizeof(junk)
466 : len);
467 if ((n = read(s, junk, n)) > 0)
468 len -= n;
469 else
470 break;
471 }
472 }
473 /*
474 * The calling applicating has bailed out of
475 * a previous call and failed to arrange to have
476 * the circuit closed or the server has got
477 * itself confused. Anyway drop the packet and
478 * wait for the correct one.
479 */
480 if (hp->id != anhp->id) {
481 DprintQ((_res.options & RES_DEBUG) ||
482 (_res.pfcode & RES_PRF_REPLY),
483 (stdout, ";; old answer (unexpected):\n"),
484 ans, (resplen>anssiz)?anssiz:resplen);
485 goto read_len;
486 }
487 } else {
488 /*
489 * Use datagrams.
490 */
491 struct timeval timeout;
492 fd_set *dsmaskp;
493 struct sockaddr_in from;
494 int fromlen;
495
496 if ((s < 0) || vc) {
497 if (vc)
498 res_close();
499 s = socket(PF_INET, SOCK_DGRAM, 0);
500 if (s < 0) {
501#if !CAN_RECONNECT
502 bad_dg_sock:
503#endif
504 terrno = errno;
505 Perror(stderr, "socket(dg)", errno);
506 return (-1);
507 }
508 connected = 0;
509 }
510 /*
511 * On a 4.3BSD+ machine (client and server,
512 * actually), sending to a nameserver datagram
513 * port with no nameserver will cause an
514 * ICMP port unreachable message to be returned.
515 * If our datagram socket is "connected" to the
516 * server, we get an ECONNREFUSED error on the next
517 * socket operation, and select returns if the
518 * error message is received. We can thus detect
519 * the absence of a nameserver without timing out.
520 * If we have sent queries to at least two servers,
521 * however, we don't want to remain connected,
522 * as we wish to receive answers from the first
523 * server to respond.
524 */
525 if (_res.nscount == 1 || (try == 0 && ns == 0)) {
526 /*
527 * Connect only if we are sure we won't
528 * receive a response from another server.
529 */
530 if (!connected) {
531 if (connect(s, (struct sockaddr *)nsap,
532 sizeof(struct sockaddr)
533 ) < 0) {
534 Aerror(stderr,
535 "connect(dg)",
536 errno, *nsap);
537 badns |= (1 << ns);
538 res_close();
539 goto next_ns;
540 }
541 connected = 1;
542 }
543 if (send(s, (char*)buf, buflen, 0) != buflen) {
544 Perror(stderr, "send", errno);
545 badns |= (1 << ns);
546 res_close();
547 goto next_ns;
548 }
549 } else {
550 /*
551 * Disconnect if we want to listen
552 * for responses from more than one server.
553 */
554 if (connected) {
555#if CAN_RECONNECT
556 struct sockaddr_in no_addr;
557
558 no_addr.sin_family = AF_INET;
559 no_addr.sin_addr.s_addr = INADDR_ANY;
560 no_addr.sin_port = 0;
561 (void) connect(s,
562 (struct sockaddr *)
563 &no_addr,
564 sizeof(no_addr));
565#else
566 int s1 = socket(PF_INET, SOCK_DGRAM,0);
567 if (s1 < 0)
568 goto bad_dg_sock;
569 (void) dup2(s1, s);
570 (void) close(s1);
571 Dprint(_res.options & RES_DEBUG,
572 (stdout, ";; new DG socket\n"))
573#endif
574 connected = 0;
575 errno = 0;
576 }
577 if (sendto(s, (char*)buf, buflen, 0,
578 (struct sockaddr *)nsap,
579 sizeof(struct sockaddr))
580 != buflen) {
581 Aerror(stderr, "sendto", errno, *nsap);
582 badns |= (1 << ns);
583 res_close();
584 goto next_ns;
585 }
586 }
587
588 /*
589 * Wait for reply
590 */
591 timeout.tv_sec = (_res.retrans << try);
592 if (try > 0)
593 timeout.tv_sec /= _res.nscount;
594 if ((long) timeout.tv_sec <= 0)
595 timeout.tv_sec = 1;
596 timeout.tv_usec = 0;
597 wait:
598 dsmaskp = (fd_set *)calloc(howmany(s+1, NFDBITS),
599 sizeof(fd_mask));
600 if (dsmaskp == NULL) {
601 res_close();
602 goto next_ns;
603 }
604 FD_SET(s, dsmaskp);
605 n = select(s+1, dsmaskp, (fd_set *)NULL,
606 (fd_set *)NULL, &timeout);
607 free(dsmaskp);
608 if (n < 0) {
609 if (errno == EINTR)
610 goto wait;
611 Perror(stderr, "select", errno);
612 res_close();
613 goto next_ns;
614 }
615 if (n == 0) {
616 /*
617 * timeout
618 */
619 Dprint(_res.options & RES_DEBUG,
620 (stdout, ";; timeout\n"));
621 gotsomewhere = 1;
622 res_close();
623 goto next_ns;
624 }
625 errno = 0;
626 fromlen = sizeof(struct sockaddr_in);
627 resplen = recvfrom(s, (char*)ans, anssiz, 0,
628 (struct sockaddr *)&from, &fromlen);
629 if (resplen <= 0) {
630 Perror(stderr, "recvfrom", errno);
631 res_close();
632 goto next_ns;
633 }
634 gotsomewhere = 1;
635 if (hp->id != anhp->id) {
636 /*
637 * response from old query, ignore it.
638 * XXX - potential security hazard could
639 * be detected here.
640 */
641 DprintQ((_res.options & RES_DEBUG) ||
642 (_res.pfcode & RES_PRF_REPLY),
643 (stdout, ";; old answer:\n"),
644 ans, (resplen>anssiz)?anssiz:resplen);
645 goto wait;
646 }
647#if CHECK_SRVR_ADDR
648 if (!(_res.options & RES_INSECURE1) &&
649 !res_isourserver(&from)) {
650 /*
651 * response from wrong server? ignore it.
652 * XXX - potential security hazard could
653 * be detected here.
654 */
655 DprintQ((_res.options & RES_DEBUG) ||
656 (_res.pfcode & RES_PRF_REPLY),
657 (stdout, ";; not our server:\n"),
658 ans, (resplen>anssiz)?anssiz:resplen);
659 goto wait;
660 }
661#endif
662 if (!(_res.options & RES_INSECURE2) &&
663 !res_queriesmatch(buf, buf + buflen,
664 ans, ans + anssiz)) {
665 /*
666 * response contains wrong query? ignore it.
667 * XXX - potential security hazard could
668 * be detected here.
669 */
670 DprintQ((_res.options & RES_DEBUG) ||
671 (_res.pfcode & RES_PRF_REPLY),
672 (stdout, ";; wrong query name:\n"),
673 ans, (resplen>anssiz)?anssiz:resplen);
674 goto wait;
675 }
676 if (anhp->rcode == SERVFAIL ||
677 anhp->rcode == NOTIMP ||
678 anhp->rcode == REFUSED) {
679 DprintQ(_res.options & RES_DEBUG,
680 (stdout, "server rejected query:\n"),
681 ans, (resplen>anssiz)?anssiz:resplen);
682 badns |= (1 << ns);
683 res_close();
684 /* don't retry if called from dig */
685 if (!_res.pfcode)
686 goto next_ns;
687 }
688 if (!(_res.options & RES_IGNTC) && anhp->tc) {
689 /*
690 * get rest of answer;
691 * use TCP with same server.
692 */
693 Dprint(_res.options & RES_DEBUG,
694 (stdout, ";; truncated answer\n"));
695 v_circuit = 1;
696 res_close();
697 goto same_ns;
698 }
699 } /*if vc/dg*/
700 Dprint((_res.options & RES_DEBUG) ||
701 ((_res.pfcode & RES_PRF_REPLY) &&
702 (_res.pfcode & RES_PRF_HEAD1)),
703 (stdout, ";; got answer:\n"));
704 DprintQ((_res.options & RES_DEBUG) ||
705 (_res.pfcode & RES_PRF_REPLY),
706 (stdout, ""),
707 ans, (resplen>anssiz)?anssiz:resplen);
708 /*
709 * If using virtual circuits, we assume that the first server
710 * is preferred over the rest (i.e. it is on the local
711 * machine) and only keep that one open.
712 * If we have temporarily opened a virtual circuit,
713 * or if we haven't been asked to keep a socket open,
714 * close the socket.
715 */
716 if ((v_circuit && (!(_res.options & RES_USEVC) || ns != 0)) ||
717 !(_res.options & RES_STAYOPEN)) {
718 res_close();
719 }
720 if (Rhook) {
721 int done = 0, loops = 0;
722
723 do {
724 res_sendhookact act;
725
726 act = (*Rhook)(nsap, buf, buflen,
727 ans, anssiz, &resplen);
728 switch (act) {
729 case res_goahead:
730 case res_done:
731 done = 1;
732 break;
733 case res_nextns:
734 res_close();
735 goto next_ns;
736 case res_modified:
737 /* give the hook another try */
738 if (++loops < 42) /*doug adams*/
739 break;
740 /*FALLTHROUGH*/
741 case res_error:
742 /*FALLTHROUGH*/
743 default:
744 return (-1);
745 }
746 } while (!done);
747
748 }
749 return (resplen);
750 next_ns: ;
751 } /*foreach ns*/
752 } /*foreach retry*/
753 res_close();
754 if (!v_circuit) {
755 if (!gotsomewhere)
756 errno = ECONNREFUSED; /* no nameservers found */
757 else
758 errno = ETIMEDOUT; /* no answer obtained */
759 } else
760 errno = terrno;
761 return (-1);
762}
763
764/*
765 * This routine is for closing the socket if a virtual circuit is used and
766 * the program wants to close it. This provides support for endhostent()
767 * which expects to close the socket.
768 *
769 * This routine is not expected to be user visible.
770 */
771void
772res_close()
773{
774 if (s >= 0) {
775 (void) close(s);
776 s = -1;
777 connected = 0;
778 vc = 0;
779 }
780}
diff --git a/src/lib/libc/net/resolver.3 b/src/lib/libc/net/resolver.3
new file mode 100644
index 0000000000..98718d448a
--- /dev/null
+++ b/src/lib/libc/net/resolver.3
@@ -0,0 +1,345 @@
1.\" $OpenBSD: resolver.3,v 1.5 1998/09/05 17:41:44 deraadt Exp $
2.\"
3.\" Copyright (c) 1985, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd June 4, 1993
35.Dt RESOLVER 3
36.Os BSD 4.3
37.Sh NAME
38.Nm res_query ,
39.Nm res_search ,
40.Nm res_mkquery ,
41.Nm res_send ,
42.Nm res_init ,
43.Nm dn_comp ,
44.Nm dn_expand
45.Nd resolver routines
46.Sh SYNOPSIS
47.Fd #include <sys/types.h>
48.Fd #include <netinet/in.h>
49.Fd #include <arpa/nameser.h>
50.Fd #include <resolv.h>
51.Fo res_query
52.Fa "char *dname"
53.Fa "int class"
54.Fa "int type"
55.Fa "u_char *answer"
56.Fa "int anslen"
57.Fc
58.Fo res_search
59.Fa "char *dname"
60.Fa "int class"
61.Fa "int type"
62.Fa "u_char *answer"
63.Fa "int anslen"
64.Fc
65.Fo res_mkquery
66.Fa "int op"
67.Fa "char *dname"
68.Fa "int class"
69.Fa "int type"
70.Fa "char *data"
71.Fa "int datalen"
72.Fa "struct rrec *newrr"
73.Fa "char *buf"
74.Fa "int buflen"
75.Fc
76.Fo res_send
77.Fa "char *msg"
78.Fa "int msglen"
79.Fa "char *answer"
80.Fa "int anslen"
81.Fc
82.Fn res_init
83.Fo dn_comp
84.Fa "char *exp_dn"
85.Fa "char *comp_dn"
86.Fa "int length"
87.Fa "char **dnptrs"
88.Fa "char **lastdnptr"
89.Fc
90.Fo dn_expand
91.Fa "u_char *msg"
92.Fa "u_char *eomorig"
93.Fa "u_char *comp_dn"
94.Fa "u_char *exp_dn"
95.Fa "int length"
96.Fc
97.Sh DESCRIPTION
98These routines are used for making, sending and interpreting
99query and reply messages with Internet domain name servers.
100.Pp
101Global configuration and state information that is used by the
102resolver routines is kept in the structure
103.Em _res .
104Most of the values have reasonable defaults and can be ignored.
105Options
106stored in
107.Em _res.options
108are defined in
109.Pa resolv.h
110and are as follows.
111Options are stored as a simple bit mask containing the bitwise ``or''
112of the options enabled.
113.Bl -tag -width RES_USE_INET6
114.It Dv RES_INIT
115True if the initial name server address and default domain name are
116initialized (i.e.,
117.Fn res_init
118has been called).
119.It Dv RES_DEBUG
120Print debugging messages.
121.It Dv RES_AAONLY
122Accept authoritative answers only.
123With this option,
124.Fn res_send
125should continue until it finds an authoritative answer or finds an error.
126Currently this is not implemented.
127.It Dv RES_USEVC
128Use
129.Tn TCP
130connections for queries instead of
131.Tn UDP
132datagrams.
133.It Dv RES_STAYOPEN
134Used with
135.Dv RES_USEVC
136to keep the
137.Tn TCP
138connection open between
139queries.
140This is useful only in programs that regularly do many queries.
141.Tn UDP
142should be the normal mode used.
143.It Dv RES_IGNTC
144Unused currently (ignore truncation errors, i.e., don't retry with
145.Tn TCP ) .
146.It Dv RES_RECURSE
147Set the recursion-desired bit in queries.
148This is the default.
149.Pf ( Fn res_send
150does not do iterative queries and expects the name server
151to handle recursion.)
152.It Dv RES_DEFNAMES
153If set,
154.Fn res_search
155will append the default domain name to single-component names
156(those that do not contain a dot).
157This option is enabled by default.
158.It Dv RES_DNSRCH
159If this option is set,
160.Fn res_search
161will search for host names in the current domain and in parent domains; see
162.Xr hostname 7 .
163This is used by the standard host lookup routine
164.Xr gethostbyname 3 .
165This option is enabled by default.
166.It Dv RES_USE_INET6
167Enable support for IPv6 addresses.
168.El
169.Pp
170The
171.Fn res_init
172routine
173reads the configuration file (if any; see
174.Xr resolv.conf 5 )
175to get the default domain name,
176search list and
177the Internet address of the local name server(s).
178If no server is configured, the host running
179the resolver is tried.
180The current domain name is defined by the hostname
181if not specified in the configuration file;
182it can be overridden by the environment variable
183.Ev LOCALDOMAIN .
184This environment variable may contain several blank-separated
185tokens if you wish to override the
186.Fa search list
187on a per-process basis.
188This is similar to the
189.Fa search
190command in the configuration file.
191Another environment variable
192.Ev RES_OPTIONS
193can be set to override certain internal resolver options which
194are otherwise set by changing fields in the
195.Fa _res
196structure or are inherited from the configuration file's
197.Fa options
198command.
199The syntax of the
200.Ev RES_OPTIONS
201environment variable is explained in
202.Xr resolv.conf 5 .
203Initialization normally occurs on the first call
204to one of the following routines.
205.Pp
206The
207.Fn res_query
208function provides an interface to the server query mechanism.
209It constructs a query, sends it to the local server,
210awaits a response, and makes preliminary checks on the reply.
211The query requests information of the specified
212.Fa type
213and
214.Fa class
215for the specified fully-qualified domain name
216.Fa dname .
217The reply message is left in the
218.Fa answer
219buffer with length
220.Fa anslen
221supplied by the caller.
222.Pp
223The
224.Fn res_search
225routine makes a query and awaits a response like
226.Fn res_query ,
227but in addition, it implements the default and search rules
228controlled by the
229.Dv RES_DEFNAMES
230and
231.Dv RES_DNSRCH
232options.
233It returns the first successful reply.
234.Pp
235The remaining routines are lower-level routines used by
236.Fn res_query .
237The
238.Fn res_mkquery
239function
240constructs a standard query message and places it in
241.Fa buf .
242It returns the size of the query, or \-1 if the query is
243larger than
244.Fa buflen .
245The query type
246.Fa op
247is usually
248.Dv QUERY ,
249but can be any of the query types defined in
250.Aq Pa arpa/nameser.h .
251The domain name for the query is given by
252.Fa dname .
253.Fa Newrr
254is currently unused but is intended for making update messages.
255.Pp
256The
257.Fn res_send
258routine
259sends a pre-formatted query and returns an answer.
260It will call
261.Fn res_init
262if
263.Dv RES_INIT
264is not set, send the query to the local name server, and
265handle timeouts and retries.
266The length of the reply message is returned, or
267\-1 if there were errors.
268.Pp
269The
270.Fn dn_comp
271function
272compresses the domain name
273.Fa exp_dn
274and stores it in
275.Fa comp_dn .
276The size of the compressed name is returned or \-1 if there were errors.
277The size of the array pointed to by
278.Fa comp_dn
279is given by
280.Fa length .
281The compression uses
282an array of pointers
283.Fa dnptrs
284to previously-compressed names in the current message.
285The first pointer points
286to the beginning of the message and the list ends with
287.Dv NULL .
288The limit to the array is specified by
289.Fa lastdnptr .
290A side effect of
291.Fn dn_comp
292is to update the list of pointers for
293labels inserted into the message
294as the name is compressed.
295If
296.Em dnptr
297is
298.Dv NULL, names are not compressed.
299If
300.Fa lastdnptr
301is
302.Dv NULL ,
303the list of labels is not updated.
304.Pp
305The
306.Fn dn_expand
307entry
308expands the compressed domain name
309.Fa comp_dn
310to a full domain name
311The compressed name is contained in a query or reply message;
312.Fa msg
313is a pointer to the beginning of the message.
314The uncompressed name is placed in the buffer indicated by
315.Fa exp_dn
316which is of size
317.Fa length .
318The size of compressed name is returned or \-1 if there was an error.
319.Sh FILES
320.Bl -tag -width Pa
321/etc/resolv.conf
322The configuration file
323see
324.Xr resolv.conf 5 .
325.El
326.Sh SEE ALSO
327.Xr gethostbyname 3 ,
328.Xr named 8 ,
329.Xr resolv.conf 5 ,
330.Xr hostname 7 ,
331.Pp
332.%T RFC1032 ,
333.%T RFC1033 ,
334.%T RFC1034 ,
335.%T RFC1035 ,
336.%T RFC1535 ,
337.%T RFC974
338.Rs
339.%T "Name Server Operations Guide for BIND"
340.Re
341.Sh HISTORY
342The
343.Nm
344function appeared in
345.Bx 4.3 .
diff --git a/src/lib/libc/net/send.c b/src/lib/libc/net/send.c
new file mode 100644
index 0000000000..8495931ca3
--- /dev/null
+++ b/src/lib/libc/net/send.c
@@ -0,0 +1,50 @@
1/*
2 * Copyright (c) 1988, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: send.c,v 1.2 1996/08/19 08:29:52 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/types.h>
39#include <sys/socket.h>
40
41#include <stddef.h>
42
43ssize_t
44send(s, msg, len, flags)
45 int s, flags;
46 size_t len;
47 const void *msg;
48{
49 return (sendto(s, msg, len, flags, NULL, 0));
50}
diff --git a/src/lib/libc/net/sethostent.c b/src/lib/libc/net/sethostent.c
new file mode 100644
index 0000000000..5392a2f11b
--- /dev/null
+++ b/src/lib/libc/net/sethostent.c
@@ -0,0 +1,60 @@
1/*
2 * Copyright (c) 1985, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: sethostent.c,v 1.4 1997/03/15 21:53:50 pefo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/param.h>
39#include <netinet/in.h>
40#include <arpa/nameser.h>
41#include <netdb.h>
42#include <resolv.h>
43
44void
45sethostent(stayopen)
46 int stayopen;
47{
48
49 if ((_res.options & RES_INIT) == 0 && res_init() == -1)
50 return;
51 if (stayopen)
52 _res.options |= RES_STAYOPEN | RES_USEVC;
53}
54
55void
56endhostent()
57{
58 _res.options &= ~(RES_STAYOPEN | RES_USEVC);
59 res_close();
60}
diff --git a/src/lib/libc/stdlib/Makefile.inc b/src/lib/libc/stdlib/Makefile.inc
new file mode 100644
index 0000000000..e75fc0d8bf
--- /dev/null
+++ b/src/lib/libc/stdlib/Makefile.inc
@@ -0,0 +1,54 @@
1# $OpenBDS: Makefile.inc,v 1.6 1996/08/21 03:47:21 tholo Exp $
2
3# stdlib sources
4.PATH: ${.CURDIR}/arch/${MACHINE_ARCH}/stdlib ${.CURDIR}/stdlib
5
6SRCS+= a64l.c abort.c atexit.c atoi.c atof.c atol.c bsearch.c calloc.c \
7 cfree.c exit.c getenv.c getopt.c getsubopt.c heapsort.c l64a.c \
8 malloc.c merge.c multibyte.c putenv.c qsort.c radixsort.c rand.c \
9 random.c realpath.c setenv.c strtod.c strtol.c strtoq.c strtoul.c \
10 strtouq.c system.c tfind.c tsearch.c \
11 _rand48.c drand48.c erand48.c jrand48.c lcong48.c lrand48.c \
12 mrand48.c nrand48.c seed48.c srand48.c qabs.c qdiv.c
13
14.if (${MACHINE_ARCH} == "m68k")
15SRCS+= abs.S div.c labs.c ldiv.c
16LSRCS+= abs.c
17.elif (${MACHINE_ARCH} == "i386")
18SRCS+= abs.S div.S labs.S ldiv.S
19LSRCS+= abs.c div.c labs.c ldiv.c
20.elif (${MACHINE_ARCH} == "ns32k")
21SRCS+= abs.S div.c labs.c ldiv.c
22LSRCS+= abs.c
23.elif (${MACHINE_ARCH} == "tahoe")
24SRCS+= abs.S div.c labs.c ldiv.c
25LSRCS+= abs.c
26.elif (${MACHINE_ARCH} == "vax")
27SRCS+= abs.c div.c labs.c ldiv.c
28.elif (${MACHINE_ARCH} == "alpha")
29# XXX should be .S's
30SRCS+= abs.c div.c labs.c ldiv.c
31.else
32SRCS+= abs.c div.c labs.c ldiv.c
33.endif
34
35MAN+= a64l.3 abort.3 abs.3 alloca.3 atexit.3 atof.3 atoi.3 atol.3 bsearch.3 \
36 calloc.3 div.3 exit.3 getenv.3 getopt.3 getsubopt.3 labs.3 ldiv.3 \
37 malloc.3 memory.3 qabs.3 qdiv.3 qsort.3 radixsort.3 rand48.3 rand.3 \
38 random.3 realpath.3 strtod.3 strtol.3 strtoul.3 system.3 tsearch.3
39
40MLINKS+=getenv.3 setenv.3 getenv.3 unsetenv.3 getenv.3 putenv.3
41MLINKS+=malloc.3 free.3 malloc.3 realloc.3
42MLINKS+=malloc.3 cfree.3
43MLINKS+=qsort.3 heapsort.3 qsort.3 mergesort.3
44MLINKS+=rand.3 srand.3
45MLINKS+=random.3 initstate.3 random.3 setstate.3 random.3 srandom.3
46MLINKS+=rand48.3 drand48.3 rand48.3 erand48.3 rand48.3 lrand48.3
47MLINKS+=rand48.3 mrand48.3 rand48.3 nrand48.3 rand48.3 jrand48.3
48MLINKS+=rand48.3 srand48.3 rand48.3 seed48.3 rand48.3 lcong48.3
49MLINKS+=strtol.3 strtoq.3
50MLINKS+=strtoul.3 strtouq.3
51MLINKS+=tsearch.3 tfind.3
52MLINKS+=tsearch.3 tdelete.3
53MLINKS+=tsearch.3 twalk.3
54MLINKS+=a64l.3 l64a.3
diff --git a/src/lib/libc/stdlib/_rand48.c b/src/lib/libc/stdlib/_rand48.c
new file mode 100644
index 0000000000..fed7372f68
--- /dev/null
+++ b/src/lib/libc/stdlib/_rand48.c
@@ -0,0 +1,50 @@
1/*
2 * Copyright (c) 1993 Martin Birgmeier
3 * All rights reserved.
4 *
5 * You may redistribute unmodified or modified versions of this source
6 * code provided that the above copyright notice and this and the
7 * following conditions are retained.
8 *
9 * This software is provided ``as is'', and comes with no warranties
10 * of any kind. I shall in no event be liable for anything that happens
11 * to anyone/anything when using this software.
12 */
13
14#if defined(LIBC_SCCS) && !defined(lint)
15static char rcsid[] = "$OpenBSD: _rand48.c,v 1.2 1996/08/19 08:33:19 tholo Exp $";
16#endif /* LIBC_SCCS and not lint */
17
18#include "rand48.h"
19
20unsigned short __rand48_seed[3] = {
21 RAND48_SEED_0,
22 RAND48_SEED_1,
23 RAND48_SEED_2
24};
25unsigned short __rand48_mult[3] = {
26 RAND48_MULT_0,
27 RAND48_MULT_1,
28 RAND48_MULT_2
29};
30unsigned short __rand48_add = RAND48_ADD;
31
32void
33__dorand48(unsigned short xseed[3])
34{
35 unsigned long accu;
36 unsigned short temp[2];
37
38 accu = (unsigned long) __rand48_mult[0] * (unsigned long) xseed[0] +
39 (unsigned long) __rand48_add;
40 temp[0] = (unsigned short) accu; /* lower 16 bits */
41 accu >>= sizeof(unsigned short) * 8;
42 accu += (unsigned long) __rand48_mult[0] * (unsigned long) xseed[1] +
43 (unsigned long) __rand48_mult[1] * (unsigned long) xseed[0];
44 temp[1] = (unsigned short) accu; /* middle 16 bits */
45 accu >>= sizeof(unsigned short) * 8;
46 accu += __rand48_mult[0] * xseed[2] + __rand48_mult[1] * xseed[1] + __rand48_mult[2] * xseed[0];
47 xseed[0] = temp[0];
48 xseed[1] = temp[1];
49 xseed[2] = (unsigned short) accu;
50}
diff --git a/src/lib/libc/stdlib/a64l.3 b/src/lib/libc/stdlib/a64l.3
new file mode 100644
index 0000000000..4ec707adf1
--- /dev/null
+++ b/src/lib/libc/stdlib/a64l.3
@@ -0,0 +1,122 @@
1.\"
2.\" Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
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 not be used to endorse or promote products
14.\" derived from this software without specific prior written permission.
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.\" $OpenBSD: a64l.3,v 1.2 1998/06/21 22:13:48 millert Exp $
28.\"
29.Dd August 17, 1997
30.Dt A64L 3
31.Os
32.Sh NAME
33.Nm a64l ,
34.Nm l64a
35.Nd convert between 32-bit integer and radix-64 ASCII string
36.Sh SYNOPSIS
37.Fd #include <stdlib.h>
38.Ft long
39.Fn a64l "const char *s"
40.Ft char *
41.Fn l64a "long l"
42.Sh DESCRIPTION
43The
44.Fn a64l
45and
46.Fn l64a
47functions are used to maintain numbers stored in radix-64
48ASCII characters. This is a notation by which 32-bit integers
49can be represented by up to six characters; each character
50represents a "digit" in a radix-64 notation.
51.Pp
52The characters used to represent "digits" are '.' for 0, '/' for 1,
53'0' through '9' for 2-11, 'A' through 'Z' for 12-37, and 'a' through
54'z' for 38-63.
55.Pp
56The
57.Fn a64l
58function takes a pointer to a null-terminated radix-64 representation
59and returns a corresponding 32-bit value. If the string pointed to by
60.Ar s
61contains more than six characters,
62.Fn a64l
63will use the first six.
64.Fn A64l
65scans the character string from left to right, decoding
66each character as a 6-bit radix-64 number. If a long integer is
67larger than 32 bits, the return value will be sign-extended.
68.Pp
69.Fn l64a
70takes a long integer argument
71.Ar l
72and returns a pointer to the corresponding radix-64 representation.
73.Sh RETURN VALUES
74On success,
75.Fn a64l
76returns a 32-bit representation of
77.Ar s .
78If
79.Ar s
80is a NULL pointer or if it contains "digits" other than those described above,
81.Fn a64l
82returns -1L and sets the global variable errno to
83.Va EINVAL .
84.Pp
85On success,
86.Fn l64a
87returns a pointer to a string containing the radix-64 representation of
88.Ar l .
89If
90.Ar l
91is 0,
92.Fn l64a
93returns a pointer to the empty string.
94If
95.Ar l
96is negative,
97.Fn l64a
98returns a NULL pointer and sets the global variable errno to
99.Va EINVAL .
100.Sh WARNINGS
101The value returned by
102.Fn l64a
103is a pointer into a static buffer, the contents of which
104will be overwritten by subsequent calls.
105.Pp
106The value returned by
107.Fn a64l
108may be incorrect if the value is too large; for that reason, only strings
109that resulted from a call to
110.Fn l64a
111should be used to call
112.Fn a64l .
113.Pp
114If a long integer is larger than 32 bits, only the low-order
11532 bits are used.
116.Sh STANDARDS
117The
118.Fn a64l
119and
120.Fn l64a
121functions conform to
122.St -xpg4.2 .
diff --git a/src/lib/libc/stdlib/a64l.c b/src/lib/libc/stdlib/a64l.c
new file mode 100644
index 0000000000..a68f0a6dcd
--- /dev/null
+++ b/src/lib/libc/stdlib/a64l.c
@@ -0,0 +1,46 @@
1/*
2 * Written by J.T. Conklin <jtc@netbsd.org>.
3 * Public domain.
4 */
5
6#if defined(LIBC_SCCS) && !defined(lint)
7static char *rcsid = "$OpenBSD: a64l.c,v 1.3 1997/08/17 22:58:34 millert Exp $";
8#endif /* LIBC_SCCS and not lint */
9
10#include <errno.h>
11#include <stdlib.h>
12
13long
14a64l(s)
15 const char *s;
16{
17 long value, digit, shift;
18 int i;
19
20 if (s == NULL) {
21 errno = EINVAL;
22 return(-1L);
23 }
24
25 value = 0;
26 shift = 0;
27 for (i = 0; *s && i < 6; i++, s++) {
28 if (*s >= '.' && *s <= '/')
29 digit = *s - '.';
30 else if (*s >= '0' && *s <= '9')
31 digit = *s - '0' + 2;
32 else if (*s >= 'A' && *s <= 'Z')
33 digit = *s - 'A' + 12;
34 else if (*s >= 'a' && *s <= 'z')
35 digit = *s - 'a' + 38;
36 else {
37 errno = EINVAL;
38 return(-1L);
39 }
40
41 value |= digit << shift;
42 shift += 6;
43 }
44
45 return(value);
46}
diff --git a/src/lib/libc/stdlib/abort.3 b/src/lib/libc/stdlib/abort.3
new file mode 100644
index 0000000000..92c9a354d0
--- /dev/null
+++ b/src/lib/libc/stdlib/abort.3
@@ -0,0 +1,70 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: abort.3,v 1.4 1997/07/17 07:39:41 deraadt Exp $
37.\"
38.Dd June 29, 1991
39.Dt ABORT 3
40.Os
41.Sh NAME
42.Nm abort
43.Nd cause abnormal program termination
44.Sh SYNOPSIS
45.Fd #include <stdlib.h>
46.Ft void
47.Fn abort void
48.Sh DESCRIPTION
49The
50.Fn abort
51function causes abnormal program termination to occur, unless the
52signal
53.Dv SIGABRT
54is being caught and the signal handler does not return.
55.Pp
56Any open streams are flushed and closed.
57.Sh RETURN VALUES
58The
59.Nm abort
60function
61never returns.
62.Sh SEE ALSO
63.Xr sigaction 2 ,
64.Xr exit 3
65.Sh STANDARDS
66The
67.Fn abort
68function
69conforms to
70.St -p1003.1-90 .
diff --git a/src/lib/libc/stdlib/abort.c b/src/lib/libc/stdlib/abort.c
new file mode 100644
index 0000000000..4ea8a2ca4b
--- /dev/null
+++ b/src/lib/libc/stdlib/abort.c
@@ -0,0 +1,77 @@
1/*
2 * Copyright (c) 1985 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: abort.c,v 1.5 1997/06/22 20:21:25 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <signal.h>
39#include <stdlib.h>
40#include <unistd.h>
41
42void (*__cleanup)();
43
44void
45abort()
46{
47 static int cleanup_called = 0;
48 sigset_t mask;
49
50
51 sigfillset(&mask);
52 /*
53 * don't block SIGABRT to give any handler a chance; we ignore
54 * any errors -- X311J doesn't allow abort to return anyway.
55 */
56 sigdelset(&mask, SIGABRT);
57 (void)sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL);
58
59 /*
60 * POSIX requires we flush stdio buffers on abort
61 */
62 if (cleanup_called == 0 && __cleanup != NULL) {
63 cleanup_called = 1;
64 (*__cleanup)();
65 }
66
67 (void)kill(getpid(), SIGABRT);
68
69 /*
70 * if SIGABRT ignored, or caught and the handler returns, do
71 * it again, only harder.
72 */
73 (void)signal(SIGABRT, SIG_DFL);
74 (void)sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL);
75 (void)kill(getpid(), SIGABRT);
76 exit(1);
77}
diff --git a/src/lib/libc/stdlib/abs.3 b/src/lib/libc/stdlib/abs.3
new file mode 100644
index 0000000000..77f82b9402
--- /dev/null
+++ b/src/lib/libc/stdlib/abs.3
@@ -0,0 +1,73 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: abs.3,v 1.2 1996/08/19 08:33:21 tholo Exp $
37.\"
38.Dd June 29, 1991
39.Dt ABS 3
40.Os
41.Sh NAME
42.Nm abs
43.Nd integer absolute value function
44.Sh SYNOPSIS
45.Fd #include <stdlib.h>
46.Ft int
47.Fn abs "int j"
48.Sh DESCRIPTION
49The
50.Fn abs
51function
52computes
53the absolute value of the integer
54.Ar j .
55.Sh RETURN VALUES
56The
57.Fn abs
58function
59returns
60the absolute value.
61.Sh SEE ALSO
62.Xr floor 3 ,
63.Xr labs 3 ,
64.Xr cabs 3 ,
65.Xr hypot 3 ,
66.Xr math 3
67.Sh STANDARDS
68The
69.Fn abs
70function conforms to
71.St -ansiC .
72.Sh BUGS
73The absolute value of the most negative integer remains negative.
diff --git a/src/lib/libc/stdlib/abs.c b/src/lib/libc/stdlib/abs.c
new file mode 100644
index 0000000000..7c79e4073c
--- /dev/null
+++ b/src/lib/libc/stdlib/abs.c
@@ -0,0 +1,45 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: abs.c,v 1.2 1996/08/19 08:33:21 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <stdlib.h>
39
40int
41abs(j)
42 int j;
43{
44 return(j < 0 ? -j : j);
45}
diff --git a/src/lib/libc/stdlib/alloca.3 b/src/lib/libc/stdlib/alloca.3
new file mode 100644
index 0000000000..ef87220772
--- /dev/null
+++ b/src/lib/libc/stdlib/alloca.3
@@ -0,0 +1,75 @@
1.\" Copyright (c) 1980, 1991 Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\" notice, this list of conditions and the following disclaimer.
9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\" notice, this list of conditions and the following disclaimer in the
11.\" documentation and/or other materials provided with the distribution.
12.\" 3. All advertising materials mentioning features or use of this software
13.\" must display the following acknowledgement:
14.\" This product includes software developed by the University of
15.\" California, Berkeley and its contributors.
16.\" 4. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" $OpenBSD: alloca.3,v 1.3 1996/08/19 08:33:22 tholo Exp $
33.\"
34.Dd May 2, 1991
35.Dt ALLOCA 3
36.Os BSD 4
37.Sh NAME
38.Nm alloca
39.Nd memory allocator
40.Sh SYNOPSIS
41.Fd #include <stdlib.h>
42.Ft void *
43.Fn alloca "size_t size"
44.Sh DESCRIPTION
45The
46.Fn alloca
47function
48allocates
49.Fa size
50bytes of space in the stack frame of the caller.
51This temporary space is automatically freed on
52return.
53.Sh RETURN VALUES
54The
55.Fn alloca
56function returns a pointer to the beginning of the allocated space.
57.Sh SEE ALSO
58.Xr brk 2 ,
59.Xr pagesize 2
60.Xr calloc 3 ,
61.Xr malloc 3 ,
62.Xr realloc 3 ,
63.Sh BUGS
64The
65.Fn alloca
66function
67is machine dependent; its use is discouraged.
68.\" .Sh HISTORY
69.\" The
70.\" .Fn alloca
71.\" function appeared in
72.\" .Bx ?? .
73.\" The function appeared in 32v, pwb and pwb.2 and in 3bsd 4bsd
74.\" The first man page (or link to a man page that I can find at the
75.\" moment is 4.3...
diff --git a/src/lib/libc/stdlib/atexit.3 b/src/lib/libc/stdlib/atexit.3
new file mode 100644
index 0000000000..0b10f010fa
--- /dev/null
+++ b/src/lib/libc/stdlib/atexit.3
@@ -0,0 +1,77 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: atexit.3,v 1.2 1996/08/19 08:33:22 tholo Exp $
37.\"
38.Dd June 29, 1991
39.Dt ATEXIT 3
40.Os
41.Sh NAME
42.Nm atexit
43.Nd register a function to be called on exit
44.Sh SYNOPSIS
45.Fd #include <stdlib.h>
46.Ft int
47.Fn atexit "void (*function)(void)"
48.Sh DESCRIPTION
49The
50.Fn atexit
51function
52registers the given
53.Ar function
54to be called at program exit, whether via
55.Xr exit 3
56or via return from the program's
57.Em main .
58Functions so registered are called in reverse order;
59no arguments are passed.
60At least 32 functions can always be registered,
61and more are allowed as long as sufficient memory can be allocated.
62.Sh RETURN VALUES
63.Rv -std atexit
64.Sh ERRORS
65.Bl -tag -width Er
66.It Bq Er ENOMEM
67No memory was available to add the function to the list.
68The existing list of functions is unmodified.
69.El
70.Sh SEE ALSO
71.Xr exit 3
72.Sh STANDARDS
73The
74.Fn atexit
75function
76conforms to
77.St -ansiC .
diff --git a/src/lib/libc/stdlib/atexit.c b/src/lib/libc/stdlib/atexit.c
new file mode 100644
index 0000000000..c0fb624141
--- /dev/null
+++ b/src/lib/libc/stdlib/atexit.c
@@ -0,0 +1,67 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Chris Torek.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: atexit.c,v 1.2 1996/08/19 08:33:22 tholo Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#include <stdlib.h>
42#include "atexit.h"
43
44struct atexit *__atexit;
45
46/*
47 * Register a function to be performed at exit.
48 */
49int
50atexit(fn)
51 void (*fn)();
52{
53 static struct atexit __atexit0; /* one guaranteed table */
54 register struct atexit *p;
55
56 if ((p = __atexit) == NULL)
57 __atexit = p = &__atexit0;
58 else if (p->ind >= ATEXIT_SIZE) {
59 if ((p = malloc(sizeof(*p))) == NULL)
60 return (-1);
61 p->ind = 0;
62 p->next = __atexit;
63 __atexit = p;
64 }
65 p->fns[p->ind++] = fn;
66 return (0);
67}
diff --git a/src/lib/libc/stdlib/atexit.h b/src/lib/libc/stdlib/atexit.h
new file mode 100644
index 0000000000..e41a7cb86c
--- /dev/null
+++ b/src/lib/libc/stdlib/atexit.h
@@ -0,0 +1,45 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * $OpenBSD: atexit.h,v 1.2 1996/08/19 08:33:23 tholo Exp $
34 */
35
36/* must be at least 32 to guarantee ANSI conformance */
37#define ATEXIT_SIZE 32
38
39struct atexit {
40 struct atexit *next; /* next in list */
41 int ind; /* next index in this table */
42 void (*fns[ATEXIT_SIZE])(); /* the table itself */
43};
44
45extern struct atexit *__atexit; /* points to head of LIFO stack */
diff --git a/src/lib/libc/stdlib/atof.3 b/src/lib/libc/stdlib/atof.3
new file mode 100644
index 0000000000..cc1b500b0f
--- /dev/null
+++ b/src/lib/libc/stdlib/atof.3
@@ -0,0 +1,73 @@
1.\" Copyright (c) 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: atof.3,v 1.2 1996/08/19 08:33:23 tholo Exp $
37.\"
38.Dd June 29, 1991
39.Dt ATOF 3
40.Os
41.Sh NAME
42.Nm atof
43.Nd convert
44.Tn ASCII
45string to double
46.Sh SYNOPSIS
47.Fd #include <stdlib.h>
48.Ft double
49.Fn atof "const char *nptr"
50.Sh DESCRIPTION
51The
52.Fn atof
53function converts the initial portion of the string pointed to by
54.Ar nptr
55to
56.Ar double
57representation.
58.Pp
59It is equivalent to:
60.Bd -literal -offset indent
61strtod(nptr, (char **)NULL);
62.Ed
63.Sh SEE ALSO
64.Xr atoi 3 ,
65.Xr atol 3 ,
66.Xr strtod 3 ,
67.Xr strtol 3 ,
68.Xr strtoul 3
69.Sh STANDARDS
70The
71.Fn atof
72function conforms to
73.St -ansiC .
diff --git a/src/lib/libc/stdlib/atof.c b/src/lib/libc/stdlib/atof.c
new file mode 100644
index 0000000000..30bac19899
--- /dev/null
+++ b/src/lib/libc/stdlib/atof.c
@@ -0,0 +1,45 @@
1/*
2 * Copyright (c) 1988 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: atof.c,v 1.2 1996/08/19 08:33:24 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <stdlib.h>
39
40double
41atof(ascii)
42 const char *ascii;
43{
44 return(strtod(ascii, (char **)NULL));
45}
diff --git a/src/lib/libc/stdlib/atoi.3 b/src/lib/libc/stdlib/atoi.3
new file mode 100644
index 0000000000..280a989e8e
--- /dev/null
+++ b/src/lib/libc/stdlib/atoi.3
@@ -0,0 +1,73 @@
1.\" Copyright (c) 1990, 1991, 1993
2.\" The Regents of the University of California. All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: atoi.3,v 1.2 1996/08/10 04:51:31 tholo Exp $
37.\"
38.Dd June 4, 1993
39.Dt ATOI 3
40.Os
41.Sh NAME
42.Nm atoi
43.Nd convert
44.Tn ASCII
45string to integer
46.Sh SYNOPSIS
47.Fd #include <stdlib.h>
48.Ft int
49.Fn atoi "const char *nptr"
50.Sh DESCRIPTION
51The
52.Fn atoi
53function converts the initial portion of the string pointed to by
54.Em nptr
55to
56.Em integer
57representation.
58.Pp
59It is equivalent to:
60.Bd -literal -offset indent
61(int)strtol(nptr, (char **)NULL, 10);
62.Ed
63.Sh SEE ALSO
64.Xr atof 3 ,
65.Xr atol 3 ,
66.Xr strtod 3 ,
67.Xr strtol 3 ,
68.Xr strtoul 3
69.Sh STANDARDS
70The
71.Fn atoi
72function conforms to
73.St -ansiC .
diff --git a/src/lib/libc/stdlib/atoi.c b/src/lib/libc/stdlib/atoi.c
new file mode 100644
index 0000000000..a74d6e1351
--- /dev/null
+++ b/src/lib/libc/stdlib/atoi.c
@@ -0,0 +1,45 @@
1/*
2 * Copyright (c) 1988 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: atoi.c,v 1.2 1996/08/19 08:33:24 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <stdlib.h>
39
40int
41atoi(str)
42 const char *str;
43{
44 return((int)strtol(str, (char **)NULL, 10));
45}
diff --git a/src/lib/libc/stdlib/atol.3 b/src/lib/libc/stdlib/atol.3
new file mode 100644
index 0000000000..2b49bd1f2c
--- /dev/null
+++ b/src/lib/libc/stdlib/atol.3
@@ -0,0 +1,74 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: atol.3,v 1.2 1996/08/19 08:33:25 tholo Exp $
37.\"
38.Dd June 29, 1991
39.Dt ATOL 3
40.Os
41.Sh NAME
42.Nm atol
43.Nd convert
44.Tn ASCII
45string to long integer
46.Sh SYNOPSIS
47.Fd #include <stdlib.h>
48.Ft long
49.Fn atol "const char *nptr"
50.Sh DESCRIPTION
51The
52.Fn atol
53function converts the initial portion of the string pointed to by
54.Ar nptr
55to
56.Em long integer
57representation.
58.Pp
59It is equivalent to:
60.Bd -literal -offset indent
61strtol(nptr, (char **)NULL, 10);
62.Ed
63.Sh SEE ALSO
64.Xr atof 3 ,
65.Xr atoi 3 ,
66.Xr strtod 3 ,
67.Xr strtol 3 ,
68.Xr strtoul 3
69.Sh STANDARDS
70The
71.Fn atol
72function
73conforms to
74.St -ansiC .
diff --git a/src/lib/libc/stdlib/atol.c b/src/lib/libc/stdlib/atol.c
new file mode 100644
index 0000000000..528a932214
--- /dev/null
+++ b/src/lib/libc/stdlib/atol.c
@@ -0,0 +1,45 @@
1/*
2 * Copyright (c) 1988 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: atol.c,v 1.2 1996/08/19 08:33:26 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <stdlib.h>
39
40long
41atol(str)
42 const char *str;
43{
44 return(strtol(str, (char **)NULL, 10));
45}
diff --git a/src/lib/libc/stdlib/bsearch.3 b/src/lib/libc/stdlib/bsearch.3
new file mode 100644
index 0000000000..570a4227b4
--- /dev/null
+++ b/src/lib/libc/stdlib/bsearch.3
@@ -0,0 +1,90 @@
1.\" Copyright (c) 1990, 1991, 1993, 1994
2.\" The Regents of the University of California. All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: bsearch.3,v 1.3 1997/06/13 23:41:35 deraadt Exp $
37.\"
38.Dd April 19, 1994
39.Dt BSEARCH 3
40.Os
41.Sh NAME
42.Nm bsearch
43.Nd binary search of a sorted table
44.Sh SYNOPSIS
45.Fd #include <stdlib.h>
46.Ft void *
47.Fn bsearch "const void *key" "const void *base" "size_t nmemb" "size_t size" "int (*compar) (const void *, const void *)"
48.Sh DESCRIPTION
49The
50.Fn bsearch
51function searches an array of
52.Fa nmemb
53objects, the initial member of which is
54pointed to by
55.Fa base ,
56for a member that matches the object pointed to by
57.Fa key .
58The size of each member of the array is specified by
59.Fa size .
60.Pp
61The contents of the array should be in ascending sorted order according
62to the comparison function referenced by
63.Fa compar .
64The
65.Fa compar
66routine
67is expected to have
68two arguments which point to the
69.Fa key
70object and to an array member, in that order, and should return an integer
71less than, equal to, or greater than zero if the
72.Fa key
73object is found, respectively, to be less than, to match, or be
74greater than the array member.
75.Sh RETURN VALUES
76The
77.Fn bsearch
78function returns a pointer to a matching member of the array, or a null
79pointer if no match is found.
80If two members compare as equal, which member is matched is unspecified.
81.Sh SEE ALSO
82.Xr db 3 ,
83.Xr lsearch 3 ,
84.Xr qsort 3 ,
85.Xr tsearch 3
86.Sh STANDARDS
87The
88.Fn bsearch
89function conforms to
90.St -ansiC .
diff --git a/src/lib/libc/stdlib/bsearch.c b/src/lib/libc/stdlib/bsearch.c
new file mode 100644
index 0000000000..eeef9bffc6
--- /dev/null
+++ b/src/lib/libc/stdlib/bsearch.c
@@ -0,0 +1,79 @@
1/*
2 * Copyright (c) 1990 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: bsearch.c,v 1.2 1996/08/19 08:33:26 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <stdlib.h>
39
40/*
41 * Perform a binary search.
42 *
43 * The code below is a bit sneaky. After a comparison fails, we
44 * divide the work in half by moving either left or right. If lim
45 * is odd, moving left simply involves halving lim: e.g., when lim
46 * is 5 we look at item 2, so we change lim to 2 so that we will
47 * look at items 0 & 1. If lim is even, the same applies. If lim
48 * is odd, moving right again involes halving lim, this time moving
49 * the base up one item past p: e.g., when lim is 5 we change base
50 * to item 3 and make lim 2 so that we will look at items 3 and 4.
51 * If lim is even, however, we have to shrink it by one before
52 * halving: e.g., when lim is 4, we still looked at item 2, so we
53 * have to make lim 3, then halve, obtaining 1, so that we will only
54 * look at item 3.
55 */
56void *
57bsearch(key, base0, nmemb, size, compar)
58 register const void *key;
59 const void *base0;
60 size_t nmemb;
61 register size_t size;
62 register int (*compar) __P((const void *, const void *));
63{
64 register const char *base = base0;
65 register int lim, cmp;
66 register const void *p;
67
68 for (lim = nmemb; lim != 0; lim >>= 1) {
69 p = base + (lim >> 1) * size;
70 cmp = (*compar)(key, p);
71 if (cmp == 0)
72 return ((void *)p);
73 if (cmp > 0) { /* key > p: move right */
74 base = (char *)p + size;
75 lim--;
76 } /* else move left */
77 }
78 return (NULL);
79}
diff --git a/src/lib/libc/stdlib/calloc.3 b/src/lib/libc/stdlib/calloc.3
new file mode 100644
index 0000000000..13a912169c
--- /dev/null
+++ b/src/lib/libc/stdlib/calloc.3
@@ -0,0 +1,70 @@
1.\" Copyright (c) 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: calloc.3,v 1.3 1996/12/10 09:06:10 deraadt Exp $
37.\"
38.Dd June 29, 1991
39.Dt CALLOC 3
40.Os
41.Sh NAME
42.Nm calloc
43.Nd allocate clean memory (zero initialized space)
44.Sh SYNOPSIS
45.Fd #include <stdlib.h>
46.Ft void *
47.Fn calloc "size_t nmemb" "size_t size"
48.Sh DESCRIPTION
49The
50.Fn calloc
51function allocates space for an array of
52.Fa nmemb
53objects, each of whose size is
54.Fa size .
55The space is initialized to all bits zero.
56.Sh RETURN VALUES
57The
58.Fn calloc
59function returns
60a pointer to
61the allocated space if successful; otherwise a null pointer is returned.
62.Sh SEE ALSO
63.Xr malloc 3 ,
64.Xr realloc 3 ,
65.Xr free 3
66.Sh STANDARDS
67The
68.Fn calloc
69function conforms to
70.St -ansiC .
diff --git a/src/lib/libc/stdlib/calloc.c b/src/lib/libc/stdlib/calloc.c
new file mode 100644
index 0000000000..a2c4f84493
--- /dev/null
+++ b/src/lib/libc/stdlib/calloc.c
@@ -0,0 +1,53 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: calloc.c,v 1.3 1996/08/20 17:42:33 downsj Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <stdlib.h>
39#include <string.h>
40
41void *
42calloc(num, size)
43 size_t num;
44 register size_t size;
45{
46 register void *p;
47
48 size *= num;
49 p = malloc(size);
50 if (p)
51 memset(p, '\0', size);
52 return(p);
53}
diff --git a/src/lib/libc/stdlib/cfree.c b/src/lib/libc/stdlib/cfree.c
new file mode 100644
index 0000000000..3af32039a9
--- /dev/null
+++ b/src/lib/libc/stdlib/cfree.c
@@ -0,0 +1,49 @@
1/* $OpenBSD: cfree.c,v 1.1 1996/08/21 03:47:22 tholo Exp $ */
2
3/*
4 * Copyright (c) 1996 SigmaSoft, Th. Lockert <tholo@sigmasoft.com>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by SigmaSoft, Th. Lockert.
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
22 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
23 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
24 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
30 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#if defined(LIBC_SCCS) && !defined(lint)
34static char rcsid[] = "$OpenBSD: cfree.c,v 1.1 1996/08/21 03:47:22 tholo Exp $";
35#endif /* LIBC_SCCS and not lint */
36
37#include <sys/cdefs.h>
38
39#ifdef __indr_reference
40__indr_reference(free, cfree);
41#else
42
43void
44cfree(p)
45 void *p;
46{
47 free(p);
48}
49#endif
diff --git a/src/lib/libc/stdlib/div.3 b/src/lib/libc/stdlib/div.3
new file mode 100644
index 0000000000..0d8c56d86b
--- /dev/null
+++ b/src/lib/libc/stdlib/div.3
@@ -0,0 +1,69 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek.
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.\" $OpenBSD: div.3,v 1.2 1996/08/19 08:33:28 tholo Exp $
35.\"
36.Dd April 19, 1991
37.Dt DIV 3
38.Os
39.Sh NAME
40.Nm div
41.Nd return quotient and remainder from division
42.Sh SYNOPSIS
43.Fd #include <stdlib.h>
44.Ft div_t
45.Fn div "int num" "int denom"
46.Sh DESCRIPTION
47The
48.Fn div
49function
50computes the value
51.Fa num/denom
52and returns the quotient and remainder in a structure named
53.Fa div_t
54that contains two
55.Em int
56members named
57.Fa quot
58and
59.Fa rem .
60.Sh SEE ALSO
61.Xr ldiv 3 ,
62.Xr qdiv 3 ,
63.Xr math 3
64.Sh STANDARDS
65The
66.Fn div
67function
68conforms to
69.St -ansiC .
diff --git a/src/lib/libc/stdlib/div.c b/src/lib/libc/stdlib/div.c
new file mode 100644
index 0000000000..c1fae29008
--- /dev/null
+++ b/src/lib/libc/stdlib/div.c
@@ -0,0 +1,79 @@
1/*
2 * Copyright (c) 1990 Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Chris Torek.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: div.c,v 1.2 1996/08/19 08:33:29 tholo Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#include <stdlib.h> /* div_t */
42
43div_t
44div(num, denom)
45 int num, denom;
46{
47 div_t r;
48
49 r.quot = num / denom;
50 r.rem = num % denom;
51 /*
52 * The ANSI standard says that |r.quot| <= |n/d|, where
53 * n/d is to be computed in infinite precision. In other
54 * words, we should always truncate the quotient towards
55 * 0, never -infinity.
56 *
57 * Machine division and remainer may work either way when
58 * one or both of n or d is negative. If only one is
59 * negative and r.quot has been truncated towards -inf,
60 * r.rem will have the same sign as denom and the opposite
61 * sign of num; if both are negative and r.quot has been
62 * truncated towards -inf, r.rem will be positive (will
63 * have the opposite sign of num). These are considered
64 * `wrong'.
65 *
66 * If both are num and denom are positive, r will always
67 * be positive.
68 *
69 * This all boils down to:
70 * if num >= 0, but r.rem < 0, we got the wrong answer.
71 * In that case, to get the right answer, add 1 to r.quot and
72 * subtract denom from r.rem.
73 */
74 if (num >= 0 && r.rem < 0) {
75 r.quot++;
76 r.rem -= denom;
77 }
78 return (r);
79}
diff --git a/src/lib/libc/stdlib/drand48.c b/src/lib/libc/stdlib/drand48.c
new file mode 100644
index 0000000000..02886d5b62
--- /dev/null
+++ b/src/lib/libc/stdlib/drand48.c
@@ -0,0 +1,26 @@
1/*
2 * Copyright (c) 1993 Martin Birgmeier
3 * All rights reserved.
4 *
5 * You may redistribute unmodified or modified versions of this source
6 * code provided that the above copyright notice and this and the
7 * following conditions are retained.
8 *
9 * This software is provided ``as is'', and comes with no warranties
10 * of any kind. I shall in no event be liable for anything that happens
11 * to anyone/anything when using this software.
12 */
13
14#if defined(LIBC_SCCS) && !defined(lint)
15static char rcsid[] = "$OpenBSD: drand48.c,v 1.2 1996/08/19 08:33:29 tholo Exp $";
16#endif /* LIBC_SCCS and not lint */
17
18#include "rand48.h"
19
20extern unsigned short __rand48_seed[3];
21
22double
23drand48(void)
24{
25 return erand48(__rand48_seed);
26}
diff --git a/src/lib/libc/stdlib/erand48.c b/src/lib/libc/stdlib/erand48.c
new file mode 100644
index 0000000000..b92dacffcc
--- /dev/null
+++ b/src/lib/libc/stdlib/erand48.c
@@ -0,0 +1,27 @@
1/*
2 * Copyright (c) 1993 Martin Birgmeier
3 * All rights reserved.
4 *
5 * You may redistribute unmodified or modified versions of this source
6 * code provided that the above copyright notice and this and the
7 * following conditions are retained.
8 *
9 * This software is provided ``as is'', and comes with no warranties
10 * of any kind. I shall in no event be liable for anything that happens
11 * to anyone/anything when using this software.
12 */
13
14#if defined(LIBC_SCCS) && !defined(lint)
15static char rcsid[] = "$OpenBSD: erand48.c,v 1.2 1996/08/19 08:33:29 tholo Exp $";
16#endif /* LIBC_SCCS and not lint */
17
18#include "rand48.h"
19
20double
21erand48(unsigned short xseed[3])
22{
23 __dorand48(xseed);
24 return ldexp((double) xseed[0], -48) +
25 ldexp((double) xseed[1], -32) +
26 ldexp((double) xseed[2], -16);
27}
diff --git a/src/lib/libc/stdlib/exit.3 b/src/lib/libc/stdlib/exit.3
new file mode 100644
index 0000000000..6dd2affef9
--- /dev/null
+++ b/src/lib/libc/stdlib/exit.3
@@ -0,0 +1,83 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: exit.3,v 1.2 1996/08/19 08:33:30 tholo Exp $
37.\"
38.Dd June 29, 1991
39.Dt EXIT 3
40.Os
41.Sh NAME
42.Nm exit
43.Nd perform normal program termination
44.Sh SYNOPSIS
45.Fd #include <stdlib.h>
46.Ft void
47.Fn exit "int status"
48.Sh DESCRIPTION
49.Fn Exit
50terminates a process.
51.Pp
52Before termination it performs the following functions in the
53order listed:
54.Bl -enum -offset indent
55.It
56Call the functions registered with the
57.Xr atexit 3
58function, in the reverse order of their registration.
59.It
60Flush all open output streams.
61.It
62Close all open streams.
63.It
64Unlink all files created with the
65.Xr tmpfile 3
66function.
67.El
68.Sh RETURN VALUES
69The
70.Fn exit
71function
72never returns.
73.Sh SEE ALSO
74.Xr _exit 2 ,
75.Xr atexit 3 ,
76.Xr intro 3 ,
77.Xr tmpfile 3
78.Sh STANDARDS
79The
80.Fn exit
81function
82conforms to
83.St -ansiC .
diff --git a/src/lib/libc/stdlib/exit.c b/src/lib/libc/stdlib/exit.c
new file mode 100644
index 0000000000..e358c94fd6
--- /dev/null
+++ b/src/lib/libc/stdlib/exit.c
@@ -0,0 +1,60 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: exit.c,v 1.2 1996/08/19 08:33:30 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <stdlib.h>
39#include <unistd.h>
40#include "atexit.h"
41
42void (*__cleanup)();
43
44/*
45 * Exit, flushing stdio buffers if necessary.
46 */
47void
48exit(status)
49 int status;
50{
51 register struct atexit *p;
52 register int n;
53
54 for (p = __atexit; p; p = p->next)
55 for (n = p->ind; --n >= 0;)
56 (*p->fns[n])();
57 if (__cleanup)
58 (*__cleanup)();
59 _exit(status);
60}
diff --git a/src/lib/libc/stdlib/getenv.3 b/src/lib/libc/stdlib/getenv.3
new file mode 100644
index 0000000000..24a8d3d095
--- /dev/null
+++ b/src/lib/libc/stdlib/getenv.3
@@ -0,0 +1,151 @@
1.\" Copyright (c) 1988, 1991, 1993
2.\" The Regents of the University of California. All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: getenv.3,v 1.2 1996/08/10 05:03:00 tholo Exp $
37.\"
38.Dd December 11, 1993
39.Dt GETENV 3
40.Os
41.Sh NAME
42.Nm getenv ,
43.Nm putenv ,
44.Nm setenv ,
45.Nm unsetenv
46.Nd environment variable functions
47.Sh SYNOPSIS
48.Fd #include <stdlib.h>
49.Ft char *
50.Fn getenv "const char *name"
51.Ft int
52.Fn setenv "const char *name" "const char *value" "int overwrite"
53.Ft int
54.Fn putenv "const char *string"
55.Ft void
56.Fn unsetenv "const char *name"
57.Sh DESCRIPTION
58These functions set, unset and fetch environment variables from the
59host
60.Em environment list .
61For compatibility with differing environment conventions,
62the given arguments
63.Ar name
64and
65.Ar value
66may be appended and prepended,
67respectively,
68with an equal sign
69.Dq Li \&= .
70.Pp
71The
72.Fn getenv
73function obtains the current value of the environment variable,
74.Ar name .
75If the variable
76.Ar name
77is not in the current environment,
78a null pointer is returned.
79.Pp
80The
81.Fn setenv
82function inserts or resets the environment variable
83.Ar name
84in the current environment list.
85If the variable
86.Ar name
87does not exist in the list,
88it is inserted with the given
89.Ar value.
90If the variable does exist, the argument
91.Ar overwrite
92is tested; if
93.Ar overwrite is
94zero, the
95variable is not reset, otherwise it is reset
96to the given
97.Ar value .
98.Pp
99The
100.Fn putenv
101function takes an argument of the form ``name=value'' and is
102equivalent to:
103.Bd -literal -offset indent
104setenv(name, value, 1);
105.Ed
106.Pp
107The
108.Fn unsetenv
109function
110deletes all instances of the variable name pointed to by
111.Fa name
112from the list.
113.Sh RETURN VALUES
114The functions
115.Fn setenv
116and
117.Fn putenv
118return zero if successful; otherwise the global variable
119.Va errno
120is set to indicate the error and a
121\-1 is returned.
122.Sh ERRORS
123.Bl -tag -width [ENOMEM]
124.It Bq Er ENOMEM
125The function
126.Fn setenv
127or
128.Fn putenv
129failed because they were unable to allocate memory for the environment.
130.El
131.Sh SEE ALSO
132.Xr csh 1 ,
133.Xr sh 1 ,
134.Xr execve 2 ,
135.Xr environ 7
136.Sh STANDARDS
137The
138.Fn getenv
139function conforms to
140.St -ansiC .
141.Sh HISTORY
142The functions
143.Fn setenv
144and
145.Fn unsetenv
146appeared in
147.At v7 .
148The
149.Fn putenv
150function appeared in
151.Bx 4.3 Reno .
diff --git a/src/lib/libc/stdlib/getenv.c b/src/lib/libc/stdlib/getenv.c
new file mode 100644
index 0000000000..4db86df915
--- /dev/null
+++ b/src/lib/libc/stdlib/getenv.c
@@ -0,0 +1,89 @@
1/*
2 * Copyright (c) 1987, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: getenv.c,v 1.4 1998/07/16 18:02:33 deraadt Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <stdlib.h>
39#include <string.h>
40
41/*
42 * __findenv --
43 * Returns pointer to value associated with name, if any, else NULL.
44 * Sets offset to be the offset of the name/value combination in the
45 * environmental array, for use by setenv(3) and unsetenv(3).
46 * Explicitly removes '=' in argument name.
47 *
48 * This routine *should* be a static; don't use it.
49 */
50char *
51__findenv(name, offset)
52 register const char *name;
53 int *offset;
54{
55 extern char **environ;
56 register int len, i;
57 register const char *np;
58 register char **p, *cp;
59
60 if (name == NULL || environ == NULL)
61 return (NULL);
62 for (np = name; *np && *np != '='; ++np)
63 ;
64 len = np - name;
65 for (p = environ; (cp = *p) != NULL; ++p) {
66 for (np = name, i = len; i && *cp; i--)
67 if (*cp++ != *np++)
68 break;
69 if (i == 0 && *cp++ == '=') {
70 *offset = p - environ;
71 return (cp);
72 }
73 }
74 return (NULL);
75}
76
77/*
78 * getenv --
79 * Returns ptr to value associated with name, if any, else NULL.
80 */
81char *
82getenv(name)
83 const char *name;
84{
85 int offset;
86 char *__findenv();
87
88 return(__findenv(name, &offset));
89}
diff --git a/src/lib/libc/stdlib/getopt.3 b/src/lib/libc/stdlib/getopt.3
new file mode 100644
index 0000000000..4340ff54fd
--- /dev/null
+++ b/src/lib/libc/stdlib/getopt.3
@@ -0,0 +1,261 @@
1.\" Copyright (c) 1988, 1991, 1993
2.\" The Regents of the University of California. All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\" notice, this list of conditions and the following disclaimer.
9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\" notice, this list of conditions and the following disclaimer in the
11.\" documentation and/or other materials provided with the distribution.
12.\" 3. All advertising materials mentioning features or use of this software
13.\" must display the following acknowledgement:
14.\" This product includes software developed by the University of
15.\" California, Berkeley and its contributors.
16.\" 4. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" $OpenBSD: getopt.3,v 1.6 1998/05/05 19:36:03 deraadt Exp $
33.\"
34.Dd April 19, 1994
35.Dt GETOPT 3
36.Os BSD 4.3
37.Sh NAME
38.Nm getopt
39.Nd get option character from command line argument list
40.Sh SYNOPSIS
41.Fd #include <unistd.h>
42.Vt extern char *optarg;
43.Vt extern int optind;
44.Vt extern int optopt;
45.Vt extern int opterr;
46.Vt extern int optreset;
47.Ft int
48.Fn getopt "int argc" "char * const *argv" "const char *optstring"
49.Sh DESCRIPTION
50The
51.Fn getopt
52function incrementally parses a command line argument list
53.Fa argv
54and returns the next
55.Em known
56option character.
57An option character is
58.Em known
59if it has been specified in the string of accepted option characters,
60.Fa optstring .
61.Pp
62The option string
63.Fa optstring
64may contain the following elements: individual characters, and
65characters followed by a colon to indicate an option argument
66is to follow.
67For example, an option string
68.Li "\&""x""
69recognizes an option
70.Dq Fl x ,
71and an option string
72.Li "\&""x:""
73recognizes an option and argument
74.Dq Fl x Ar argument .
75It does not matter to
76.Fn getopt
77if a following argument has leading white space.
78.Pp
79On return from
80.Fn getopt ,
81.Va optarg
82points to an option argument, if it is anticipated,
83and the variable
84.Va optind
85contains the index to the next
86.Fa argv
87argument for a subsequent call
88to
89.Fn getopt .
90The variable
91.Va optopt
92saves the last
93.Em known
94option character returned by
95.Fn getopt .
96.Pp
97The variable
98.Va opterr
99and
100.Va optind
101are both initialized to 1.
102The
103.Va optind
104variable may be set to another value before a set of calls to
105.Fn getopt
106in order to skip over more or less argv entries.
107.Pp
108In order to use
109.Fn getopt
110to evaluate multiple sets of arguments, or to evaluate a single set of
111arguments multiple times,
112the variable
113.Va optreset
114must be set to 1 before the second and each additional set of calls to
115.Fn getopt ,
116and the variable
117.Va optind
118must be reinitialized.
119.Pp
120The
121.Fn getopt
122function
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
127by the option
128.Ql --
129(double dash) which causes
130.Fn getopt
131to signal the end of argument processing and returns \-1.
132When all options have been processed (i.e., up to the first non-option
133argument),
134.Fn getopt
135returns \-1.
136.Sh DIAGNOSTICS
137If the
138.Fn getopt
139function encounters a character not found in the string
140.Va optstring
141or detects
142a missing option argument it writes an error message to
143.Em stderr
144and returns
145.Ql ? .
146Setting
147.Va opterr
148to a zero will disable these error messages.
149If
150.Va optstring
151has a leading
152.Ql \&:
153then a missing option argument causes a
154.Ql \&:
155to be returned in addition to suppressing any error messages.
156.Pp
157Option arguments are allowed to begin with
158.Dq Li \- ;
159this is reasonable but
160reduces the amount of error checking possible.
161.Sh EXTENSIONS
162The
163.Va optreset
164variable was added to make it possible to call the
165.Fn getopt
166function multiple times.
167This is an extension to the
168.St -p1003.2
169specification.
170.Sh EXAMPLE
171.Bd -literal -compact
172extern char *optarg;
173extern int optind;
174int bflag, ch, fd;
175
176bflag = 0;
177while ((ch = getopt(argc, argv, "bf:")) != -1) {
178 switch (ch) {
179 case 'b':
180 bflag = 1;
181 break;
182 case 'f':
183 if ((fd = open(optarg, O_RDONLY, 0)) < 0) {
184 (void)fprintf(stderr,
185 "myname: %s: %s\en", optarg, strerror(errno));
186 exit(1);
187 }
188 break;
189 case '?':
190 default:
191 usage();
192 }
193}
194argc -= optind;
195argv += optind;
196.Ed
197.Sh HISTORY
198The
199.Fn getopt
200function appeared
201.Bx 4.3 .
202.Sh BUGS
203The
204.Fn getopt
205function was once specified to return
206.Dv EOF
207instead of \-1.
208This was changed by
209.St -p1003.2-92
210to decouple
211.Fn getopt
212from
213.Pa <stdio.h> .
214.Pp
215A single dash
216.Dq Li -
217may be specified as a character in
218.Fa optstring ,
219however it should
220.Em never
221have an argument associated with it.
222This allows
223.Fn getopt
224to be used with programs that expect
225.Dq Li -
226as an option flag.
227This practice is wrong, and should not be used in any current development.
228It is provided for backward compatibility
229.Em only .
230By default, a single dash causes
231.Fn getopt
232to return \-1.
233This is, we believe, compatible with System V.
234.Pp
235It is also possible to handle digits as option letters.
236This allows
237.Fn getopt
238to be used with programs that expect a number
239.Pq Dq Li \&-\&3
240as an option.
241This practice is wrong, and should not be used in any current development.
242It is provided for backward compatibility
243.Em only .
244The following code fragment works in most cases.
245.Bd -literal -offset indent
246int length;
247char *p;
248
249while ((c = getopt(argc, argv, "0123456789")) != -1)
250 switch (c) {
251 case '0': case '1': case '2': case '3': case '4':
252 case '5': case '6': case '7': case '8': case '9':
253 p = argv[optind - 1];
254 if (p[0] == '-' && p[1] == ch && !p[2])
255 length = atoi(++p);
256 else
257 length = atoi(argv[optind] + 1);
258 break;
259 }
260}
261.Ed
diff --git a/src/lib/libc/stdlib/getopt.c b/src/lib/libc/stdlib/getopt.c
new file mode 100644
index 0000000000..b7f6163662
--- /dev/null
+++ b/src/lib/libc/stdlib/getopt.c
@@ -0,0 +1,117 @@
1/*
2 * Copyright (c) 1987, 1993, 1994
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: getopt.c,v 1.2 1996/08/19 08:33:32 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <stdio.h>
39#include <stdlib.h>
40#include <string.h>
41
42int opterr = 1, /* if error message should be printed */
43 optind = 1, /* index into parent argv vector */
44 optopt, /* character checked for validity */
45 optreset; /* reset getopt */
46char *optarg; /* argument associated with option */
47
48#define BADCH (int)'?'
49#define BADARG (int)':'
50#define EMSG ""
51
52/*
53 * getopt --
54 * Parse argc/argv argument vector.
55 */
56int
57getopt(nargc, nargv, ostr)
58 int nargc;
59 char * const *nargv;
60 const char *ostr;
61{
62 extern char *__progname;
63 static char *place = EMSG; /* option letter processing */
64 char *oli; /* option letter list index */
65
66 if (optreset || !*place) { /* update scanning pointer */
67 optreset = 0;
68 if (optind >= nargc || *(place = nargv[optind]) != '-') {
69 place = EMSG;
70 return (-1);
71 }
72 if (place[1] && *++place == '-') { /* found "--" */
73 ++optind;
74 place = EMSG;
75 return (-1);
76 }
77 } /* option letter okay? */
78 if ((optopt = (int)*place++) == (int)':' ||
79 !(oli = strchr(ostr, optopt))) {
80 /*
81 * if the user didn't specify '-' as an option,
82 * assume it means -1.
83 */
84 if (optopt == (int)'-')
85 return (-1);
86 if (!*place)
87 ++optind;
88 if (opterr && *ostr != ':')
89 (void)fprintf(stderr,
90 "%s: illegal option -- %c\n", __progname, optopt);
91 return (BADCH);
92 }
93 if (*++oli != ':') { /* don't need argument */
94 optarg = NULL;
95 if (!*place)
96 ++optind;
97 }
98 else { /* need an argument */
99 if (*place) /* no white space */
100 optarg = place;
101 else if (nargc <= ++optind) { /* no arg */
102 place = EMSG;
103 if (*ostr == ':')
104 return (BADARG);
105 if (opterr)
106 (void)fprintf(stderr,
107 "%s: option requires an argument -- %c\n",
108 __progname, optopt);
109 return (BADCH);
110 }
111 else /* white space */
112 optarg = nargv[optind];
113 place = EMSG;
114 ++optind;
115 }
116 return (optopt); /* dump back option letter */
117}
diff --git a/src/lib/libc/stdlib/getsubopt.3 b/src/lib/libc/stdlib/getsubopt.3
new file mode 100644
index 0000000000..8acc91bdd1
--- /dev/null
+++ b/src/lib/libc/stdlib/getsubopt.3
@@ -0,0 +1,148 @@
1.\" $OpenBSD: getsubopt.3,v 1.2 1998/06/15 17:55:07 mickey Exp $
2.\"
3.\" Copyright (c) 1990, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.\" @(#)getsubopt.3 8.1 (Berkeley) 6/9/93
35.\"
36.Dd June 9, 1993
37.Dt GETSUBOPT 3
38.Os
39.Sh NAME
40.Nm getsubopt
41.Nd get sub options from an argument
42.Sh SYNOPSIS
43.Fd #include <stdlib.h>
44.Vt extern char *suboptarg
45.Ft int
46.Fn getsubopt "char **optionp" "char * const *tokens" "char **valuep"
47.Sh DESCRIPTION
48The
49.Fn getsubopt
50function
51parses a string containing tokens delimited by one or more tab, space or
52comma
53.Pq Ql \&,
54characters.
55It is intended for use in parsing groups of option arguments provided
56as part of a utility command line.
57.Pp
58The argument
59.Fa optionp
60is a pointer to a pointer to the string.
61The argument
62.Fa tokens
63is a pointer to a
64.Dv NULL Ns -terminated
65array of pointers to strings.
66.Pp
67The
68.Fn getsubopt
69function
70returns the zero-based offset of the pointer in the
71.Fa tokens
72array referencing a string which matches the first token
73in the string, or, \-1 if the string contains no tokens or
74.Fa tokens
75does not contain a matching string.
76.Pp
77If the token is of the form ``name=value'', the location referenced by
78.Fa valuep
79will be set to point to the start of the ``value'' portion of the token.
80.Pp
81On return from
82.Fn getsubopt ,
83.Fa optionp
84will be set to point to the start of the next token in the string,
85or the null at the end of the string if no more tokens are present.
86The external variable
87.Fa suboptarg
88will be set to point to the start of the current token, or
89.Dv NULL
90if no
91tokens were present.
92The argument
93.Fa valuep
94will be set to point to the ``value'' portion of the token, or
95.Dv NULL
96if no ``value'' portion was present.
97.Sh EXAMPLE
98.Bd -literal -compact
99char *tokens[] = {
100 #define ONE 0
101 "one",
102 #define TWO 1
103 "two",
104 NULL
105};
106
107\&...
108
109extern char *optarg, *suboptarg;
110char *options, *value;
111
112while ((ch = getopt(argc, argv, "ab:")) != \-1) {
113 switch(ch) {
114 case 'a':
115 /* process ``a'' option */
116 break;
117 case 'b':
118 options = optarg;
119 while (*options) {
120 switch(getsubopt(&options, tokens, &value)) {
121 case ONE:
122 /* process ``one'' sub option */
123 break;
124 case TWO:
125 /* process ``two'' sub option */
126 if (!value)
127 error("no value for two");
128 i = atoi(value);
129 break;
130 case \-1:
131 if (suboptarg)
132 error("illegal sub option %s",
133 suboptarg);
134 else
135 error("missing sub option");
136 break;
137 }
138 break;
139 }
140.Ed
141.Sh SEE ALSO
142.Xr getopt 3 ,
143.Xr strsep 3
144.Sh HISTORY
145The
146.Fn getsubopt
147function first appeared in
148.Bx 4.4 .
diff --git a/src/lib/libc/stdlib/getsubopt.c b/src/lib/libc/stdlib/getsubopt.c
new file mode 100644
index 0000000000..1667a31d7d
--- /dev/null
+++ b/src/lib/libc/stdlib/getsubopt.c
@@ -0,0 +1,106 @@
1/* $OpenBSD: getsubopt.c,v 1.1 1997/08/20 04:02:17 millert Exp $ */
2
3/*-
4 * Copyright (c) 1990, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36#ifndef lint
37#if 0
38static char sccsid[] = "@(#)getsubopt.c 8.1 (Berkeley) 6/4/93";
39#else
40static char rcsid[] = "$OpenBSD: getsubopt.c,v 1.1 1997/08/20 04:02:17 millert Exp $";
41#endif
42#endif /* not lint */
43
44#include <unistd.h>
45#include <stdlib.h>
46#include <string.h>
47
48/*
49 * The SVID interface to getsubopt provides no way of figuring out which
50 * part of the suboptions list wasn't matched. This makes error messages
51 * tricky... The extern variable suboptarg is a pointer to the token
52 * which didn't match.
53 */
54char *suboptarg;
55
56int
57getsubopt(optionp, tokens, valuep)
58 register char **optionp, **valuep;
59 register char * const *tokens;
60{
61 register int cnt;
62 register char *p;
63
64 suboptarg = *valuep = NULL;
65
66 if (!optionp || !*optionp)
67 return(-1);
68
69 /* skip leading white-space, commas */
70 for (p = *optionp; *p && (*p == ',' || *p == ' ' || *p == '\t'); ++p);
71
72 if (!*p) {
73 *optionp = p;
74 return(-1);
75 }
76
77 /* save the start of the token, and skip the rest of the token. */
78 for (suboptarg = p;
79 *++p && *p != ',' && *p != '=' && *p != ' ' && *p != '\t';);
80
81 if (*p) {
82 /*
83 * If there's an equals sign, set the value pointer, and
84 * skip over the value part of the token. Terminate the
85 * token.
86 */
87 if (*p == '=') {
88 *p = '\0';
89 for (*valuep = ++p;
90 *p && *p != ',' && *p != ' ' && *p != '\t'; ++p);
91 if (*p)
92 *p++ = '\0';
93 } else
94 *p++ = '\0';
95 /* Skip any whitespace or commas after this token. */
96 for (; *p && (*p == ',' || *p == ' ' || *p == '\t'); ++p);
97 }
98
99 /* set optionp for next round. */
100 *optionp = p;
101
102 for (cnt = 0; *tokens; ++tokens, ++cnt)
103 if (!strcmp(suboptarg, *tokens))
104 return(cnt);
105 return(-1);
106}
diff --git a/src/lib/libc/stdlib/heapsort.c b/src/lib/libc/stdlib/heapsort.c
new file mode 100644
index 0000000000..e3e4392e05
--- /dev/null
+++ b/src/lib/libc/stdlib/heapsort.c
@@ -0,0 +1,183 @@
1/*-
2 * Copyright (c) 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Ronnie Kon at Mindcraft Inc., Kevin Lew and Elmer Yglesias.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: heapsort.c,v 1.2 1996/08/19 08:33:32 tholo Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#include <sys/types.h>
42#include <errno.h>
43#include <stdlib.h>
44
45/*
46 * Swap two areas of size number of bytes. Although qsort(3) permits random
47 * blocks of memory to be sorted, sorting pointers is almost certainly the
48 * common case (and, were it not, could easily be made so). Regardless, it
49 * isn't worth optimizing; the SWAP's get sped up by the cache, and pointer
50 * arithmetic gets lost in the time required for comparison function calls.
51 */
52#define SWAP(a, b, count, size, tmp) { \
53 count = size; \
54 do { \
55 tmp = *a; \
56 *a++ = *b; \
57 *b++ = tmp; \
58 } while (--count); \
59}
60
61/* Copy one block of size size to another. */
62#define COPY(a, b, count, size, tmp1, tmp2) { \
63 count = size; \
64 tmp1 = a; \
65 tmp2 = b; \
66 do { \
67 *tmp1++ = *tmp2++; \
68 } while (--count); \
69}
70
71/*
72 * Build the list into a heap, where a heap is defined such that for
73 * the records K1 ... KN, Kj/2 >= Kj for 1 <= j/2 <= j <= N.
74 *
75 * There two cases. If j == nmemb, select largest of Ki and Kj. If
76 * j < nmemb, select largest of Ki, Kj and Kj+1.
77 */
78#define CREATE(initval, nmemb, par_i, child_i, par, child, size, count, tmp) { \
79 for (par_i = initval; (child_i = par_i * 2) <= nmemb; \
80 par_i = child_i) { \
81 child = base + child_i * size; \
82 if (child_i < nmemb && compar(child, child + size) < 0) { \
83 child += size; \
84 ++child_i; \
85 } \
86 par = base + par_i * size; \
87 if (compar(child, par) <= 0) \
88 break; \
89 SWAP(par, child, count, size, tmp); \
90 } \
91}
92
93/*
94 * Select the top of the heap and 'heapify'. Since by far the most expensive
95 * action is the call to the compar function, a considerable optimization
96 * in the average case can be achieved due to the fact that k, the displaced
97 * elememt, is ususally quite small, so it would be preferable to first
98 * heapify, always maintaining the invariant that the larger child is copied
99 * over its parent's record.
100 *
101 * Then, starting from the *bottom* of the heap, finding k's correct place,
102 * again maintianing the invariant. As a result of the invariant no element
103 * is 'lost' when k is assigned its correct place in the heap.
104 *
105 * The time savings from this optimization are on the order of 15-20% for the
106 * average case. See Knuth, Vol. 3, page 158, problem 18.
107 *
108 * XXX Don't break the #define SELECT line, below. Reiser cpp gets upset.
109 */
110#define SELECT(par_i, child_i, nmemb, par, child, size, k, count, tmp1, tmp2) { \
111 for (par_i = 1; (child_i = par_i * 2) <= nmemb; par_i = child_i) { \
112 child = base + child_i * size; \
113 if (child_i < nmemb && compar(child, child + size) < 0) { \
114 child += size; \
115 ++child_i; \
116 } \
117 par = base + par_i * size; \
118 COPY(par, child, count, size, tmp1, tmp2); \
119 } \
120 for (;;) { \
121 child_i = par_i; \
122 par_i = child_i / 2; \
123 child = base + child_i * size; \
124 par = base + par_i * size; \
125 if (child_i == 1 || compar(k, par) < 0) { \
126 COPY(child, k, count, size, tmp1, tmp2); \
127 break; \
128 } \
129 COPY(child, par, count, size, tmp1, tmp2); \
130 } \
131}
132
133/*
134 * Heapsort -- Knuth, Vol. 3, page 145. Runs in O (N lg N), both average
135 * and worst. While heapsort is faster than the worst case of quicksort,
136 * the BSD quicksort does median selection so that the chance of finding
137 * a data set that will trigger the worst case is nonexistent. Heapsort's
138 * only advantage over quicksort is that it requires little additional memory.
139 */
140int
141heapsort(vbase, nmemb, size, compar)
142 void *vbase;
143 size_t nmemb, size;
144 int (*compar) __P((const void *, const void *));
145{
146 register int cnt, i, j, l;
147 register char tmp, *tmp1, *tmp2;
148 char *base, *k, *p, *t;
149
150 if (nmemb <= 1)
151 return (0);
152
153 if (!size) {
154 errno = EINVAL;
155 return (-1);
156 }
157
158 if ((k = malloc(size)) == NULL)
159 return (-1);
160
161 /*
162 * Items are numbered from 1 to nmemb, so offset from size bytes
163 * below the starting address.
164 */
165 base = (char *)vbase - size;
166
167 for (l = nmemb / 2 + 1; --l;)
168 CREATE(l, nmemb, i, j, t, p, size, cnt, tmp);
169
170 /*
171 * For each element of the heap, save the largest element into its
172 * final slot, save the displaced element (k), then recreate the
173 * heap.
174 */
175 while (nmemb > 1) {
176 COPY(k, base + nmemb * size, cnt, size, tmp1, tmp2);
177 COPY(base + nmemb * size, base + size, cnt, size, tmp1, tmp2);
178 --nmemb;
179 SELECT(i, j, nmemb, t, p, size, k, cnt, tmp1, tmp2);
180 }
181 free(k);
182 return (0);
183}
diff --git a/src/lib/libc/stdlib/jrand48.c b/src/lib/libc/stdlib/jrand48.c
new file mode 100644
index 0000000000..99cddb71e5
--- /dev/null
+++ b/src/lib/libc/stdlib/jrand48.c
@@ -0,0 +1,25 @@
1/*
2 * Copyright (c) 1993 Martin Birgmeier
3 * All rights reserved.
4 *
5 * You may redistribute unmodified or modified versions of this source
6 * code provided that the above copyright notice and this and the
7 * following conditions are retained.
8 *
9 * This software is provided ``as is'', and comes with no warranties
10 * of any kind. I shall in no event be liable for anything that happens
11 * to anyone/anything when using this software.
12 */
13
14#if defined(LIBC_SCCS) && !defined(lint)
15static char rcsid[] = "$OpenBSD: jrand48.c,v 1.2 1996/08/19 08:33:33 tholo Exp $";
16#endif /* LIBC_SCCS and not lint */
17
18#include "rand48.h"
19
20long
21jrand48(unsigned short xseed[3])
22{
23 __dorand48(xseed);
24 return ((long) xseed[2] << 16) + (long) xseed[1];
25}
diff --git a/src/lib/libc/stdlib/l64a.c b/src/lib/libc/stdlib/l64a.c
new file mode 100644
index 0000000000..4e99391254
--- /dev/null
+++ b/src/lib/libc/stdlib/l64a.c
@@ -0,0 +1,46 @@
1/*
2 * Written by J.T. Conklin <jtc@netbsd.org>.
3 * Public domain.
4 */
5
6#if defined(LIBC_SCCS) && !defined(lint)
7static char *rcsid = "$OpenBSD: l64a.c,v 1.3 1997/08/17 22:58:34 millert Exp $";
8#endif /* LIBC_SCCS and not lint */
9
10#include <errno.h>
11#include <stdlib.h>
12
13char *
14l64a(value)
15 long value;
16{
17 static char buf[8];
18 char *s = buf;
19 int digit;
20 int i;
21
22 if (value < 0) {
23 errno = EINVAL;
24 return(NULL);
25 }
26
27 for (i = 0; value != 0 && i < 6; i++) {
28 digit = value & 0x3f;
29
30 if (digit < 2)
31 *s = digit + '.';
32 else if (digit < 12)
33 *s = digit + '0' - 2;
34 else if (digit < 38)
35 *s = digit + 'A' - 12;
36 else
37 *s = digit + 'a' - 38;
38
39 value >>= 6;
40 s++;
41 }
42
43 *s = '\0';
44
45 return(buf);
46}
diff --git a/src/lib/libc/stdlib/labs.3 b/src/lib/libc/stdlib/labs.3
new file mode 100644
index 0000000000..05eae329df
--- /dev/null
+++ b/src/lib/libc/stdlib/labs.3
@@ -0,0 +1,66 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: labs.3,v 1.2 1996/08/19 08:33:34 tholo Exp $
37.\"
38.Dd June 29, 1991
39.Dt LABS 3
40.Os
41.Sh NAME
42.Nm labs
43.Nd return the absolute value of a long integer
44.Sh SYNOPSIS
45.Fd #include <stdlib.h>
46.Ft long
47.Fn labs "long j"
48.Sh DESCRIPTION
49The
50.Fn labs
51function
52returns the absolute value of the long integer
53.Ar j .
54.Sh SEE ALSO
55.Xr abs 3 ,
56.Xr floor 3 ,
57.Xr cabs 3 ,
58.Xr math 3
59.Sh STANDARDS
60The
61.Fn labs
62function
63conforms to
64.St -ansiC .
65.Sh BUGS
66The absolute value of the most negative integer remains negative.
diff --git a/src/lib/libc/stdlib/labs.c b/src/lib/libc/stdlib/labs.c
new file mode 100644
index 0000000000..f20e2c29be
--- /dev/null
+++ b/src/lib/libc/stdlib/labs.c
@@ -0,0 +1,45 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: labs.c,v 1.2 1996/08/19 08:33:34 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <stdlib.h>
39
40long
41labs(j)
42 long j;
43{
44 return(j < 0 ? -j : j);
45}
diff --git a/src/lib/libc/stdlib/lcong48.c b/src/lib/libc/stdlib/lcong48.c
new file mode 100644
index 0000000000..44bd74e48a
--- /dev/null
+++ b/src/lib/libc/stdlib/lcong48.c
@@ -0,0 +1,34 @@
1/*
2 * Copyright (c) 1993 Martin Birgmeier
3 * All rights reserved.
4 *
5 * You may redistribute unmodified or modified versions of this source
6 * code provided that the above copyright notice and this and the
7 * following conditions are retained.
8 *
9 * This software is provided ``as is'', and comes with no warranties
10 * of any kind. I shall in no event be liable for anything that happens
11 * to anyone/anything when using this software.
12 */
13
14#if defined(LIBC_SCCS) && !defined(lint)
15static char rcsid[] = "$OpenBSD: lcong48.c,v 1.2 1996/08/19 08:33:35 tholo Exp $";
16#endif /* LIBC_SCCS and not lint */
17
18#include "rand48.h"
19
20extern unsigned short __rand48_seed[3];
21extern unsigned short __rand48_mult[3];
22extern unsigned short __rand48_add;
23
24void
25lcong48(unsigned short p[7])
26{
27 __rand48_seed[0] = p[0];
28 __rand48_seed[1] = p[1];
29 __rand48_seed[2] = p[2];
30 __rand48_mult[0] = p[3];
31 __rand48_mult[1] = p[4];
32 __rand48_mult[2] = p[5];
33 __rand48_add = p[6];
34}
diff --git a/src/lib/libc/stdlib/ldiv.3 b/src/lib/libc/stdlib/ldiv.3
new file mode 100644
index 0000000000..8757f4ddd5
--- /dev/null
+++ b/src/lib/libc/stdlib/ldiv.3
@@ -0,0 +1,71 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: ldiv.3,v 1.2 1996/08/19 08:33:35 tholo Exp $
37.\"
38.Dd June 29, 1991
39.Dt LDIV 3
40.Os
41.Sh NAME
42.Nm ldiv
43.Nd return quotient and remainder from division
44.Sh SYNOPSIS
45.Fd #include <stdlib.h>
46.Ft ldiv_t
47.Fn ldiv "long num" "long denom"
48.Sh DESCRIPTION
49The
50.Fn ldiv
51function
52computes the value
53.Ar num/denom
54and returns the quotient and remainder in a structure named
55.Ar ldiv_t
56that contains two
57.Em long integer
58members named
59.Ar quot
60and
61.Ar rem .
62.Sh SEE ALSO
63.Xr div 3 ,
64.Xr qdiv 3 ,
65.Xr math 3
66.Sh STANDARDS
67The
68.Fn ldiv
69function
70conforms to
71.St -ansiC .
diff --git a/src/lib/libc/stdlib/ldiv.c b/src/lib/libc/stdlib/ldiv.c
new file mode 100644
index 0000000000..908c2bf0aa
--- /dev/null
+++ b/src/lib/libc/stdlib/ldiv.c
@@ -0,0 +1,58 @@
1/*
2 * Copyright (c) 1990 Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Chris Torek.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: ldiv.c,v 1.2 1996/08/19 08:33:35 tholo Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#include <stdlib.h> /* ldiv_t */
42
43ldiv_t
44ldiv(num, denom)
45 long num, denom;
46{
47 ldiv_t r;
48
49 /* see div.c for comments */
50
51 r.quot = num / denom;
52 r.rem = num % denom;
53 if (num >= 0 && r.rem < 0) {
54 r.quot++;
55 r.rem -= denom;
56 }
57 return (r);
58}
diff --git a/src/lib/libc/stdlib/lrand48.c b/src/lib/libc/stdlib/lrand48.c
new file mode 100644
index 0000000000..6b7524a51b
--- /dev/null
+++ b/src/lib/libc/stdlib/lrand48.c
@@ -0,0 +1,27 @@
1/*
2 * Copyright (c) 1993 Martin Birgmeier
3 * All rights reserved.
4 *
5 * You may redistribute unmodified or modified versions of this source
6 * code provided that the above copyright notice and this and the
7 * following conditions are retained.
8 *
9 * This software is provided ``as is'', and comes with no warranties
10 * of any kind. I shall in no event be liable for anything that happens
11 * to anyone/anything when using this software.
12 */
13
14#if defined(LIBC_SCCS) && !defined(lint)
15static char rcsid[] = "$OpenBSD: lrand48.c,v 1.2 1996/08/19 08:33:36 tholo Exp $";
16#endif /* LIBC_SCCS and not lint */
17
18#include "rand48.h"
19
20extern unsigned short __rand48_seed[3];
21
22long
23lrand48(void)
24{
25 __dorand48(__rand48_seed);
26 return ((long) __rand48_seed[2] << 15) + ((long) __rand48_seed[1] >> 1);
27}
diff --git a/src/lib/libc/stdlib/malloc.3 b/src/lib/libc/stdlib/malloc.3
new file mode 100644
index 0000000000..d5f8837ec2
--- /dev/null
+++ b/src/lib/libc/stdlib/malloc.3
@@ -0,0 +1,350 @@
1.\" Copyright (c) 1980, 1991, 1993
2.\" The Regents of the University of California. All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: malloc.3,v 1.9 1998/08/15 20:32:02 deraadt Exp $
37.\"
38.Dd August 27, 1996
39.Dt MALLOC 3
40.Os OpenBSD
41.Sh NAME
42.Nm malloc ,
43.Nd general memory allocation function
44.Pp
45.Nm free ,
46.Nm cfree
47.Nd free up memory allocated with malloc, calloc or realloc
48.Pp
49.Nm realloc
50.Nd reallocation of memory function
51.Sh SYNOPSIS
52.Fd #include <stdlib.h>
53.Ft void *
54.Fn malloc "size_t size"
55.Ft void
56.Fn free "void *ptr"
57.Ft void
58.Fn cfree "void *ptr"
59.Ft void *
60.Fn realloc "void *ptr" "size_t size"
61.Ft char *
62.Va malloc_options
63.Sh DESCRIPTION
64The
65.Fn malloc
66function allocates uninitialized space for an object whose
67size is specified by
68.Fa size .
69The
70.Fn malloc
71function maintains multiple lists of free blocks according to size, allocating
72space from the appropriate list.
73.Pp
74The allocated space is
75suitably aligned (after possible pointer
76coercion) for storage of any type of object. If the space is of
77.Em pagesize
78or larger, the memory returned will be page-aligned.
79.Pp
80Allocation of a zero size object returns a pointer to a zero size object.
81.Pp
82The
83.Fn free
84function causes the space pointed to by
85.Fa ptr
86to be deallocated, that is, at least made available for further allocation,
87but if possible, it will passed back to the kernel with
88.Xr sbrk 2 .
89If
90.Fa ptr
91is a null pointer, no action occurs.
92.Pp
93A
94.Fn cfree
95function is also provided for compatibility with old systems and other
96.Nm malloc
97libraries; it is simply an alias for
98.Fn free .
99.Pp
100The
101.Fn realloc
102function changes the size of the object pointed to by
103.Fa ptr
104to the size specified by
105.Fa size .
106The contents of the object are unchanged up to the lesser
107of the new and old sizes.
108If the new size is larger, the value of the newly allocated portion
109of the object is indeterminate and uninitialized.
110If
111.Fa ptr
112is a null pointer, the
113.Fn realloc
114function behaves like the
115.Fn malloc
116function for the specified size.
117If the space cannot be allocated, the object
118pointed to by
119.Fa ptr
120is unchanged.
121If
122.Fa size
123is zero and
124.Fa ptr
125is not a null pointer, the object it points to is freed and a new zero size
126object is returned.
127.Pp
128When using
129.Fn realloc
130one must be careful to avoid the following idiom:
131.Pp
132.Bd -literal -offset indent
133if ((p = realloc(p, nsize)) == NULL)
134 return NULL;
135.Ed
136.Pp
137In most cases, this will result in a leak of memory.
138As stated earlier, a return value of
139.Fa NULL
140indicates that the old object still remains allocated.
141Better code looks like this:
142.Bd -literal -offset indent
143if ((p2 = realloc(p, nsize)) == NULL) {
144 if (p)
145 free(p);
146 p = NULL;
147 return NULL;
148}
149p = p2;
150.Ed
151.Pp
152Malloc will first look for a symbolic link called
153.Pa /etc/malloc.conf
154and next check the environment for a variable called
155.Ev MALLOC_OPTIONS
156and finally for the global variable
157.Va malloc_options
158and scan them for flags in that order.
159Flags are single letters, uppercase means on, lowercase means off.
160.Bl -tag -width indent
161.It A
162``abort'' malloc will coredump the process, rather than tolerate failure.
163This is a very handy debugging aid, since the core file will represent the
164time of failure,
165rather than when the NULL pointer was accessed.
166
167.It D
168``dump'' malloc will dump statistics in a file called ``malloc.out'' at exit.
169This option requires the library to have been compiled with -DMALLOC_STATS in
170order to have any effect.
171
172.It J
173``junk'' fill some junk into the area allocated.
174Currently junk is bytes of 0xd0, this is pronounced ``Duh'' :-)
175
176.It H
177``hint'' pass a hint to the kernel about pages we don't use. If the
178machine is paging a lot this may help a bit.
179
180.It N
181Do not output warning messages when encountering possible corruption
182or bad pointers.
183
184.It R
185``realloc'' always reallocate when
186.Fn realloc
187is called, even if the initial allocation was big enough.
188This can substantially aid in compacting memory.
189
190.It U
191``utrace'' generate entries for
192.Xr ktrace 1
193for all operations.
194Consult the source for this one.
195
196.It X
197``xmalloc''
198rather than return failure,
199.Xr abort 3
200the program with a diagnostic message on stderr.
201It is the intention that this option be set at compile time by
202including in the source:
203.Bd -literal -offset indent
204extern char *malloc_options;
205malloc_options = "X";
206.Ed
207
208.It Z
209``zero'' fill some junk into the area allocated (see ``J''),
210except for the exact length the user asked for, which is zeroed.
211
212.It <
213``Half the cache size'' Reduce the size of the cache by a factor of two.
214
215.It >
216``Double the cache size'' Double the size of the cache by a factor of two.
217.El
218.Pp
219So to set a systemwide reduction of cache size and coredumps on problems
220one would:
221.Li ln -s 'A<' /etc/malloc.conf
222.Pp
223The ``J'' and ``Z'' is mostly for testing and debugging,
224if a program changes behavior if either of these options are used,
225it is buggy.
226.Pp
227The default cache size is 16 pages.
228.Sh ENVIRONMENT
229See above.
230.Sh RETURN VALUES
231The
232.Fn malloc
233function returns
234a pointer to the allocated space if successful; otherwise
235a null pointer is returned.
236.Pp
237The
238.Fn free
239function returns no value.
240.Pp
241The
242.Fn realloc
243function a pointer to the possibly moved allocated space;
244otherwise a null pointer is returned.
245.Sh MESSAGES
246If
247.Fn malloc ,
248.Fn free
249or
250.Fn realloc
251detects an error or warning condition,
252a message will be printed to filedescriptor
2532 (not using stdio).
254Errors will always result in the process being
255.Xr abort 2 'ed,
256If the ``A'' option has been specified, also warnings will
257.Xr abort 2
258the process.
259.Pp
260Here is a brief description of the error messages and what they mean:
261.Pp
262``(ES): mumble mumble mumble'':
263malloc have been compiled with -DEXTRA_SANITY and something looks
264fishy in there. Consult sources and or wizards.
265.Pp
266``allocation failed''
267if the ``A'' option is specified it is an error for
268.Fn malloc
269or
270.Fn realloc
271to return NULL.
272.Pp
273``mmap(2) failed, check limits.''
274This is a rather weird condition that is most likely to mean that
275the system is seriously overloaded or that your ulimits are sick.
276.Pp
277``freelist is destroyed.''
278mallocs internal freelist has been stomped on.
279.Pp
280Here is a brief description of the warning messages and what they mean:
281.Pp
282``chunk/page is already free.''
283A pointer to a free chunk is attempted freed again.
284.Pp
285``junk pointer, too high to make sense.''
286The pointer doesn't make sense. It's above the area of memory that
287malloc knows something about.
288This could be a pointer from some
289.Xr mmap 2 'ed
290memory.
291.Pp
292``junk pointer, too low to make sense.''
293The pointer doesn't make sense. It's below the area of memory that
294malloc knows something about.
295This pointer probably came from your data or bss segments.
296.Pp
297``malloc() has never been called.''
298Nothing has ever been allocated, yet something is being freed or
299realloc'ed.
300.Pp
301``modified (chunk-/page-) pointer.''
302The pointer passed to free or realloc has been modified.
303.Pp
304``pointer to wrong page.''
305The pointer that malloc is trying to free is not pointing to
306a sensible page.
307.Pp
308``recursive call.''
309You have tried to call recursively into these functions.
310I can only imagine this as happening if you call one of these
311functions from a signal function, which happens to be called
312while you're already in here.
313Well, sorry to say: that's not supported.
314If this is a problem for you I'd like to hear about it. It
315would be possible to add a sigblock() around this package,
316but it would have a performance penalty that is not acceptable
317as the default.
318.Pp
319``unknown char in MALLOC_OPTIONS''
320we found something we didn't understand.
321.Sh SEE ALSO
322.Xr brk 2 ,
323.Xr alloca 3 ,
324.Xr calloc 3 ,
325.Xr getpagesize 3 ,
326.Xr memory 3
327.Pa /usr/share/doc/papers/malloc.ascii.gz
328.Sh STANDARDS
329The
330.Fn malloc
331function conforms to
332.St -ansiC .
333.Sh HISTORY
334The present implementation of malloc started out as a filesystem on a drum
335attached to a 20bit binary challenged computer built with discrete germanium
336transistors, and it has since graduated to handle primary storage rather than
337secondary.
338.Pp
339The main difference from other malloc implementations are believed to be that
340the free pages are not accessed until allocated.
341Most malloc implementations will store a data structure containing a,
342possibly double-, linked list in the free chunks of memory, used to tie
343all the free memory together.
344That is a quite suboptimal thing to do.
345Every time the free-list is traversed, all the otherwise unused, and very
346likely paged out, pages get faulted into primary memory, just to see what
347lies after them in the list.
348.Pp
349On systems which are paging, this can make a factor five in difference on the
350page-faults of a process.
diff --git a/src/lib/libc/stdlib/malloc.c b/src/lib/libc/stdlib/malloc.c
new file mode 100644
index 0000000000..d1d8759791
--- /dev/null
+++ b/src/lib/libc/stdlib/malloc.c
@@ -0,0 +1,1242 @@
1/*
2 * ----------------------------------------------------------------------------
3 * "THE BEER-WARE LICENSE" (Revision 42):
4 * <phk@FreeBSD.ORG> wrote this file. As long as you retain this notice you
5 * can do whatever you want with this stuff. If we meet some day, and you think
6 * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
7 * ----------------------------------------------------------------------------
8 */
9
10#if defined(LIBC_SCCS) && !defined(lint)
11static char rcsid[] = "$OpenBSD: malloc.c,v 1.32 1998/08/06 16:26:32 millert Exp $";
12#endif /* LIBC_SCCS and not lint */
13
14/*
15 * Defining MALLOC_EXTRA_SANITY will enable extra checks which are
16 * related to internal conditions and consistency in malloc.c. This has
17 * a noticeable runtime performance hit, and generally will not do you
18 * any good unless you fiddle with the internals of malloc or want
19 * to catch random pointer corruption as early as possible.
20 */
21#ifndef MALLOC_EXTRA_SANITY
22#undef MALLOC_EXTRA_SANITY
23#endif
24
25/*
26 * Defining MALLOC_STATS will enable you to call malloc_dump() and set
27 * the [dD] options in the MALLOC_OPTIONS environment variable.
28 * It has no run-time performance hit, but does pull in stdio...
29 */
30#ifndef MALLOC_STATS
31#undef MALLOC_STATS
32#endif
33
34/*
35 * What to use for Junk. This is the byte value we use to fill with
36 * when the 'J' option is enabled.
37 */
38#define SOME_JUNK 0xd0 /* as in "Duh" :-) */
39
40#include <stdio.h>
41#include <stdlib.h>
42#include <string.h>
43#include <unistd.h>
44#include <fcntl.h>
45#include <errno.h>
46#include <sys/types.h>
47#include <sys/param.h>
48#include <sys/mman.h>
49
50/*
51 * The basic parameters you can tweak.
52 *
53 * malloc_pageshift pagesize = 1 << malloc_pageshift
54 * It's probably best if this is the native
55 * page size, but it shouldn't have to be.
56 *
57 * malloc_minsize minimum size of an allocation in bytes.
58 * If this is too small it's too much work
59 * to manage them. This is also the smallest
60 * unit of alignment used for the storage
61 * returned by malloc/realloc.
62 *
63 */
64
65#if defined(__i386__) && defined(__FreeBSD__)
66# define malloc_pageshift 12U
67# define malloc_minsize 16U
68#endif /* __i386__ && __FreeBSD__ */
69
70#if defined(__sparc__) && !defined(__OpenBSD__)
71# define malloc_pageshirt 12U
72# define malloc_minsize 16U
73# define MAP_ANON (0)
74# define USE_DEV_ZERO
75# define MADV_FREE MADV_DONTNEED
76#endif /* __sparc__ */
77
78/* Insert your combination here... */
79#if defined(__FOOCPU__) && defined(__BAROS__)
80# define malloc_pageshift 12U
81# define malloc_minsize 16U
82#endif /* __FOOCPU__ && __BAROS__ */
83
84#if defined(__OpenBSD__) && !defined(__sparc__)
85# define malloc_pageshift (PGSHIFT)
86# define malloc_minsize 16U
87#endif /* __OpenBSD__ */
88
89#ifdef _THREAD_SAFE
90#include <pthread.h>
91static pthread_mutex_t malloc_lock;
92#define THREAD_LOCK() pthread_mutex_lock(&malloc_lock)
93#define THREAD_UNLOCK() pthread_mutex_unlock(&malloc_lock)
94#define THREAD_LOCK_INIT() pthread_mutex_init(&malloc_lock, 0);
95#else
96#define THREAD_LOCK()
97#define THREAD_UNLOCK()
98#define THREAD_LOCK_INIT()
99#endif
100
101/*
102 * No user serviceable parts behind this point.
103 *
104 * This structure describes a page worth of chunks.
105 */
106
107struct pginfo {
108 struct pginfo *next; /* next on the free list */
109 void *page; /* Pointer to the page */
110 u_short size; /* size of this page's chunks */
111 u_short shift; /* How far to shift for this size chunks */
112 u_short free; /* How many free chunks */
113 u_short total; /* How many chunk */
114 u_long bits[1]; /* Which chunks are free */
115};
116
117/*
118 * This structure describes a number of free pages.
119 */
120
121struct pgfree {
122 struct pgfree *next; /* next run of free pages */
123 struct pgfree *prev; /* prev run of free pages */
124 void *page; /* pointer to free pages */
125 void *end; /* pointer to end of free pages */
126 u_long size; /* number of bytes free */
127};
128
129/*
130 * How many bits per u_long in the bitmap.
131 * Change only if not 8 bits/byte
132 */
133#define MALLOC_BITS (8*sizeof(u_long))
134
135/*
136 * Magic values to put in the page_directory
137 */
138#define MALLOC_NOT_MINE ((struct pginfo*) 0)
139#define MALLOC_FREE ((struct pginfo*) 1)
140#define MALLOC_FIRST ((struct pginfo*) 2)
141#define MALLOC_FOLLOW ((struct pginfo*) 3)
142#define MALLOC_MAGIC ((struct pginfo*) 4)
143
144#ifndef malloc_pageshift
145#define malloc_pageshift 12U
146#endif
147
148#ifndef malloc_minsize
149#define malloc_minsize 16U
150#endif
151
152#ifndef malloc_pageshift
153#error "malloc_pageshift undefined"
154#endif
155
156#if !defined(malloc_pagesize)
157#define malloc_pagesize (1UL<<malloc_pageshift)
158#endif
159
160#if ((1UL<<malloc_pageshift) != malloc_pagesize)
161#error "(1UL<<malloc_pageshift) != malloc_pagesize"
162#endif
163
164#ifndef malloc_maxsize
165#define malloc_maxsize ((malloc_pagesize)>>1)
166#endif
167
168/* A mask for the offset inside a page. */
169#define malloc_pagemask ((malloc_pagesize)-1)
170
171#define pageround(foo) (((foo) + (malloc_pagemask))&(~(malloc_pagemask)))
172#define ptr2index(foo) (((u_long)(foo) >> malloc_pageshift)-malloc_origo)
173
174/* fd of /dev/zero */
175#ifdef USE_DEV_ZERO
176static int fdzero;
177#define MMAP_FD fdzero
178#define INIT_MMAP() \
179 { if ((fdzero=open("/dev/zero", O_RDWR, 0000)) == -1) \
180 wrterror("open of /dev/zero"); }
181#else
182#define MMAP_FD (-1)
183#define INIT_MMAP()
184#endif
185
186/* Set when initialization has been done */
187static unsigned malloc_started;
188
189/* Number of free pages we cache */
190static unsigned malloc_cache = 16;
191
192/* The offset from pagenumber to index into the page directory */
193static u_long malloc_origo;
194
195/* The last index in the page directory we care about */
196static u_long last_index;
197
198/* Pointer to page directory. Allocated "as if with" malloc */
199static struct pginfo **page_dir;
200
201/* How many slots in the page directory */
202static size_t malloc_ninfo;
203
204/* Free pages line up here */
205static struct pgfree free_list;
206
207/* Abort(), user doesn't handle problems. */
208static int malloc_abort;
209
210/* Are we trying to die ? */
211static int suicide;
212
213#ifdef MALLOC_STATS
214/* dump statistics */
215static int malloc_stats;
216#endif
217
218/* avoid outputting warnings? */
219static int malloc_silent;
220
221/* always realloc ? */
222static int malloc_realloc;
223
224#ifdef __FreeBSD__
225/* pass the kernel a hint on free pages ? */
226static int malloc_hint;
227#endif
228
229/* xmalloc behaviour ? */
230static int malloc_xmalloc;
231
232/* zero fill ? */
233static int malloc_zero;
234
235/* junk fill ? */
236static int malloc_junk;
237
238#ifdef __FreeBSD__
239/* utrace ? */
240static int malloc_utrace;
241
242struct ut { void *p; size_t s; void *r; };
243
244void utrace __P((struct ut *, int));
245
246#define UTRACE(a, b, c) \
247 if (malloc_utrace) \
248 {struct ut u; u.p=a; u.s = b; u.r=c; utrace(&u, sizeof u);}
249#else /* !__FreeBSD__ */
250#define UTRACE(a,b,c)
251#endif
252
253/* my last break. */
254static void *malloc_brk;
255
256/* one location cache for free-list holders */
257static struct pgfree *px;
258
259/* compile-time options */
260char *malloc_options;
261
262/* Name of the current public function */
263static char *malloc_func;
264
265/* Macro for mmap */
266#define MMAP(size) \
267 mmap((void *)0, (size), PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, \
268 MMAP_FD, (off_t)0);
269
270/*
271 * Necessary function declarations
272 */
273static int extend_pgdir(u_long index);
274static void *imalloc(size_t size);
275static void ifree(void *ptr);
276static void *irealloc(void *ptr, size_t size);
277static void *malloc_bytes(size_t size);
278
279#ifdef MALLOC_STATS
280void
281malloc_dump(fd)
282 FILE *fd;
283{
284 struct pginfo **pd;
285 struct pgfree *pf;
286 int j;
287
288 pd = page_dir;
289
290 /* print out all the pages */
291 for(j=0;j<=last_index;j++) {
292 fprintf(fd, "%08lx %5d ", (j+malloc_origo) << malloc_pageshift, j);
293 if (pd[j] == MALLOC_NOT_MINE) {
294 for(j++;j<=last_index && pd[j] == MALLOC_NOT_MINE;j++)
295 ;
296 j--;
297 fprintf(fd, ".. %5d not mine\n", j);
298 } else if (pd[j] == MALLOC_FREE) {
299 for(j++;j<=last_index && pd[j] == MALLOC_FREE;j++)
300 ;
301 j--;
302 fprintf(fd, ".. %5d free\n", j);
303 } else if (pd[j] == MALLOC_FIRST) {
304 for(j++;j<=last_index && pd[j] == MALLOC_FOLLOW;j++)
305 ;
306 j--;
307 fprintf(fd, ".. %5d in use\n", j);
308 } else if (pd[j] < MALLOC_MAGIC) {
309 fprintf(fd, "(%p)\n", pd[j]);
310 } else {
311 fprintf(fd, "%p %d (of %d) x %d @ %p --> %p\n",
312 pd[j], pd[j]->free, pd[j]->total,
313 pd[j]->size, pd[j]->page, pd[j]->next);
314 }
315 }
316
317 for(pf=free_list.next; pf; pf=pf->next) {
318 fprintf(fd, "Free: @%p [%p...%p[ %ld ->%p <-%p\n",
319 pf, pf->page, pf->end, pf->size, pf->prev, pf->next);
320 if (pf == pf->next) {
321 fprintf(fd, "Free_list loops.\n");
322 break;
323 }
324 }
325
326 /* print out various info */
327 fprintf(fd, "Minsize\t%d\n", malloc_minsize);
328 fprintf(fd, "Maxsize\t%d\n", malloc_maxsize);
329 fprintf(fd, "Pagesize\t%lu\n", (u_long)malloc_pagesize);
330 fprintf(fd, "Pageshift\t%d\n", malloc_pageshift);
331 fprintf(fd, "FirstPage\t%ld\n", malloc_origo);
332 fprintf(fd, "LastPage\t%ld %lx\n", last_index+malloc_pageshift,
333 (last_index + malloc_pageshift) << malloc_pageshift);
334 fprintf(fd, "Break\t%ld\n", (u_long)sbrk(0) >> malloc_pageshift);
335}
336#endif /* MALLOC_STATS */
337
338extern char *__progname;
339
340static void
341wrterror(p)
342 char *p;
343{
344 char *q = " error: ";
345 write(2, __progname, strlen(__progname));
346 write(2, malloc_func, strlen(malloc_func));
347 write(2, q, strlen(q));
348 write(2, p, strlen(p));
349 suicide = 1;
350#ifdef MALLOC_STATS
351 if (malloc_stats)
352 malloc_dump(stderr);
353#endif /* MALLOC_STATS */
354 abort();
355}
356
357static void
358wrtwarning(p)
359 char *p;
360{
361 char *q = " warning: ";
362 if (malloc_abort)
363 wrterror(p);
364 else if (malloc_silent)
365 return;
366 write(2, __progname, strlen(__progname));
367 write(2, malloc_func, strlen(malloc_func));
368 write(2, q, strlen(q));
369 write(2, p, strlen(p));
370}
371
372#ifdef MALLOC_STATS
373static void
374malloc_exit()
375{
376 FILE *fd = fopen("malloc.out", "a");
377 char *q = "malloc() warning: Couldn't dump stats.\n";
378 if (fd) {
379 malloc_dump(fd);
380 fclose(fd);
381 } else
382 write(2, q, strlen(q));
383}
384#endif /* MALLOC_STATS */
385
386
387/*
388 * Allocate a number of pages from the OS
389 */
390static void *
391map_pages(pages)
392 int pages;
393{
394 caddr_t result, tail;
395
396 result = (caddr_t)pageround((u_long)sbrk(0));
397 tail = result + (pages << malloc_pageshift);
398
399 if (brk(tail)) {
400#ifdef MALLOC_EXTRA_SANITY
401 wrterror("(ES): map_pages fails\n");
402#endif /* MALLOC_EXTRA_SANITY */
403 return 0;
404 }
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 0;
411
412 return result;
413}
414
415/*
416 * Extend page directory
417 */
418static int
419extend_pgdir(index)
420 u_long index;
421{
422 struct pginfo **new, **old;
423 size_t i, oldlen;
424
425 /* Make it this many pages */
426 i = index * sizeof *page_dir;
427 i /= malloc_pagesize;
428 i += 2;
429
430 /* remember the old mapping size */
431 oldlen = malloc_ninfo * sizeof *page_dir;
432
433 /*
434 * NOTE: we allocate new pages and copy the directory rather than tempt
435 * fate by trying to "grow" the region.. There is nothing to prevent
436 * us from accidently re-mapping space that's been allocated by our caller
437 * via dlopen() or other mmap().
438 *
439 * The copy problem is not too bad, as there is 4K of page index per
440 * 4MB of malloc arena.
441 *
442 * We can totally avoid the copy if we open a file descriptor to associate
443 * the anon mappings with. Then, when we remap the pages at the new
444 * address, the old pages will be "magically" remapped.. But this means
445 * keeping open a "secret" file descriptor.....
446 */
447
448 /* Get new pages */
449 new = (struct pginfo**) MMAP(i * malloc_pagesize);
450 if (new == (struct pginfo **)-1)
451 return 0;
452
453 /* Copy the old stuff */
454 memcpy(new, page_dir,
455 malloc_ninfo * sizeof *page_dir);
456
457 /* register the new size */
458 malloc_ninfo = i * malloc_pagesize / sizeof *page_dir;
459
460 /* swap the pointers */
461 old = page_dir;
462 page_dir = new;
463
464 /* Now free the old stuff */
465 munmap(old, oldlen);
466 return 1;
467}
468
469/*
470 * Initialize the world
471 */
472static void
473malloc_init ()
474{
475 char *p, b[64];
476 int i, j;
477 int save_errno = errno;
478
479 THREAD_LOCK_INIT();
480
481 INIT_MMAP();
482
483#ifdef MALLOC_EXTRA_SANITY
484 malloc_junk = 1;
485#endif /* MALLOC_EXTRA_SANITY */
486
487 for (i = 0; i < 3; i++) {
488 if (i == 0) {
489 j = readlink("/etc/malloc.conf", b, sizeof b - 1);
490 if (j <= 0)
491 continue;
492 b[j] = '\0';
493 p = b;
494 } else if (i == 1) {
495 if (issetugid() == 0)
496 p = getenv("MALLOC_OPTIONS");
497 else
498 continue;
499 } else if (i == 2) {
500 p = malloc_options;
501 }
502 for (; p && *p; p++) {
503 switch (*p) {
504 case '>': malloc_cache <<= 1; break;
505 case '<': malloc_cache >>= 1; break;
506 case 'a': malloc_abort = 0; break;
507 case 'A': malloc_abort = 1; break;
508#ifdef MALLOC_STATS
509 case 'd': malloc_stats = 0; break;
510 case 'D': malloc_stats = 1; break;
511#endif /* MALLOC_STATS */
512#ifdef __FreeBSD__
513 case 'h': malloc_hint = 0; break;
514 case 'H': malloc_hint = 1; break;
515#endif /* __FreeBSD__ */
516 case 'r': malloc_realloc = 0; break;
517 case 'R': malloc_realloc = 1; break;
518 case 'j': malloc_junk = 0; break;
519 case 'J': malloc_junk = 1; break;
520 case 'n': malloc_silent = 0; break;
521 case 'N': malloc_silent = 1; break;
522#ifdef __FreeBSD__
523 case 'u': malloc_utrace = 0; break;
524 case 'U': malloc_utrace = 1; break;
525#endif /* __FreeBSD__ */
526 case 'x': malloc_xmalloc = 0; break;
527 case 'X': malloc_xmalloc = 1; break;
528 case 'z': malloc_zero = 0; break;
529 case 'Z': malloc_zero = 1; break;
530 default:
531 j = malloc_abort;
532 malloc_abort = 0;
533 wrtwarning("unknown char in MALLOC_OPTIONS\n");
534 malloc_abort = j;
535 break;
536 }
537 }
538 }
539
540 UTRACE(0, 0, 0);
541
542 /*
543 * We want junk in the entire allocation, and zero only in the part
544 * the user asked for.
545 */
546 if (malloc_zero)
547 malloc_junk=1;
548
549#ifdef MALLOC_STATS
550 if (malloc_stats)
551 atexit(malloc_exit);
552#endif /* MALLOC_STATS */
553
554 /* Allocate one page for the page directory */
555 page_dir = (struct pginfo **) MMAP(malloc_pagesize);
556
557 if (page_dir == (struct pginfo **) -1)
558 wrterror("mmap(2) failed, check limits.\n");
559
560 /*
561 * We need a maximum of malloc_pageshift buckets, steal these from the
562 * front of the page_directory;
563 */
564 malloc_origo = ((u_long)pageround((u_long)sbrk(0))) >> malloc_pageshift;
565 malloc_origo -= malloc_pageshift;
566
567 malloc_ninfo = malloc_pagesize / sizeof *page_dir;
568
569 /* Been here, done that */
570 malloc_started++;
571
572 /* Recalculate the cache size in bytes, and make sure it's nonzero */
573
574 if (!malloc_cache)
575 malloc_cache++;
576
577 malloc_cache <<= malloc_pageshift;
578
579 /*
580 * This is a nice hack from Kaleb Keithly (kaleb@x.org).
581 * We can sbrk(2) further back when we keep this on a low address.
582 */
583 px = (struct pgfree *) imalloc (sizeof *px);
584 errno = save_errno;
585}
586
587/*
588 * Allocate a number of complete pages
589 */
590static void *
591malloc_pages(size)
592 size_t size;
593{
594 void *p, *delay_free = 0;
595 int i;
596 struct pgfree *pf;
597 u_long index;
598
599 size = pageround(size);
600
601 p = 0;
602 /* Look for free pages before asking for more */
603 for(pf = free_list.next; pf; pf = pf->next) {
604
605#ifdef MALLOC_EXTRA_SANITY
606 if (pf->size & malloc_pagemask)
607 wrterror("(ES): junk length entry on free_list\n");
608 if (!pf->size)
609 wrterror("(ES): zero length entry on free_list\n");
610 if (pf->page == pf->end)
611 wrterror("(ES): zero entry on free_list\n");
612 if (pf->page > pf->end)
613 wrterror("(ES): sick entry on free_list\n");
614 if ((void*)pf->page >= (void*)sbrk(0))
615 wrterror("(ES): entry on free_list past brk\n");
616 if (page_dir[ptr2index(pf->page)] != MALLOC_FREE)
617 wrterror("(ES): non-free first page on free-list\n");
618 if (page_dir[ptr2index(pf->end)-1] != MALLOC_FREE)
619 wrterror("(ES): non-free last page on free-list\n");
620#endif /* MALLOC_EXTRA_SANITY */
621
622 if (pf->size < size)
623 continue;
624
625 if (pf->size == size) {
626 p = pf->page;
627 if (pf->next)
628 pf->next->prev = pf->prev;
629 pf->prev->next = pf->next;
630 delay_free = pf;
631 break;
632 }
633
634 p = pf->page;
635 pf->page = (char *)pf->page + size;
636 pf->size -= size;
637 break;
638 }
639
640#ifdef MALLOC_EXTRA_SANITY
641 if (p && page_dir[ptr2index(p)] != MALLOC_FREE)
642 wrterror("(ES): allocated non-free page on free-list\n");
643#endif /* MALLOC_EXTRA_SANITY */
644
645 size >>= malloc_pageshift;
646
647 /* Map new pages */
648 if (!p)
649 p = map_pages(size);
650
651 if (p) {
652
653 index = ptr2index(p);
654 page_dir[index] = MALLOC_FIRST;
655 for (i=1;i<size;i++)
656 page_dir[index+i] = MALLOC_FOLLOW;
657
658 if (malloc_junk)
659 memset(p, SOME_JUNK, size << malloc_pageshift);
660 }
661
662 if (delay_free) {
663 if (!px)
664 px = delay_free;
665 else
666 ifree(delay_free);
667 }
668
669 return p;
670}
671
672/*
673 * Allocate a page of fragments
674 */
675
676static __inline__ int
677malloc_make_chunks(bits)
678 int bits;
679{
680 struct pginfo *bp;
681 void *pp;
682 int i, k, l;
683
684 /* Allocate a new bucket */
685 pp = malloc_pages((size_t)malloc_pagesize);
686 if (!pp)
687 return 0;
688
689 /* Find length of admin structure */
690 l = sizeof *bp - sizeof(u_long);
691 l += sizeof(u_long) *
692 (((malloc_pagesize >> bits)+MALLOC_BITS-1) / MALLOC_BITS);
693
694 /* Don't waste more than two chunks on this */
695 if ((1UL<<(bits)) <= l+l) {
696 bp = (struct pginfo *)pp;
697 } else {
698 bp = (struct pginfo *)imalloc(l);
699 if (!bp) {
700 ifree(pp);
701 return 0;
702 }
703 }
704
705 bp->size = (1UL<<bits);
706 bp->shift = bits;
707 bp->total = bp->free = malloc_pagesize >> bits;
708 bp->page = pp;
709
710 /* set all valid bits in the bitmap */
711 k = bp->total;
712 i = 0;
713
714 /* Do a bunch at a time */
715 for(;k-i >= MALLOC_BITS; i += MALLOC_BITS)
716 bp->bits[i / MALLOC_BITS] = ~0UL;
717
718 for(; i < k; i++)
719 bp->bits[i/MALLOC_BITS] |= 1UL<<(i%MALLOC_BITS);
720
721 if (bp == bp->page) {
722 /* Mark the ones we stole for ourselves */
723 for(i=0;l > 0;i++) {
724 bp->bits[i/MALLOC_BITS] &= ~(1UL<<(i%MALLOC_BITS));
725 bp->free--;
726 bp->total--;
727 l -= (1 << bits);
728 }
729 }
730
731 /* MALLOC_LOCK */
732
733 page_dir[ptr2index(pp)] = bp;
734
735 bp->next = page_dir[bits];
736 page_dir[bits] = bp;
737
738 /* MALLOC_UNLOCK */
739
740 return 1;
741}
742
743/*
744 * Allocate a fragment
745 */
746static void *
747malloc_bytes(size)
748 size_t size;
749{
750 int i,j;
751 u_long u;
752 struct pginfo *bp;
753 int k;
754 u_long *lp;
755
756 /* Don't bother with anything less than this */
757 if (size < malloc_minsize)
758 size = malloc_minsize;
759
760 /* Find the right bucket */
761 j = 1;
762 i = size-1;
763 while (i >>= 1)
764 j++;
765
766 /* If it's empty, make a page more of that size chunks */
767 if (!page_dir[j] && !malloc_make_chunks(j))
768 return 0;
769
770 bp = page_dir[j];
771
772 /* Find first word of bitmap which isn't empty */
773 for (lp = bp->bits; !*lp; lp++)
774 ;
775
776 /* Find that bit, and tweak it */
777 u = 1;
778 k = 0;
779 while (!(*lp & u)) {
780 u += u;
781 k++;
782 }
783 *lp ^= u;
784
785 /* If there are no more free, remove from free-list */
786 if (!--bp->free) {
787 page_dir[j] = bp->next;
788 bp->next = 0;
789 }
790
791 /* Adjust to the real offset of that chunk */
792 k += (lp-bp->bits)*MALLOC_BITS;
793 k <<= bp->shift;
794
795 if (malloc_junk)
796 memset((char *)bp->page + k, SOME_JUNK, bp->size);
797
798 return (u_char *)bp->page + k;
799}
800
801/*
802 * Allocate a piece of memory
803 */
804static void *
805imalloc(size)
806 size_t size;
807{
808 void *result;
809
810 if (!malloc_started)
811 malloc_init();
812
813 if (suicide)
814 abort();
815
816 if ((size + malloc_pagesize) < size) /* Check for overflow */
817 result = 0;
818 else if (size <= malloc_maxsize)
819 result = malloc_bytes(size);
820 else
821 result = malloc_pages(size);
822
823 if (malloc_abort && !result)
824 wrterror("allocation failed.\n");
825
826 if (malloc_zero && result)
827 memset(result, 0, size);
828
829 return result;
830}
831
832/*
833 * Change the size of an allocation.
834 */
835static void *
836irealloc(ptr, size)
837 void *ptr;
838 size_t size;
839{
840 void *p;
841 u_long osize, index;
842 struct pginfo **mp;
843 int i;
844
845 if (suicide)
846 abort();
847
848 if (!malloc_started) {
849 wrtwarning("malloc() has never been called.\n");
850 return 0;
851 }
852
853 index = ptr2index(ptr);
854
855 if (index < malloc_pageshift) {
856 wrtwarning("junk pointer, too low to make sense.\n");
857 return 0;
858 }
859
860 if (index > last_index) {
861 wrtwarning("junk pointer, too high to make sense.\n");
862 return 0;
863 }
864
865 mp = &page_dir[index];
866
867 if (*mp == MALLOC_FIRST) { /* Page allocation */
868
869 /* Check the pointer */
870 if ((u_long)ptr & malloc_pagemask) {
871 wrtwarning("modified (page-) pointer.\n");
872 return 0;
873 }
874
875 /* Find the size in bytes */
876 for (osize = malloc_pagesize; *++mp == MALLOC_FOLLOW;)
877 osize += malloc_pagesize;
878
879 if (!malloc_realloc && /* unless we have to, */
880 size <= osize && /* .. or are too small, */
881 size > (osize - malloc_pagesize)) { /* .. or can free a page, */
882 return ptr; /* don't do anything. */
883 }
884
885 } else if (*mp >= MALLOC_MAGIC) { /* Chunk allocation */
886
887 /* Check the pointer for sane values */
888 if (((u_long)ptr & ((*mp)->size-1))) {
889 wrtwarning("modified (chunk-) pointer.\n");
890 return 0;
891 }
892
893 /* Find the chunk index in the page */
894 i = ((u_long)ptr & malloc_pagemask) >> (*mp)->shift;
895
896 /* Verify that it isn't a free chunk already */
897 if ((*mp)->bits[i/MALLOC_BITS] & (1UL<<(i%MALLOC_BITS))) {
898 wrtwarning("chunk is already free.\n");
899 return 0;
900 }
901
902 osize = (*mp)->size;
903
904 if (!malloc_realloc && /* Unless we have to, */
905 size < osize && /* ..or are too small, */
906 (size > osize/2 || /* ..or could use a smaller size, */
907 osize == malloc_minsize)) { /* ..(if there is one) */
908 return ptr; /* ..Don't do anything */
909 }
910
911 } else {
912 wrtwarning("pointer to wrong page.\n");
913 return 0;
914 }
915
916 p = imalloc(size);
917
918 if (p) {
919 /* copy the lesser of the two sizes, and free the old one */
920 if (osize < size)
921 memcpy(p, ptr, osize);
922 else
923 memcpy(p, ptr, size);
924 ifree(ptr);
925 }
926 return p;
927}
928
929/*
930 * Free a sequence of pages
931 */
932
933static __inline__ void
934free_pages(ptr, index, info)
935 void *ptr;
936 int index;
937 struct pginfo *info;
938{
939 int i;
940 struct pgfree *pf, *pt=0;
941 u_long l;
942 void *tail;
943
944 if (info == MALLOC_FREE) {
945 wrtwarning("page is already free.\n");
946 return;
947 }
948
949 if (info != MALLOC_FIRST) {
950 wrtwarning("pointer to wrong page.\n");
951 return;
952 }
953
954 if ((u_long)ptr & malloc_pagemask) {
955 wrtwarning("modified (page-) pointer.\n");
956 return;
957 }
958
959 /* Count how many pages and mark them free at the same time */
960 page_dir[index] = MALLOC_FREE;
961 for (i = 1; page_dir[index+i] == MALLOC_FOLLOW; i++)
962 page_dir[index + i] = MALLOC_FREE;
963
964 l = i << malloc_pageshift;
965
966 if (malloc_junk)
967 memset(ptr, SOME_JUNK, l);
968
969#ifdef __FreeBSD__
970 if (malloc_hint)
971 madvise(ptr, l, MADV_FREE);
972#endif
973
974 tail = (char *)ptr+l;
975
976 /* add to free-list */
977 if (!px)
978 px = imalloc(sizeof *px); /* This cannot fail... */
979 px->page = ptr;
980 px->end = tail;
981 px->size = l;
982 if (!free_list.next) {
983
984 /* Nothing on free list, put this at head */
985 px->next = free_list.next;
986 px->prev = &free_list;
987 free_list.next = px;
988 pf = px;
989 px = 0;
990
991 } else {
992
993 /* Find the right spot, leave pf pointing to the modified entry. */
994 tail = (char *)ptr+l;
995
996 for(pf = free_list.next; pf->end < ptr && pf->next; pf = pf->next)
997 ; /* Race ahead here */
998
999 if (pf->page > tail) {
1000 /* Insert before entry */
1001 px->next = pf;
1002 px->prev = pf->prev;
1003 pf->prev = px;
1004 px->prev->next = px;
1005 pf = px;
1006 px = 0;
1007 } else if (pf->end == ptr ) {
1008 /* Append to the previous entry */
1009 pf->end = (char *)pf->end + l;
1010 pf->size += l;
1011 if (pf->next && pf->end == pf->next->page ) {
1012 /* And collapse the next too. */
1013 pt = pf->next;
1014 pf->end = pt->end;
1015 pf->size += pt->size;
1016 pf->next = pt->next;
1017 if (pf->next)
1018 pf->next->prev = pf;
1019 }
1020 } else if (pf->page == tail) {
1021 /* Prepend to entry */
1022 pf->size += l;
1023 pf->page = ptr;
1024 } else if (!pf->next) {
1025 /* Append at tail of chain */
1026 px->next = 0;
1027 px->prev = pf;
1028 pf->next = px;
1029 pf = px;
1030 px = 0;
1031 } else {
1032 wrterror("freelist is destroyed.\n");
1033 }
1034 }
1035
1036 /* Return something to OS ? */
1037 if (!pf->next && /* If we're the last one, */
1038 pf->size > malloc_cache && /* ..and the cache is full, */
1039 pf->end == malloc_brk && /* ..and none behind us, */
1040 malloc_brk == sbrk(0)) { /* ..and it's OK to do... */
1041
1042 /*
1043 * Keep the cache intact. Notice that the '>' above guarantees that
1044 * the pf will always have at least one page afterwards.
1045 */
1046 pf->end = (char *)pf->page + malloc_cache;
1047 pf->size = malloc_cache;
1048
1049 brk(pf->end);
1050 malloc_brk = pf->end;
1051
1052 index = ptr2index(pf->end);
1053 last_index = index - 1;
1054
1055 for(i=index;i <= last_index;)
1056 page_dir[i++] = MALLOC_NOT_MINE;
1057
1058 /* XXX: We could realloc/shrink the pagedir here I guess. */
1059 }
1060 if (pt)
1061 ifree(pt);
1062}
1063
1064/*
1065 * Free a chunk, and possibly the page it's on, if the page becomes empty.
1066 */
1067
1068/* ARGSUSED */
1069static __inline__ void
1070free_bytes(ptr, index, info)
1071 void *ptr;
1072 int index;
1073 struct pginfo *info;
1074{
1075 int i;
1076 struct pginfo **mp;
1077 void *vp;
1078
1079 /* Find the chunk number on the page */
1080 i = ((u_long)ptr & malloc_pagemask) >> info->shift;
1081
1082 if (((u_long)ptr & (info->size-1))) {
1083 wrtwarning("modified (chunk-) pointer.\n");
1084 return;
1085 }
1086
1087 if (info->bits[i/MALLOC_BITS] & (1UL<<(i%MALLOC_BITS))) {
1088 wrtwarning("chunk is already free.\n");
1089 return;
1090 }
1091
1092 if (malloc_junk)
1093 memset(ptr, SOME_JUNK, info->size);
1094
1095 info->bits[i/MALLOC_BITS] |= 1UL<<(i%MALLOC_BITS);
1096 info->free++;
1097
1098 mp = page_dir + info->shift;
1099
1100 if (info->free == 1) {
1101
1102 /* Page became non-full */
1103
1104 mp = page_dir + info->shift;
1105 /* Insert in address order */
1106 while (*mp && (*mp)->next && (*mp)->next->page < info->page)
1107 mp = &(*mp)->next;
1108 info->next = *mp;
1109 *mp = info;
1110 return;
1111 }
1112
1113 if (info->free != info->total)
1114 return;
1115
1116 /* Find & remove this page in the queue */
1117 while (*mp != info) {
1118 mp = &((*mp)->next);
1119#ifdef MALLOC_EXTRA_SANITY
1120 if (!*mp)
1121 wrterror("(ES): Not on queue\n");
1122#endif /* MALLOC_EXTRA_SANITY */
1123 }
1124 *mp = info->next;
1125
1126 /* Free the page & the info structure if need be */
1127 page_dir[ptr2index(info->page)] = MALLOC_FIRST;
1128 vp = info->page; /* Order is important ! */
1129 if(vp != (void*)info)
1130 ifree(info);
1131 ifree(vp);
1132}
1133
1134static void
1135ifree(ptr)
1136 void *ptr;
1137{
1138 struct pginfo *info;
1139 int index;
1140
1141 /* This is legal */
1142 if (!ptr)
1143 return;
1144
1145 if (!malloc_started) {
1146 wrtwarning("malloc() has never been called.\n");
1147 return;
1148 }
1149
1150 /* If we're already sinking, don't make matters any worse. */
1151 if (suicide)
1152 return;
1153
1154 index = ptr2index(ptr);
1155
1156 if (index < malloc_pageshift) {
1157 wrtwarning("junk pointer, too low to make sense.\n");
1158 return;
1159 }
1160
1161 if (index > last_index) {
1162 wrtwarning("junk pointer, too high to make sense.\n");
1163 return;
1164 }
1165
1166 info = page_dir[index];
1167
1168 if (info < MALLOC_MAGIC)
1169 free_pages(ptr, index, info);
1170 else
1171 free_bytes(ptr, index, info);
1172 return;
1173}
1174
1175/*
1176 * These are the public exported interface routines.
1177 */
1178
1179static int malloc_active;
1180
1181void *
1182malloc(size_t size)
1183{
1184 register void *r;
1185
1186 malloc_func = " in malloc():";
1187 THREAD_LOCK();
1188 if (malloc_active++) {
1189 wrtwarning("recursive call.\n");
1190 malloc_active--;
1191 return (0);
1192 }
1193 r = imalloc(size);
1194 UTRACE(0, size, r);
1195 malloc_active--;
1196 THREAD_UNLOCK();
1197 if (malloc_xmalloc && !r)
1198 wrterror("out of memory.\n");
1199 return (r);
1200}
1201
1202void
1203free(void *ptr)
1204{
1205 malloc_func = " in free():";
1206 THREAD_LOCK();
1207 if (malloc_active++) {
1208 wrtwarning("recursive call.\n");
1209 malloc_active--;
1210 return;
1211 }
1212 ifree(ptr);
1213 UTRACE(ptr, 0, 0);
1214 malloc_active--;
1215 THREAD_UNLOCK();
1216 return;
1217}
1218
1219void *
1220realloc(void *ptr, size_t size)
1221{
1222 register void *r;
1223
1224 malloc_func = " in realloc():";
1225 THREAD_LOCK();
1226 if (malloc_active++) {
1227 wrtwarning("recursive call.\n");
1228 malloc_active--;
1229 return (0);
1230 }
1231 if (!ptr) {
1232 r = imalloc(size);
1233 } else {
1234 r = irealloc(ptr, size);
1235 }
1236 UTRACE(ptr, size, r);
1237 malloc_active--;
1238 THREAD_UNLOCK();
1239 if (malloc_xmalloc && !r)
1240 wrterror("out of memory.\n");
1241 return (r);
1242}
diff --git a/src/lib/libc/stdlib/memory.3 b/src/lib/libc/stdlib/memory.3
new file mode 100644
index 0000000000..712c7c45d2
--- /dev/null
+++ b/src/lib/libc/stdlib/memory.3
@@ -0,0 +1,70 @@
1.\" Copyright (c) 1991 Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\" notice, this list of conditions and the following disclaimer.
9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\" notice, this list of conditions and the following disclaimer in the
11.\" documentation and/or other materials provided with the distribution.
12.\" 3. All advertising materials mentioning features or use of this software
13.\" must display the following acknowledgement:
14.\" This product includes software developed by the University of
15.\" California, Berkeley and its contributors.
16.\" 4. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" $OpenBSD: memory.3,v 1.2 1996/08/19 08:33:37 tholo Exp $
33.\"
34.Dd May 2, 1991
35.Dt MEMORY 3
36.Os BSD 4
37.Sh NAME
38.Nm malloc ,
39.Nm free ,
40.Nm realloc ,
41.Nm calloc ,
42.Nm alloca
43.Nd general memory allocation operations
44.Sh SYNOPSIS
45.Fd #include <stdlib.h>
46.Ft void *
47.Fn malloc "size_t size"
48.Ft void
49.Fn free "void *ptr"
50.Ft void *
51.Fn realloc "void *ptr" "size_t size"
52.Ft void *
53.Fn calloc "size_t nelem" "size_t elsize"
54.Ft void *
55.Fn alloca "size_t size"
56.Sh DESCRIPTION
57These functions allocate and free memory for the calling process.
58They are described in the
59individual manual pages.
60.Sh SEE ALSO
61.Xr calloc 3 ,
62.Xr free 3 ,
63.Xr malloc 3 ,
64.Xr realloc 3 ,
65.Xr alloca 3 ,
66.Sh STANDARDS
67These functions, with the exception of
68.Fn alloca
69conform to
70.St -ansiC .
diff --git a/src/lib/libc/stdlib/merge.c b/src/lib/libc/stdlib/merge.c
new file mode 100644
index 0000000000..0a1015ad9d
--- /dev/null
+++ b/src/lib/libc/stdlib/merge.c
@@ -0,0 +1,347 @@
1/*-
2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Peter McIlroy.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: merge.c,v 1.3 1996/09/15 09:31:50 tholo Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41/*
42 * Hybrid exponential search/linear search merge sort with hybrid
43 * natural/pairwise first pass. Requires about .3% more comparisons
44 * for random data than LSMS with pairwise first pass alone.
45 * It works for objects as small as two bytes.
46 */
47
48#define NATURAL
49#define THRESHOLD 16 /* Best choice for natural merge cut-off. */
50
51/* #define NATURAL to get hybrid natural merge.
52 * (The default is pairwise merging.)
53 */
54
55#include <sys/types.h>
56
57#include <errno.h>
58#include <stdlib.h>
59#include <string.h>
60
61static void setup __P((u_char *, u_char *, size_t, size_t, int (*)()));
62static void insertionsort __P((u_char *, size_t, size_t, int (*)()));
63
64#define ISIZE sizeof(int)
65#define PSIZE sizeof(u_char *)
66#define ICOPY_LIST(src, dst, last) \
67 do \
68 *(int*)dst = *(int*)src, src += ISIZE, dst += ISIZE; \
69 while(src < last)
70#define ICOPY_ELT(src, dst, i) \
71 do \
72 *(int*) dst = *(int*) src, src += ISIZE, dst += ISIZE; \
73 while (i -= ISIZE)
74
75#define CCOPY_LIST(src, dst, last) \
76 do \
77 *dst++ = *src++; \
78 while (src < last)
79#define CCOPY_ELT(src, dst, i) \
80 do \
81 *dst++ = *src++; \
82 while (i -= 1)
83
84/*
85 * Find the next possible pointer head. (Trickery for forcing an array
86 * to do double duty as a linked list when objects do not align with word
87 * boundaries.
88 */
89/* Assumption: PSIZE is a power of 2. */
90#define EVAL(p) (u_char **) \
91 ((u_char *)0 + \
92 (((u_char *)p + PSIZE - 1 - (u_char *) 0) & ~(PSIZE - 1)))
93
94/*
95 * Arguments are as for qsort.
96 */
97int
98mergesort(base, nmemb, size, cmp)
99 void *base;
100 size_t nmemb;
101 register size_t size;
102 int (*cmp) __P((const void *, const void *));
103{
104 register int i, sense;
105 int big, iflag;
106 register u_char *f1, *f2, *t, *b, *tp2, *q, *l1, *l2;
107 u_char *list2, *list1, *p2, *p, *last, **p1;
108
109 if (size < PSIZE / 2) { /* Pointers must fit into 2 * size. */
110 errno = EINVAL;
111 return (-1);
112 }
113
114 /*
115 * XXX
116 * Stupid subtraction for the Cray.
117 */
118 iflag = 0;
119 if (!(size % ISIZE) && !(((char *)base - (char *)0) % ISIZE))
120 iflag = 1;
121
122 if ((list2 = malloc(nmemb * size + PSIZE)) == NULL)
123 return (-1);
124
125 list1 = base;
126 setup(list1, list2, nmemb, size, cmp);
127 last = list2 + nmemb * size;
128 i = big = 0;
129 while (*EVAL(list2) != last) {
130 l2 = list1;
131 p1 = EVAL(list1);
132 for (tp2 = p2 = list2; p2 != last; p1 = EVAL(l2)) {
133 p2 = *EVAL(p2);
134 f1 = l2;
135 f2 = l1 = list1 + (p2 - list2);
136 if (p2 != last)
137 p2 = *EVAL(p2);
138 l2 = list1 + (p2 - list2);
139 while (f1 < l1 && f2 < l2) {
140 if ((*cmp)(f1, f2) <= 0) {
141 q = f2;
142 b = f1, t = l1;
143 sense = -1;
144 } else {
145 q = f1;
146 b = f2, t = l2;
147 sense = 0;
148 }
149 if (!big) { /* here i = 0 */
150 while ((b += size) < t && cmp(q, b) >sense)
151 if (++i == 6) {
152 big = 1;
153 goto EXPONENTIAL;
154 }
155 } else {
156EXPONENTIAL: for (i = size; ; i <<= 1)
157 if ((p = (b + i)) >= t) {
158 if ((p = t - size) > b &&
159 (*cmp)(q, p) <= sense)
160 t = p;
161 else
162 b = p;
163 break;
164 } else if ((*cmp)(q, p) <= sense) {
165 t = p;
166 if (i == size)
167 big = 0;
168 goto FASTCASE;
169 } else
170 b = p;
171 while (t > b+size) {
172 i = (((t - b) / size) >> 1) * size;
173 if ((*cmp)(q, p = b + i) <= sense)
174 t = p;
175 else
176 b = p;
177 }
178 goto COPY;
179FASTCASE: while (i > size)
180 if ((*cmp)(q,
181 p = b + (i >>= 1)) <= sense)
182 t = p;
183 else
184 b = p;
185COPY: b = t;
186 }
187 i = size;
188 if (q == f1) {
189 if (iflag) {
190 ICOPY_LIST(f2, tp2, b);
191 ICOPY_ELT(f1, tp2, i);
192 } else {
193 CCOPY_LIST(f2, tp2, b);
194 CCOPY_ELT(f1, tp2, i);
195 }
196 } else {
197 if (iflag) {
198 ICOPY_LIST(f1, tp2, b);
199 ICOPY_ELT(f2, tp2, i);
200 } else {
201 CCOPY_LIST(f1, tp2, b);
202 CCOPY_ELT(f2, tp2, i);
203 }
204 }
205 }
206 if (f2 < l2) {
207 if (iflag)
208 ICOPY_LIST(f2, tp2, l2);
209 else
210 CCOPY_LIST(f2, tp2, l2);
211 } else if (f1 < l1) {
212 if (iflag)
213 ICOPY_LIST(f1, tp2, l1);
214 else
215 CCOPY_LIST(f1, tp2, l1);
216 }
217 *p1 = l2;
218 }
219 tp2 = list1; /* swap list1, list2 */
220 list1 = list2;
221 list2 = tp2;
222 last = list2 + nmemb*size;
223 }
224 if (base == list2) {
225 memmove(list2, list1, nmemb*size);
226 list2 = list1;
227 }
228 free(list2);
229 return (0);
230}
231
232#define swap(a, b) { \
233 s = b; \
234 i = size; \
235 do { \
236 tmp = *a; *a++ = *s; *s++ = tmp; \
237 } while (--i); \
238 a -= size; \
239 }
240#define reverse(bot, top) { \
241 s = top; \
242 do { \
243 i = size; \
244 do { \
245 tmp = *bot; *bot++ = *s; *s++ = tmp; \
246 } while (--i); \
247 s -= size2; \
248 } while(bot < s); \
249}
250
251/*
252 * Optional hybrid natural/pairwise first pass. Eats up list1 in runs of
253 * increasing order, list2 in a corresponding linked list. Checks for runs
254 * when THRESHOLD/2 pairs compare with same sense. (Only used when NATURAL
255 * is defined. Otherwise simple pairwise merging is used.)
256 */
257void
258setup(list1, list2, n, size, cmp)
259 size_t n, size;
260 int (*cmp) __P((const void *, const void *));
261 u_char *list1, *list2;
262{
263 int i, length, size2, tmp, sense;
264 u_char *f1, *f2, *s, *l2, *last, *p2;
265
266 size2 = size*2;
267 if (n <= 5) {
268 insertionsort(list1, n, size, cmp);
269 *EVAL(list2) = (u_char*) list2 + n*size;
270 return;
271 }
272 /*
273 * Avoid running pointers out of bounds; limit n to evens
274 * for simplicity.
275 */
276 i = 4 + (n & 1);
277 insertionsort(list1 + (n - i) * size, i, size, cmp);
278 last = list1 + size * (n - i);
279 *EVAL(list2 + (last - list1)) = list2 + n * size;
280
281#ifdef NATURAL
282 p2 = list2;
283 f1 = list1;
284 sense = (cmp(f1, f1 + size) > 0);
285 for (; f1 < last; sense = !sense) {
286 length = 2;
287 /* Find pairs with same sense. */
288 for (f2 = f1 + size2; f2 < last; f2 += size2) {
289 if ((cmp(f2, f2+ size) > 0) != sense)
290 break;
291 length += 2;
292 }
293 if (length < THRESHOLD) { /* Pairwise merge */
294 do {
295 p2 = *EVAL(p2) = f1 + size2 - list1 + list2;
296 if (sense > 0)
297 swap (f1, f1 + size);
298 } while ((f1 += size2) < f2);
299 } else { /* Natural merge */
300 l2 = f2;
301 for (f2 = f1 + size2; f2 < l2; f2 += size2) {
302 if ((cmp(f2-size, f2) > 0) != sense) {
303 p2 = *EVAL(p2) = f2 - list1 + list2;
304 if (sense > 0)
305 reverse(f1, f2-size);
306 f1 = f2;
307 }
308 }
309 if (sense > 0)
310 reverse (f1, f2-size);
311 f1 = f2;
312 if (f2 < last || cmp(f2 - size, f2) > 0)
313 p2 = *EVAL(p2) = f2 - list1 + list2;
314 else
315 p2 = *EVAL(p2) = list2 + n*size;
316 }
317 }
318#else /* pairwise merge only. */
319 for (f1 = list1, p2 = list2; f1 < last; f1 += size2) {
320 p2 = *EVAL(p2) = p2 + size2;
321 if (cmp (f1, f1 + size) > 0)
322 swap(f1, f1 + size);
323 }
324#endif /* NATURAL */
325}
326
327/*
328 * This is to avoid out-of-bounds addresses in sorting the
329 * last 4 elements.
330 */
331static void
332insertionsort(a, n, size, cmp)
333 u_char *a;
334 size_t n, size;
335 int (*cmp) __P((const void *, const void *));
336{
337 u_char *ai, *s, *t, *u, tmp;
338 int i;
339
340 for (ai = a+size; --n >= 1; ai += size)
341 for (t = ai; t > a; t -= size) {
342 u = t - size;
343 if (cmp(u, t) <= 0)
344 break;
345 swap(u, t);
346 }
347}
diff --git a/src/lib/libc/stdlib/mrand48.c b/src/lib/libc/stdlib/mrand48.c
new file mode 100644
index 0000000000..cd34260b5c
--- /dev/null
+++ b/src/lib/libc/stdlib/mrand48.c
@@ -0,0 +1,27 @@
1/*
2 * Copyright (c) 1993 Martin Birgmeier
3 * All rights reserved.
4 *
5 * You may redistribute unmodified or modified versions of this source
6 * code provided that the above copyright notice and this and the
7 * following conditions are retained.
8 *
9 * This software is provided ``as is'', and comes with no warranties
10 * of any kind. I shall in no event be liable for anything that happens
11 * to anyone/anything when using this software.
12 */
13
14#if defined(LIBC_SCCS) && !defined(lint)
15static char rcsid[] = "$OpenBSD: mrand48.c,v 1.2 1996/08/19 08:33:39 tholo Exp $";
16#endif /* LIBC_SCCS and not lint */
17
18#include "rand48.h"
19
20extern unsigned short __rand48_seed[3];
21
22long
23mrand48(void)
24{
25 __dorand48(__rand48_seed);
26 return ((long) __rand48_seed[2] << 16) + (long) __rand48_seed[1];
27}
diff --git a/src/lib/libc/stdlib/multibyte.c b/src/lib/libc/stdlib/multibyte.c
new file mode 100644
index 0000000000..12e70c4a2c
--- /dev/null
+++ b/src/lib/libc/stdlib/multibyte.c
@@ -0,0 +1,130 @@
1/*
2 * Copyright (c) 1991 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: multibyte.c,v 1.2 1996/08/19 08:33:39 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <stdlib.h>
39
40/*
41 * Stub multibyte character functions.
42 * This cheezy implementation is fixed to the native single-byte
43 * character set.
44 */
45
46int
47mblen(s, n)
48 const char *s;
49 size_t n;
50{
51 if (s == NULL || *s == '\0')
52 return 0;
53 if (n == 0)
54 return -1;
55 return 1;
56}
57
58/*ARGSUSED*/
59int
60mbtowc(pwc, s, n)
61 wchar_t *pwc;
62 const char *s;
63 size_t n;
64{
65 if (s == NULL)
66 return 0;
67 if (n == 0)
68 return -1;
69 if (pwc)
70 *pwc = (wchar_t) *s;
71 return (*s != '\0');
72}
73
74/*ARGSUSED*/
75int
76#ifdef __STDC__
77wctomb(char *s, wchar_t wchar)
78#else
79wctomb(s, wchar)
80 char *s;
81 wchar_t wchar;
82#endif
83{
84 if (s == NULL)
85 return 0;
86
87 *s = (char) wchar;
88 return 1;
89}
90
91/*ARGSUSED*/
92size_t
93mbstowcs(pwcs, s, n)
94 wchar_t *pwcs;
95 const char *s;
96 size_t n;
97{
98 int count = 0;
99
100 if (n != 0) {
101 do {
102 if ((*pwcs++ = (wchar_t) *s++) == 0)
103 break;
104 count++;
105 } while (--n != 0);
106 }
107
108 return count;
109}
110
111/*ARGSUSED*/
112size_t
113wcstombs(s, pwcs, n)
114 char *s;
115 const wchar_t *pwcs;
116 size_t n;
117{
118 int count = 0;
119
120 if (n != 0) {
121 do {
122 if ((*s++ = (char) *pwcs++) == 0)
123 break;
124 count++;
125 } while (--n != 0);
126 }
127
128 return count;
129}
130
diff --git a/src/lib/libc/stdlib/nrand48.c b/src/lib/libc/stdlib/nrand48.c
new file mode 100644
index 0000000000..b1ec2cebb1
--- /dev/null
+++ b/src/lib/libc/stdlib/nrand48.c
@@ -0,0 +1,25 @@
1/*
2 * Copyright (c) 1993 Martin Birgmeier
3 * All rights reserved.
4 *
5 * You may redistribute unmodified or modified versions of this source
6 * code provided that the above copyright notice and this and the
7 * following conditions are retained.
8 *
9 * This software is provided ``as is'', and comes with no warranties
10 * of any kind. I shall in no event be liable for anything that happens
11 * to anyone/anything when using this software.
12 */
13
14#if defined(LIBC_SCCS) && !defined(lint)
15static char rcsid[] = "$OpenBSD: nrand48.c,v 1.2 1996/08/19 08:33:40 tholo Exp $";
16#endif /* LIBC_SCCS and not lint */
17
18#include "rand48.h"
19
20long
21nrand48(unsigned short xseed[3])
22{
23 __dorand48(xseed);
24 return ((long) xseed[2] << 15) + ((long) xseed[1] >> 1);
25}
diff --git a/src/lib/libc/stdlib/putenv.c b/src/lib/libc/stdlib/putenv.c
new file mode 100644
index 0000000000..d8c4886d4b
--- /dev/null
+++ b/src/lib/libc/stdlib/putenv.c
@@ -0,0 +1,58 @@
1/*-
2 * Copyright (c) 1988, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: putenv.c,v 1.2 1996/08/10 05:03:00 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <stdlib.h>
39#include <string.h>
40
41int
42putenv(str)
43 const char *str;
44{
45 char *p, *equal;
46 int rval;
47
48 if ((p = strdup(str)) == NULL)
49 return (-1);
50 if ((equal = strchr(p, '=')) == NULL) {
51 (void)free(p);
52 return (-1);
53 }
54 *equal = '\0';
55 rval = setenv(p, equal + 1, 1);
56 (void)free(p);
57 return (rval);
58}
diff --git a/src/lib/libc/stdlib/qabs.3 b/src/lib/libc/stdlib/qabs.3
new file mode 100644
index 0000000000..92a8bdc4b9
--- /dev/null
+++ b/src/lib/libc/stdlib/qabs.3
@@ -0,0 +1,61 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: qabs.3,v 1.2 1996/08/19 08:33:40 tholo Exp $
37.\"
38.Dd June 29, 1991
39.Dt QABS 3
40.Os
41.Sh NAME
42.Nm qabs
43.Nd return the absolute value of a quad integer
44.Sh SYNOPSIS
45.Fd #include <stdlib.h>
46.Ft quad_t
47.Fn qabs "quad_t j"
48.Sh DESCRIPTION
49The
50.Fn qabs
51function
52returns the absolute value of the quad integer
53.Ar j .
54.Sh SEE ALSO
55.Xr abs 3 ,
56.Xr labs 3 ,
57.Xr floor 3 ,
58.Xr cabs 3 ,
59.Xr math 3
60.Sh BUGS
61The absolute value of the most negative integer remains negative.
diff --git a/src/lib/libc/stdlib/qabs.c b/src/lib/libc/stdlib/qabs.c
new file mode 100644
index 0000000000..ccc42cbec6
--- /dev/null
+++ b/src/lib/libc/stdlib/qabs.c
@@ -0,0 +1,45 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: qabs.c,v 1.2 1996/08/19 08:33:40 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <stdlib.h>
39
40quad_t
41qabs(j)
42 quad_t j;
43{
44 return(j < 0 ? -j : j);
45}
diff --git a/src/lib/libc/stdlib/qdiv.3 b/src/lib/libc/stdlib/qdiv.3
new file mode 100644
index 0000000000..12aca0b1ea
--- /dev/null
+++ b/src/lib/libc/stdlib/qdiv.3
@@ -0,0 +1,65 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: qdiv.3,v 1.2 1996/08/19 08:33:41 tholo Exp $
37.\"
38.Dd June 29, 1991
39.Dt QDIV 3
40.Os
41.Sh NAME
42.Nm qdiv
43.Nd return quotient and remainder from division
44.Sh SYNOPSIS
45.Fd #include <stdlib.h>
46.Ft qdiv_t
47.Fn qdiv "quad_t num" "quad_t denom"
48.Sh DESCRIPTION
49The
50.Fn qdiv
51function
52computes the value
53.Ar num/denom
54and returns the quotient and remainder in a structure named
55.Ar qdiv_t
56that contains two
57.Em quad integer
58members named
59.Ar quot
60and
61.Ar rem .
62.Sh SEE ALSO
63.Xr div 3 ,
64.Xr ldiv 3 ,
65.Xr math 3
diff --git a/src/lib/libc/stdlib/qdiv.c b/src/lib/libc/stdlib/qdiv.c
new file mode 100644
index 0000000000..07e84cd649
--- /dev/null
+++ b/src/lib/libc/stdlib/qdiv.c
@@ -0,0 +1,58 @@
1/*
2 * Copyright (c) 1990 Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Chris Torek.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: qdiv.c,v 1.2 1996/08/19 08:33:41 tholo Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#include <stdlib.h> /* qdiv_t */
42
43qdiv_t
44qdiv(num, denom)
45 quad_t num, denom;
46{
47 qdiv_t r;
48
49 /* see div.c for comments */
50
51 r.quot = num / denom;
52 r.rem = num % denom;
53 if (num >= 0 && r.rem < 0) {
54 r.quot++;
55 r.rem -= denom;
56 }
57 return (r);
58}
diff --git a/src/lib/libc/stdlib/qsort.3 b/src/lib/libc/stdlib/qsort.3
new file mode 100644
index 0000000000..a65c5819d0
--- /dev/null
+++ b/src/lib/libc/stdlib/qsort.3
@@ -0,0 +1,233 @@
1.\" Copyright (c) 1990, 1991, 1993
2.\" The Regents of the University of California. All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: qsort.3,v 1.2 1996/08/19 08:33:42 tholo Exp $
37.\"
38.Dd June 4, 1993
39.Dt QSORT 3
40.Os
41.Sh NAME
42.Nm qsort, heapsort, mergesort
43.Nd sort functions
44.Sh SYNOPSIS
45.Fd #include <stdlib.h>
46.Ft void
47.Fn qsort "void *base" "size_t nmemb" "size_t size" "int (*compar)(const void *, const void *)"
48.Ft int
49.Fn heapsort "void *base" "size_t nmemb" "size_t size" "int (*compar)(const void *, const void *)"
50.Ft int
51.Fn mergesort "void *base" "size_t nmemb" "size_t size" "int (*compar)(const void *, const void *)"
52.Sh DESCRIPTION
53The
54.Fn qsort
55function is a modified partition-exchange sort, or quicksort.
56The
57.Fn heapsort
58function is a modified selection sort.
59The
60.Fn mergesort
61function is a modified merge sort with exponential search
62intended for sorting data with pre-existing order.
63.Pp
64The
65.Fn qsort
66and
67.Fn heapsort
68functions sort an array of
69.Fa nmemb
70objects, the initial member of which is pointed to by
71.Fa base .
72The size of each object is specified by
73.Fa size .
74.Fn Mergesort
75behaves similarly, but
76.Em requires
77that
78.Fa size
79be greater than
80.Dq "sizeof(void *) / 2" .
81.Pp
82The contents of the array
83.Fa base
84are sorted in ascending order according to
85a comparison function pointed to by
86.Fa compar ,
87which requires two arguments pointing to the objects being
88compared.
89.Pp
90The comparison function must return an integer less than, equal to, or
91greater than zero if the first argument is considered to be respectively
92less than, equal to, or greater than the second.
93.Pp
94The functions
95.Fn qsort
96and
97.Fn heapsort
98are
99.Em not
100stable, that is, if two members compare as equal, their order in
101the sorted array is undefined.
102The function
103.Fn mergesort
104is stable.
105.Pp
106The
107.Fn qsort
108function is an implementation of C.A.R. Hoare's ``quicksort'' algorithm,
109a variant of partition-exchange sorting; in particular, see D.E. Knuth's
110Algorithm Q.
111.Fn Qsort
112takes O N lg N average time.
113This implementation uses median selection to avoid its
114O N**2 worst-case behavior.
115.Pp
116The
117.Fn heapsort
118function is an implementation of J.W.J. William's ``heapsort'' algorithm,
119a variant of selection sorting; in particular, see D.E. Knuth's Algorithm H.
120.Fn Heapsort
121takes O N lg N worst-case time.
122Its
123.Em only
124advantage over
125.Fn qsort
126is that it uses almost no additional memory; while
127.Fn qsort
128does not allocate memory, it is implemented using recursion.
129.Pp
130The function
131.Fn mergesort
132requires additional memory of size
133.Fa nmemb *
134.Fa size
135bytes; it should be used only when space is not at a premium.
136.Fn Mergesort
137is optimized for data with pre-existing order; its worst case
138time is O N lg N; its best case is O N.
139.Pp
140Normally,
141.Fn qsort
142is faster than
143.Fn mergesort
144is faster than
145.Fn heapsort .
146Memory availability and pre-existing order in the data can make this
147untrue.
148.Sh RETURN VALUES
149The
150.Fn qsort
151function
152returns no value.
153.Pp
154Upon successful completion,
155.Fn heapsort
156and
157.Fn mergesort
158return 0.
159Otherwise, they return \-1 and the global variable
160.Va errno
161is set to indicate the error.
162.Sh ERRORS
163The
164.Fn heapsort
165function succeeds unless:
166.Bl -tag -width Er
167.It Bq Er EINVAL
168The
169.Fa size
170argument is zero, or,
171the
172.Fa size
173argument to
174.Fn mergesort
175is less than
176.Dq "sizeof(void *) / 2" .
177.It Bq Er ENOMEM
178.Fn Heapsort
179or
180.Fn mergesort
181were unable to allocate memory.
182.El
183.Sh COMPATIBILITY
184Previous versions of
185.Fn qsort
186did not permit the comparison routine itself to call
187.Fn qsort 3 .
188This is no longer true.
189.Sh SEE ALSO
190.Xr sort 1 ,
191.Xr radixsort 3
192.Rs
193.%A Hoare, C.A.R.
194.%D 1962
195.%T "Quicksort"
196.%J "The Computer Journal"
197.%V 5:1
198.%P pp. 10-15
199.Re
200.Rs
201.%A Williams, J.W.J
202.%D 1964
203.%T "Heapsort"
204.%J "Communications of the ACM"
205.%V 7:1
206.%P pp. 347-348
207.Re
208.Rs
209.%A Knuth, D.E.
210.%D 1968
211.%B "The Art of Computer Programming"
212.%V Vol. 3
213.%T "Sorting and Searching"
214.%P pp. 114-123, 145-149
215.Re
216.Rs
217.%A Mcilroy, P.M.
218.%T "Optimistic Sorting and Information Theoretic Complexity"
219.%J "Fourth Annual ACM-SIAM Symposium on Discrete Algorithms"
220.%V January 1992
221.Re
222.Rs
223.%A Bentley, J.L.
224.%T "Engineering a Sort Function"
225.%J "bentley@research.att.com"
226.%V January 1992
227.Re
228.Sh STANDARDS
229The
230.Fn qsort
231function
232conforms to
233.St -ansiC .
diff --git a/src/lib/libc/stdlib/qsort.c b/src/lib/libc/stdlib/qsort.c
new file mode 100644
index 0000000000..1c3020b595
--- /dev/null
+++ b/src/lib/libc/stdlib/qsort.c
@@ -0,0 +1,175 @@
1/*-
2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: qsort.c,v 1.5 1997/06/20 11:19:38 deraadt Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/types.h>
39#include <stdlib.h>
40
41static __inline char *med3 __P((char *, char *, char *, int (*)()));
42static __inline void swapfunc __P((char *, char *, int, int));
43
44#define min(a, b) (a) < (b) ? a : b
45
46/*
47 * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
48 */
49#define swapcode(TYPE, parmi, parmj, n) { \
50 long i = (n) / sizeof (TYPE); \
51 register TYPE *pi = (TYPE *) (parmi); \
52 register TYPE *pj = (TYPE *) (parmj); \
53 do { \
54 register TYPE t = *pi; \
55 *pi++ = *pj; \
56 *pj++ = t; \
57 } while (--i > 0); \
58}
59
60#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \
61 es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;
62
63static __inline void
64swapfunc(a, b, n, swaptype)
65 char *a, *b;
66 int n, swaptype;
67{
68 if (swaptype <= 1)
69 swapcode(long, a, b, n)
70 else
71 swapcode(char, a, b, n)
72}
73
74#define swap(a, b) \
75 if (swaptype == 0) { \
76 long t = *(long *)(a); \
77 *(long *)(a) = *(long *)(b); \
78 *(long *)(b) = t; \
79 } else \
80 swapfunc(a, b, es, swaptype)
81
82#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype)
83
84static __inline char *
85med3(a, b, c, cmp)
86 char *a, *b, *c;
87 int (*cmp)();
88{
89 return cmp(a, b) < 0 ?
90 (cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a ))
91 :(cmp(b, c) > 0 ? b : (cmp(a, c) < 0 ? a : c ));
92}
93
94void
95qsort(aa, n, es, cmp)
96 void *aa;
97 size_t n, es;
98 int (*cmp)();
99{
100 char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
101 int d, r, swaptype, swap_cnt;
102 register char *a = aa;
103
104loop: SWAPINIT(a, es);
105 swap_cnt = 0;
106 if (n < 7) {
107 for (pm = (char *)a + es; pm < (char *) a + n * es; pm += es)
108 for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
109 pl -= es)
110 swap(pl, pl - es);
111 return;
112 }
113 pm = (char *)a + (n / 2) * es;
114 if (n > 7) {
115 pl = (char *)a;
116 pn = (char *)a + (n - 1) * es;
117 if (n > 40) {
118 d = (n / 8) * es;
119 pl = med3(pl, pl + d, pl + 2 * d, cmp);
120 pm = med3(pm - d, pm, pm + d, cmp);
121 pn = med3(pn - 2 * d, pn - d, pn, cmp);
122 }
123 pm = med3(pl, pm, pn, cmp);
124 }
125 swap(a, pm);
126 pa = pb = (char *)a + es;
127
128 pc = pd = (char *)a + (n - 1) * es;
129 for (;;) {
130 while (pb <= pc && (r = cmp(pb, a)) <= 0) {
131 if (r == 0) {
132 swap_cnt = 1;
133 swap(pa, pb);
134 pa += es;
135 }
136 pb += es;
137 }
138 while (pb <= pc && (r = cmp(pc, a)) >= 0) {
139 if (r == 0) {
140 swap_cnt = 1;
141 swap(pc, pd);
142 pd -= es;
143 }
144 pc -= es;
145 }
146 if (pb > pc)
147 break;
148 swap(pb, pc);
149 swap_cnt = 1;
150 pb += es;
151 pc -= es;
152 }
153 if (swap_cnt == 0) { /* Switch to insertion sort */
154 for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es)
155 for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
156 pl -= es)
157 swap(pl, pl - es);
158 return;
159 }
160
161 pn = (char *)a + n * es;
162 r = min(pa - (char *)a, pb - pa);
163 vecswap(a, pb - r, r);
164 r = min(pd - pc, pn - pd - es);
165 vecswap(pb, pn - r, r);
166 if ((r = pb - pa) > es)
167 qsort(a, r / es, es, cmp);
168 if ((r = pd - pc) > es) {
169 /* Iterate rather than recurse to save stack space */
170 a = pn - r;
171 n = r / es;
172 goto loop;
173 }
174/* qsort(pn - r, r / es, es, cmp);*/
175}
diff --git a/src/lib/libc/stdlib/radixsort.3 b/src/lib/libc/stdlib/radixsort.3
new file mode 100644
index 0000000000..8b0ea89a0f
--- /dev/null
+++ b/src/lib/libc/stdlib/radixsort.3
@@ -0,0 +1,161 @@
1.\" Copyright (c) 1990, 1991, 1993
2.\" The Regents of the University of California. All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\" notice, this list of conditions and the following disclaimer.
9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\" notice, this list of conditions and the following disclaimer in the
11.\" documentation and/or other materials provided with the distribution.
12.\" 3. All advertising materials mentioning features or use of this software
13.\" must display the following acknowledgement:
14.\" This product includes software developed by the University of
15.\" California, Berkeley and its contributors.
16.\" 4. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" $OpenBSD: radixsort.3,v 1.4 1998/06/15 17:55:08 mickey Exp $
33.\"
34.Dd January 27, 1994
35.Dt RADIXSORT 3
36.Os
37.Sh NAME
38.Nm radixsort
39.Nd radix sort
40.Sh SYNOPSIS
41.Fd #include <limits.h>
42.Fd #include <stdlib.h>
43.Ft int
44.Fn radixsort "const u_char **base" "int nmemb" "const u_char *table" "u_int endbyte"
45.Ft int
46.Fn sradixsort "const u_char **base" "int nmemb" "const u_char *table" "u_int endbyte"
47.Sh DESCRIPTION
48The
49.Fn radixsort
50and
51.Fn sradixsort
52functions
53are implementations of radix sort.
54.Pp
55These functions sort an array of pointers to byte strings, the initial
56member of which is referenced by
57.Fa base .
58The byte strings may contain any values; the end of each string
59is denoted by the user-specified value
60.Fa endbyte .
61.Pp
62Applications may specify a sort order by providing the
63.Fa table
64argument.
65If
66.Pf non- Dv NULL ,
67.Fa table
68must reference an array of
69.Dv UCHAR_MAX
70+ 1 bytes which contains the sort
71weight of each possible byte value.
72The end-of-string byte must have a sort weight of 0 or 255
73(for sorting in reverse order).
74More than one byte may have the same sort weight.
75The
76.Fa table
77argument
78is useful for applications which wish to sort different characters
79equally, for example, providing a table with the same weights
80for A-Z as for a-z will result in a case-insensitive sort.
81If
82.Fa table
83is NULL, the contents of the array are sorted in ascending order
84according to the
85.Tn ASCII
86order of the byte strings they reference and
87.Fa endbyte
88has a sorting weight of 0.
89.Pp
90The
91.Fn sradixsort
92function is stable, that is, if two elements compare as equal, their
93order in the sorted array is unchanged.
94The
95.Fn sradixsort
96function uses additional memory sufficient to hold
97.Fa nmemb
98pointers.
99.Pp
100The
101.Fn radixsort
102function is not stable, but uses no additional memory.
103.Pp
104These functions are variants of most-significant-byte radix sorting; in
105particular, see D.E. Knuth's Algorithm R and section 5.2.5, exercise 10.
106They take linear time relative to the number of bytes in the strings.
107.Sh RETURN VALUES
108Upon successful completion 0 is returned.
109Otherwise, \-1 is returned and the global variable
110.Va errno
111is set to indicate the error.
112.Sh ERRORS
113.Bl -tag -width Er
114.It Bq Er EINVAL
115The value of the
116.Fa endbyte
117element of
118.Fa table
119is not 0 or 255.
120.El
121.Pp
122Additionally, the
123.Fn sradixsort
124function
125may fail and set
126.Va errno
127for any of the errors specified for the library routine
128.Xr malloc 3 .
129.Sh SEE ALSO
130.Xr sort 1 ,
131.Xr qsort 3
132.Pp
133.Rs
134.%A Knuth, D.E.
135.%D 1968
136.%B "The Art of Computer Programming"
137.%T "Sorting and Searching"
138.%V Vol. 3
139.%P pp. 170-178
140.Re
141.Rs
142.%A Paige, R.
143.%D 1987
144.%T "Three Partition Refinement Algorithms"
145.%J "SIAM J. Comput."
146.%V Vol. 16
147.%N No. 6
148.Re
149.Rs
150.%A McIlroy, P.
151.%D 1993
152.%B "Engineering Radix Sort"
153.%T "Computing Systems"
154.%V Vol. 6:1
155.%P pp. 5-27
156.Re
157.Sh HISTORY
158The
159.Fn radixsort
160function first appeared in
161.Bx 4.4 .
diff --git a/src/lib/libc/stdlib/radixsort.c b/src/lib/libc/stdlib/radixsort.c
new file mode 100644
index 0000000000..41ed962466
--- /dev/null
+++ b/src/lib/libc/stdlib/radixsort.c
@@ -0,0 +1,317 @@
1/*-
2 * Copyright (c) 1990, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Peter McIlroy and by Dan Bernstein at New York University,
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: radixsort.c,v 1.3 1996/08/19 08:33:44 tholo Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41/*
42 * Radixsort routines.
43 *
44 * Program r_sort_a() is unstable but uses O(logN) extra memory for a stack.
45 * Use radixsort(a, n, trace, endchar) for this case.
46 *
47 * For stable sorting (using N extra pointers) use sradixsort(), which calls
48 * r_sort_b().
49 *
50 * For a description of this code, see D. McIlroy, P. McIlroy, K. Bostic,
51 * "Engineering Radix Sort".
52 */
53
54#include <sys/types.h>
55#include <stdlib.h>
56#include <errno.h>
57
58typedef struct {
59 const u_char **sa;
60 int sn, si;
61} stack;
62
63static __inline void simplesort
64 __P((const u_char **, int, int, const u_char *, u_int));
65static void r_sort_a __P((const u_char **, int, int, const u_char *, u_int));
66static void r_sort_b __P((const u_char **,
67 const u_char **, int, int, const u_char *, u_int));
68
69#define THRESHOLD 20 /* Divert to simplesort(). */
70#define SIZE 512 /* Default stack size. */
71
72#define SETUP { \
73 if (tab == NULL) { \
74 tr = tr0; \
75 for (c = 0; c < endch; c++) \
76 tr0[c] = c + 1; \
77 tr0[c] = 0; \
78 for (c++; c < 256; c++) \
79 tr0[c] = c; \
80 endch = 0; \
81 } else { \
82 endch = tab[endch]; \
83 tr = tab; \
84 if (endch != 0 && endch != 255) { \
85 errno = EINVAL; \
86 return (-1); \
87 } \
88 } \
89}
90
91int
92radixsort(a, n, tab, endch)
93 const u_char **a, *tab;
94 int n;
95 u_int endch;
96{
97 const u_char *tr;
98 int c;
99 u_char tr0[256];
100
101 SETUP;
102 r_sort_a(a, n, 0, tr, endch);
103 return (0);
104}
105
106int
107sradixsort(a, n, tab, endch)
108 const u_char **a, *tab;
109 int n;
110 u_int endch;
111{
112 const u_char *tr, **ta;
113 int c;
114 u_char tr0[256];
115
116 SETUP;
117 if (n < THRESHOLD)
118 simplesort(a, n, 0, tr, endch);
119 else {
120 if ((ta = malloc(n * sizeof(a))) == NULL)
121 return (-1);
122 r_sort_b(a, ta, n, 0, tr, endch);
123 free(ta);
124 }
125 return (0);
126}
127
128#define empty(s) (s >= sp)
129#define pop(a, n, i) a = (--sp)->sa, n = sp->sn, i = sp->si
130#define push(a, n, i) sp->sa = a, sp->sn = n, (sp++)->si = i
131#define swap(a, b, t) t = a, a = b, b = t
132
133/* Unstable, in-place sort. */
134void
135r_sort_a(a, n, i, tr, endch)
136 const u_char **a;
137 int n, i;
138 const u_char *tr;
139 u_int endch;
140{
141 static int count[256], nc, bmin;
142 register int c;
143 register const u_char **ak, *r;
144 stack s[SIZE], *sp, *sp0, *sp1, temp;
145 int *cp, bigc;
146 const u_char **an, *t, **aj, **top[256];
147
148 /* Set up stack. */
149 sp = s;
150 push(a, n, i);
151 while (!empty(s)) {
152 pop(a, n, i);
153 if (n < THRESHOLD) {
154 simplesort(a, n, i, tr, endch);
155 continue;
156 }
157 an = a + n;
158
159 /* Make character histogram. */
160 if (nc == 0) {
161 bmin = 255; /* First occupied bin, excluding eos. */
162 for (ak = a; ak < an;) {
163 c = tr[(*ak++)[i]];
164 if (++count[c] == 1 && c != endch) {
165 if (c < bmin)
166 bmin = c;
167 nc++;
168 }
169 }
170 if (sp + nc > s + SIZE) { /* Get more stack. */
171 r_sort_a(a, n, i, tr, endch);
172 continue;
173 }
174 }
175
176 /*
177 * Set top[]; push incompletely sorted bins onto stack.
178 * top[] = pointers to last out-of-place element in bins.
179 * count[] = counts of elements in bins.
180 * Before permuting: top[c-1] + count[c] = top[c];
181 * during deal: top[c] counts down to top[c-1].
182 */
183 sp0 = sp1 = sp; /* Stack position of biggest bin. */
184 bigc = 2; /* Size of biggest bin. */
185 if (endch == 0) /* Special case: set top[eos]. */
186 top[0] = ak = a + count[0];
187 else {
188 ak = a;
189 top[255] = an;
190 }
191 for (cp = count + bmin; nc > 0; cp++) {
192 while (*cp == 0) /* Find next non-empty pile. */
193 cp++;
194 if (*cp > 1) {
195 if (*cp > bigc) {
196 bigc = *cp;
197 sp1 = sp;
198 }
199 push(ak, *cp, i+1);
200 }
201 top[cp-count] = ak += *cp;
202 nc--;
203 }
204 swap(*sp0, *sp1, temp); /* Play it safe -- biggest bin last. */
205
206 /*
207 * Permute misplacements home. Already home: everything
208 * before aj, and in bin[c], items from top[c] on.
209 * Inner loop:
210 * r = next element to put in place;
211 * ak = top[r[i]] = location to put the next element.
212 * aj = bottom of 1st disordered bin.
213 * Outer loop:
214 * Once the 1st disordered bin is done, ie. aj >= ak,
215 * aj<-aj + count[c] connects the bins in a linked list;
216 * reset count[c].
217 */
218 for (aj = a; aj < an; *aj = r, aj += count[c], count[c] = 0)
219 for (r = *aj; aj < (ak = --top[c = tr[r[i]]]);)
220 swap(*ak, r, t);
221 }
222}
223
224/* Stable sort, requiring additional memory. */
225void
226r_sort_b(a, ta, n, i, tr, endch)
227 const u_char **a, **ta;
228 int n, i;
229 const u_char *tr;
230 u_int endch;
231{
232 static int count[256], nc, bmin;
233 register int c;
234 register const u_char **ak, **ai;
235 stack s[512], *sp, *sp0, *sp1, temp;
236 const u_char **top[256];
237 int *cp, bigc;
238
239 sp = s;
240 push(a, n, i);
241 while (!empty(s)) {
242 pop(a, n, i);
243 if (n < THRESHOLD) {
244 simplesort(a, n, i, tr, endch);
245 continue;
246 }
247
248 if (nc == 0) {
249 bmin = 255;
250 for (ak = a + n; --ak >= a;) {
251 c = tr[(*ak)[i]];
252 if (++count[c] == 1 && c != endch) {
253 if (c < bmin)
254 bmin = c;
255 nc++;
256 }
257 }
258 if (sp + nc > s + SIZE) {
259 r_sort_b(a, ta, n, i, tr, endch);
260 continue;
261 }
262 }
263
264 sp0 = sp1 = sp;
265 bigc = 2;
266 if (endch == 0) {
267 top[0] = ak = a + count[0];
268 count[0] = 0;
269 } else {
270 ak = a;
271 top[255] = a + n;
272 count[255] = 0;
273 }
274 for (cp = count + bmin; nc > 0; cp++) {
275 while (*cp == 0)
276 cp++;
277 if ((c = *cp) > 1) {
278 if (c > bigc) {
279 bigc = c;
280 sp1 = sp;
281 }
282 push(ak, c, i+1);
283 }
284 top[cp-count] = ak += c;
285 *cp = 0; /* Reset count[]. */
286 nc--;
287 }
288 swap(*sp0, *sp1, temp);
289
290 for (ak = ta + n, ai = a+n; ak > ta;) /* Copy to temp. */
291 *--ak = *--ai;
292 for (ak = ta+n; --ak >= ta;) /* Deal to piles. */
293 *--top[tr[(*ak)[i]]] = *ak;
294 }
295}
296
297static __inline void
298simplesort(a, n, b, tr, endch) /* insertion sort */
299 register const u_char **a;
300 int n, b;
301 register const u_char *tr;
302 u_int endch;
303{
304 register u_char ch;
305 const u_char **ak, **ai, *s, *t;
306
307 for (ak = a+1; --n >= 1; ak++)
308 for (ai = ak; ai > a; ai--) {
309 for (s = ai[0] + b, t = ai[-1] + b;
310 (ch = tr[*s]) != endch; s++, t++)
311 if (ch != tr[*t])
312 break;
313 if (ch >= tr[*t])
314 break;
315 swap(ai[0], ai[-1], s);
316 }
317}
diff --git a/src/lib/libc/stdlib/rand.3 b/src/lib/libc/stdlib/rand.3
new file mode 100644
index 0000000000..32d32761f1
--- /dev/null
+++ b/src/lib/libc/stdlib/rand.3
@@ -0,0 +1,87 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: rand.3,v 1.4 1998/07/05 19:54:22 millert Exp $
37.\"
38.Dd June 29, 1991
39.Dt RAND 3
40.Os
41.Sh NAME
42.Nm rand ,
43.Nm srand
44.Nd bad random number generator
45.Sh SYNOPSIS
46.Fd #include <stdlib.h>
47.Ft void
48.Fn srand "unsigned seed"
49.Ft int
50.Fn rand void
51.Sh DESCRIPTION
52.Bf -symbolic
53These interfaces are obsoleted by
54.Xr random 3 .
55.Ef
56.Pp
57The
58.Fn rand
59function computes a sequence of pseudo-random integers in the range
60of 0 to
61.Dv RAND_MAX
62(as defined by the header file
63.Aq Pa stdlib.h ) .
64.Pp
65The
66.Fn srand
67function sets its argument as the seed for a new sequence of
68pseudo-random numbers to be returned by
69.Fn rand .
70These sequences are repeatable by calling
71.Fn srand
72with the same seed value.
73.Pp
74If no seed value is provided, the functions are automatically
75seeded with a value of 1.
76.Sh SEE ALSO
77.Xr arc4random 3 ,
78.Xr rand48 3 ,
79.Xr random 3
80.Sh STANDARDS
81The
82.Fn rand
83and
84.Fn srand
85functions
86conform to
87.St -ansiC .
diff --git a/src/lib/libc/stdlib/rand.c b/src/lib/libc/stdlib/rand.c
new file mode 100644
index 0000000000..f270ffd986
--- /dev/null
+++ b/src/lib/libc/stdlib/rand.c
@@ -0,0 +1,54 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: rand.c,v 1.2 1996/08/19 08:33:44 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/types.h>
39#include <stdlib.h>
40
41static u_long next = 1;
42
43int
44rand()
45{
46 return ((next = next * 1103515245 + 12345) % ((u_int)RAND_MAX + 1));
47}
48
49void
50srand(seed)
51u_int seed;
52{
53 next = seed;
54}
diff --git a/src/lib/libc/stdlib/rand48.3 b/src/lib/libc/stdlib/rand48.3
new file mode 100644
index 0000000000..d5236a4779
--- /dev/null
+++ b/src/lib/libc/stdlib/rand48.3
@@ -0,0 +1,161 @@
1\" Copyright (c) 1993 Martin Birgmeier
2.\" All rights reserved.
3.\"
4.\" You may redistribute unmodified or modified versions of this source
5.\" code provided that the above copyright notice and this and the
6.\" following conditions are retained.
7.\"
8.\" This software is provided ``as is'', and comes with no warranties
9.\" of any kind. I shall in no event be liable for anything that happens
10.\" to anyone/anything when using this software.
11.\"
12.\" $OpenBSD: rand48.3,v 1.3 1998/07/05 19:54:23 millert Exp $
13.\"
14.Dd October 8, 1993
15.Dt RAND48 3
16.Os
17.Sh NAME
18.Nm drand48 ,
19.Nm erand48 ,
20.Nm lrand48 ,
21.Nm nrand48 ,
22.Nm mrand48 ,
23.Nm jrand48 ,
24.Nm srand48 ,
25.Nm seed48 ,
26.Nm lcong48
27.Nd pseudo random number generators and initialization routines
28.Sh SYNOPSIS
29.Fd #include <stdlib.h>
30.Ft double
31.Fn drand48 void
32.Ft double
33.Fn erand48 "unsigned short xseed[3]"
34.Ft long
35.Fn lrand48 void
36.Ft long
37.Fn nrand48 "unsigned short xseed[3]"
38.Ft long
39.Fn mrand48 void
40.Ft long
41.Fn jrand48 "unsigned short xseed[3]"
42.Ft void
43.Fn srand48 "long seed"
44.Ft "unsigned short *"
45.Fn seed48 "unsigned short xseed[3]"
46.Ft void
47.Fn lcong48 "unsigned short p[7]"
48.Sh DESCRIPTION
49The
50.Fn rand48
51family of functions generates pseudo-random numbers using a linear
52congruential algorithm working on integers 48 bits in size. The
53particular formula employed is
54r(n+1) = (a * r(n) + c) mod m
55where the default values are
56for the multiplicand a = 0xfdeece66d = 25214903917 and
57the addend c = 0xb = 11. The modulus is always fixed at m = 2 ** 48.
58r(n) is called the seed of the random number generator.
59.Pp
60For all the six generator routines described next, the first
61computational step is to perform a single iteration of the algorithm.
62.Pp
63.Fn drand48
64and
65.Fn erand48
66return values of type double. The full 48 bits of r(n+1) are
67loaded into the mantissa of the returned value, with the exponent set
68such that the values produced lie in the interval [0.0, 1.0).
69.Pp
70.Fn lrand48
71and
72.Fn nrand48
73return values of type long in the range
74[0, 2**31-1]. The high-order (31) bits of
75r(n+1) are loaded into the lower bits of the returned value, with
76the topmost (sign) bit set to zero.
77.Pp
78.Fn mrand48
79and
80.Fn jrand48
81return values of type long in the range
82[-2**31, 2**31-1]. The high-order (32) bits of
83r(n+1) are loaded into the returned value.
84.Pp
85.Fn drand48 ,
86.Fn lrand48 ,
87and
88.Fn mrand48
89use an internal buffer to store r(n). For these functions
90the initial value of r(0) = 0x1234abcd330e = 20017429951246.
91.Pp
92On the other hand,
93.Fn erand48 ,
94.Fn nrand48 ,
95and
96.Fn jrand48
97use a user-supplied buffer to store the seed r(n),
98which consists of an array of 3 shorts, where the zeroth member
99holds the least significant bits.
100.Pp
101All functions share the same multiplicand and addend.
102.Pp
103.Fn srand48
104is used to initialize the internal buffer r(n) of
105.Fn drand48 ,
106.Fn lrand48 ,
107and
108.Fn mrand48
109such that the 32 bits of the seed value are copied into the upper 32 bits
110of r(n), with the lower 16 bits of r(n) arbitrarily being set to 0x330e.
111Additionally, the constant multiplicand and addend of the algorithm are
112reset to the default values given above.
113.Pp
114.Fn seed48
115also initializes the internal buffer r(n) of
116.Fn drand48 ,
117.Fn lrand48 ,
118and
119.Fn mrand48 ,
120but 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,
122the constant multiplicand and addend of the algorithm are
123reset to the default values given above.
124.Fn seed48
125returns a pointer to an array of 3 shorts which contains the old seed.
126This array is statically allocated, thus its contents are lost after
127each new call to
128.Fn seed48 .
129.Pp
130Finally,
131.Fn lcong48
132allows full control over the multiplicand and addend used in
133.Fn drand48 ,
134.Fn erand48 ,
135.Fn lrand48 ,
136.Fn nrand48 ,
137.Fn mrand48 ,
138and
139.Fn jrand48 ,
140and the seed used in
141.Fn drand48 ,
142.Fn lrand48 ,
143and
144.Fn mrand48 .
145An array of 7 shorts is passed as parameter; the first three shorts are
146used to initialize the seed; the second three are used to initialize the
147multiplicand; and the last short is used to initialize the addend.
148It is thus not possible to use values greater than 0xffff as the addend.
149.Pp
150Note that all three methods of seeding the random number generator
151always also set the multiplicand and addend for any of the six
152generator calls.
153.Pp
154For a more powerful random number generator, see
155.Xr random 3
156.Sh AUTHOR
157Martin Birgmeier
158.Sh SEE ALSO
159.Xr arc4random 3 ,
160.Xr rand 3 ,
161.Xr random 3 .
diff --git a/src/lib/libc/stdlib/rand48.h b/src/lib/libc/stdlib/rand48.h
new file mode 100644
index 0000000000..e7cb3e0333
--- /dev/null
+++ b/src/lib/libc/stdlib/rand48.h
@@ -0,0 +1,32 @@
1/*
2 * Copyright (c) 1993 Martin Birgmeier
3 * All rights reserved.
4 *
5 * You may redistribute unmodified or modified versions of this source
6 * code provided that the above copyright notice and this and the
7 * following conditions are retained.
8 *
9 * This software is provided ``as is'', and comes with no warranties
10 * of any kind. I shall in no event be liable for anything that happens
11 * to anyone/anything when using this software.
12 *
13 * $OpenBSD: rand48.h,v 1.2 1996/08/19 08:33:45 tholo Exp $
14 */
15
16#ifndef _RAND48_H_
17#define _RAND48_H_
18
19#include <math.h>
20#include <stdlib.h>
21
22void __dorand48 __P((unsigned short[3]));
23
24#define RAND48_SEED_0 (0x330e)
25#define RAND48_SEED_1 (0xabcd)
26#define RAND48_SEED_2 (0x1234)
27#define RAND48_MULT_0 (0xe66d)
28#define RAND48_MULT_1 (0xdeec)
29#define RAND48_MULT_2 (0x0005)
30#define RAND48_ADD (0x000b)
31
32#endif /* _RAND48_H_ */
diff --git a/src/lib/libc/stdlib/random.3 b/src/lib/libc/stdlib/random.3
new file mode 100644
index 0000000000..acfbd8cdeb
--- /dev/null
+++ b/src/lib/libc/stdlib/random.3
@@ -0,0 +1,183 @@
1.\" Copyright (c) 1983, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\" notice, this list of conditions and the following disclaimer.
9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\" notice, this list of conditions and the following disclaimer in the
11.\" documentation and/or other materials provided with the distribution.
12.\" 3. All advertising materials mentioning features or use of this software
13.\" must display the following acknowledgement:
14.\" This product includes software developed by the University of
15.\" California, Berkeley and its contributors.
16.\" 4. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" $OpenBSD: random.3,v 1.6 1998/07/05 19:54:25 millert Exp $
33.\"
34.Dd April 19, 1991
35.Dt RANDOM 3
36.Os BSD 4.2
37.Sh NAME
38.Nm random ,
39.Nm srandom ,
40.Nm initstate ,
41.Nm setstate
42.Nd better random number generator; routines for changing generators
43.Sh SYNOPSIS
44.Fd #include <stdlib.h>
45.Ft long
46.Fn random void
47.Ft void
48.Fn srandom "unsigned int seed"
49.Ft char *
50.Fn initstate "unsigned int seed" "char *state" "size_t n"
51.Ft char *
52.Fn setstate "const char *state"
53.Sh DESCRIPTION
54The
55.Fn random
56function
57uses a non-linear additive feedback random number generator employing a
58default table of size 31 long integers to return successive pseudo-random
59numbers in the range from 0 to
60.if t 2\u\s731\s10\d\(mi1.
61.if n (2**31)\(mi1.
62The maximum value returned by
63.Fn random
64is
65.Dv LONG_MAX
66(as defined by the header file
67.Aq Pa limits.h ) .
68The period of this random number generator is very large, approximately
69.if t 16\(mu(2\u\s731\s10\d\(mi1).
70.if n 16*((2**31)\(mi1).
71.Pp
72The
73.Fn random Ns / Fn srandom
74have (almost) the same calling sequence and initialization properties as
75.Xr rand 3 Ns / Xr srand 3 .
76The difference is that
77.Xr rand
78produces a much less random sequence \(em in fact, the low dozen bits
79generated by rand go through a cyclic pattern. All the bits generated by
80.Fn random
81are usable. For example,
82.Sq Li random()&01
83will produce a random binary
84value.
85.Pp
86Unlike
87.Xr srand ,
88.Fn srandom
89does not return the old seed; the reason for this is that the amount of
90state information used is much more than a single word. (Two other
91routines are provided to deal with restarting/changing random
92number generators). Like
93.Xr rand 3 ,
94however,
95.Fn random
96will by default produce a sequence of numbers that can be duplicated
97by calling
98.Fn srandom
99with
100.Ql 1
101as the seed.
102.Pp
103The
104.Fn initstate
105routine allows a state array, passed in as an argument, to be initialized
106for future use. The size of the state array (in bytes) is used by
107.Fn initstate
108to decide how sophisticated a random number generator it should use \(em the
109more state, the better the random numbers will be.
110(Current "optimal" values for the amount of state information are
1118, 32, 64, 128, and 256 bytes; other amounts will be rounded down to
112the nearest known amount. Using less than 8 bytes will cause an error.)
113The seed for the initialization (which specifies a starting point for
114the random number sequence, and provides for restarting at the same
115point) is also an argument.
116The
117.Fn initstate
118function
119returns a pointer to the previous state information array.
120.Pp
121Once a state has been initialized, the
122.Fn setstate
123routine provides for rapid switching between states.
124The
125.Fn setstate
126function
127returns a pointer to the previous state array; its
128argument state array is used for further random number generation
129until the next call to
130.Fn initstate
131or
132.Fn setstate .
133.Pp
134Once a state array has been initialized, it may be restarted at a
135different point either by calling
136.Fn initstate
137(with the desired seed, the state array, and its size) or by calling
138both
139.Fn setstate
140(with the state array) and
141.Fn srandom
142(with the desired seed).
143The advantage of calling both
144.Fn setstate
145and
146.Fn srandom
147is that the size of the state array does not have to be remembered after
148it is initialized.
149.Pp
150With 256 bytes of state information, the period of the random number
151generator is greater than
152.if t 2\u\s769\s10\d,
153.if n 2**69
154which should be sufficient for most purposes.
155.Sh AUTHOR
156Earl T. Cohen
157.Sh DIAGNOSTICS
158If
159.Fn initstate
160is called with less than 8 bytes of state information, or if
161.Fn setstate
162detects that the state information has been garbled, error
163messages are printed on the standard error output.
164.Sh SEE ALSO
165.Xr arc4random 3 ,
166.Xr drand48 3 ,
167.Xr rand 3
168.Sh STANDARDS
169The
170.Fn random ,
171.Fn srandom ,
172.Fn initstate ,
173and
174.Fn setstate
175functions conform to
176.St -xpg4.2 .
177.Sh HISTORY
178These
179functions appeared in
180.Bx 4.2 .
181.Sh BUGS
182About 2/3 the speed of
183.Xr rand 3 .
diff --git a/src/lib/libc/stdlib/random.c b/src/lib/libc/stdlib/random.c
new file mode 100644
index 0000000000..79344f30f1
--- /dev/null
+++ b/src/lib/libc/stdlib/random.c
@@ -0,0 +1,370 @@
1/*
2 * Copyright (c) 1983 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: random.c,v 1.6 1998/02/07 02:16:25 millert Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <stdio.h>
39#include <stdlib.h>
40
41/*
42 * random.c:
43 *
44 * An improved random number generation package. In addition to the standard
45 * rand()/srand() like interface, this package also has a special state info
46 * interface. The initstate() routine is called with a seed, an array of
47 * bytes, and a count of how many bytes are being passed in; this array is
48 * then initialized to contain information for random number generation with
49 * that much state information. Good sizes for the amount of state
50 * information are 32, 64, 128, and 256 bytes. The state can be switched by
51 * calling the setstate() routine with the same array as was initiallized
52 * with initstate(). By default, the package runs with 128 bytes of state
53 * information and generates far better random numbers than a linear
54 * congruential generator. If the amount of state information is less than
55 * 32 bytes, a simple linear congruential R.N.G. is used.
56 *
57 * Internally, the state information is treated as an array of longs; the
58 * zeroeth element of the array is the type of R.N.G. being used (small
59 * integer); the remainder of the array is the state information for the
60 * R.N.G. Thus, 32 bytes of state information will give 7 longs worth of
61 * state information, which will allow a degree seven polynomial. (Note:
62 * the zeroeth word of state information also has some other information
63 * stored in it -- see setstate() for details).
64 *
65 * The random number generation technique is a linear feedback shift register
66 * approach, employing trinomials (since there are fewer terms to sum up that
67 * way). In this approach, the least significant bit of all the numbers in
68 * the state table will act as a linear feedback shift register, and will
69 * have period 2^deg - 1 (where deg is the degree of the polynomial being
70 * used, assuming that the polynomial is irreducible and primitive). The
71 * higher order bits will have longer periods, since their values are also
72 * influenced by pseudo-random carries out of the lower bits. The total
73 * period of the generator is approximately deg*(2**deg - 1); thus doubling
74 * the amount of state information has a vast influence on the period of the
75 * generator. Note: the deg*(2**deg - 1) is an approximation only good for
76 * large deg, when the period of the shift register is the dominant factor.
77 * With deg equal to seven, the period is actually much longer than the
78 * 7*(2**7 - 1) predicted by this formula.
79 */
80
81/*
82 * For each of the currently supported random number generators, we have a
83 * break value on the amount of state information (you need at least this
84 * many bytes of state info to support this random number generator), a degree
85 * for the polynomial (actually a trinomial) that the R.N.G. is based on, and
86 * the separation between the two lower order coefficients of the trinomial.
87 */
88#define TYPE_0 0 /* linear congruential */
89#define BREAK_0 8
90#define DEG_0 0
91#define SEP_0 0
92
93#define TYPE_1 1 /* x**7 + x**3 + 1 */
94#define BREAK_1 32
95#define DEG_1 7
96#define SEP_1 3
97
98#define TYPE_2 2 /* x**15 + x + 1 */
99#define BREAK_2 64
100#define DEG_2 15
101#define SEP_2 1
102
103#define TYPE_3 3 /* x**31 + x**3 + 1 */
104#define BREAK_3 128
105#define DEG_3 31
106#define SEP_3 3
107
108#define TYPE_4 4 /* x**63 + x + 1 */
109#define BREAK_4 256
110#define DEG_4 63
111#define SEP_4 1
112
113/*
114 * Array versions of the above information to make code run faster --
115 * relies on fact that TYPE_i == i.
116 */
117#define MAX_TYPES 5 /* max number of types above */
118
119static int degrees[MAX_TYPES] = { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 };
120static int seps [MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 };
121
122/*
123 * Initially, everything is set up as if from:
124 *
125 * initstate(1, &randtbl, 128);
126 *
127 * Note that this initialization takes advantage of the fact that srandom()
128 * advances the front and rear pointers 10*rand_deg times, and hence the
129 * rear pointer which starts at 0 will also end up at zero; thus the zeroeth
130 * element of the state information, which contains info about the current
131 * position of the rear pointer is just
132 *
133 * MAX_TYPES * (rptr - state) + TYPE_3 == TYPE_3.
134 */
135
136static long randtbl[DEG_3 + 1] = {
137 TYPE_3,
138 0x991539b1, 0x16a5bce3, 0x6774a4cd, 0x3e01511e, 0x4e508aaa, 0x61048c05,
139 0xf5500617, 0x846b7115, 0x6a19892c, 0x896a97af, 0xdb48f936, 0x14898454,
140 0x37ffd106, 0xb58bff9c, 0x59e17104, 0xcf918a49, 0x09378c83, 0x52c7a471,
141 0x8d293ea9, 0x1f4fc301, 0xc3db71be, 0x39b44e1c, 0xf8a44ef9, 0x4c8b80b1,
142 0x19edc328, 0x87bf4bdd, 0xc9b240e5, 0xe9ee4b1b, 0x4382aee7, 0x535b6b41,
143 0xf3bec5da,
144};
145
146/*
147 * fptr and rptr are two pointers into the state info, a front and a rear
148 * pointer. These two pointers are always rand_sep places aparts, as they
149 * cycle cyclically through the state information. (Yes, this does mean we
150 * could get away with just one pointer, but the code for random() is more
151 * efficient this way). The pointers are left positioned as they would be
152 * from the call
153 *
154 * initstate(1, randtbl, 128);
155 *
156 * (The position of the rear pointer, rptr, is really 0 (as explained above
157 * in the initialization of randtbl) because the state table pointer is set
158 * to point to randtbl[1] (as explained below).
159 */
160static long *fptr = &randtbl[SEP_3 + 1];
161static long *rptr = &randtbl[1];
162
163/*
164 * The following things are the pointer to the state information table, the
165 * type of the current generator, the degree of the current polynomial being
166 * used, and the separation between the two pointers. Note that for efficiency
167 * of random(), we remember the first location of the state information, not
168 * the zeroeth. Hence it is valid to access state[-1], which is used to
169 * store the type of the R.N.G. Also, we remember the last location, since
170 * this is more efficient than indexing every time to find the address of
171 * the last element to see if the front and rear pointers have wrapped.
172 */
173static long *state = &randtbl[1];
174static int rand_type = TYPE_3;
175static int rand_deg = DEG_3;
176static int rand_sep = SEP_3;
177static long *end_ptr = &randtbl[DEG_3 + 1];
178
179/*
180 * srandom:
181 *
182 * Initialize the random number generator based on the given seed. If the
183 * type is the trivial no-state-information type, just remember the seed.
184 * Otherwise, initializes state[] based on the given "seed" via a linear
185 * congruential generator. Then, the pointers are set to known locations
186 * that are exactly rand_sep places apart. Lastly, it cycles the state
187 * information a given number of times to get rid of any initial dependencies
188 * introduced by the L.C.R.N.G. Note that the initialization of randtbl[]
189 * for default usage relies on values produced by this routine.
190 */
191void
192srandom(x)
193 u_int x;
194{
195 register long int test;
196 register int i;
197 ldiv_t val;
198
199 if (rand_type == TYPE_0)
200 state[0] = x;
201 else {
202 state[0] = x;
203 for (i = 1; i < rand_deg; i++) {
204 /*
205 * Implement the following, without overflowing 31 bits:
206 *
207 * state[i] = (16807 * state[i - 1]) % 2147483647;
208 *
209 * 2^31-1 (prime) = 2147483647 = 127773*16807+2836
210 */
211 val = ldiv(state[i-1], 127773);
212 test = 16807 * val.rem - 2836 * val.quot;
213 state[i] = test + (test < 0 ? 2147483647 : 0);
214 }
215 fptr = &state[rand_sep];
216 rptr = &state[0];
217 for (i = 0; i < 10 * rand_deg; i++)
218 (void)random();
219 }
220}
221
222/*
223 * initstate:
224 *
225 * Initialize the state information in the given array of n bytes for future
226 * random number generation. Based on the number of bytes we are given, and
227 * the break values for the different R.N.G.'s, we choose the best (largest)
228 * one we can and set things up for it. srandom() is then called to
229 * initialize the state information.
230 *
231 * Note that on return from srandom(), we set state[-1] to be the type
232 * multiplexed with the current value of the rear pointer; this is so
233 * successive calls to initstate() won't lose this information and will be
234 * able to restart with setstate().
235 *
236 * Note: the first thing we do is save the current state, if any, just like
237 * setstate() so that it doesn't matter when initstate is called.
238 *
239 * Returns a pointer to the old state.
240 */
241char *
242initstate(seed, arg_state, n)
243 u_int seed; /* seed for R.N.G. */
244 char *arg_state; /* pointer to state array */
245 size_t n; /* # bytes of state info */
246{
247 register char *ostate = (char *)(&state[-1]);
248
249 if (rand_type == TYPE_0)
250 state[-1] = rand_type;
251 else
252 state[-1] = MAX_TYPES * (rptr - state) + rand_type;
253 if (n < BREAK_0)
254 return(NULL);
255 if (n < BREAK_1) {
256 rand_type = TYPE_0;
257 rand_deg = DEG_0;
258 rand_sep = SEP_0;
259 } else if (n < BREAK_2) {
260 rand_type = TYPE_1;
261 rand_deg = DEG_1;
262 rand_sep = SEP_1;
263 } else if (n < BREAK_3) {
264 rand_type = TYPE_2;
265 rand_deg = DEG_2;
266 rand_sep = SEP_2;
267 } else if (n < BREAK_4) {
268 rand_type = TYPE_3;
269 rand_deg = DEG_3;
270 rand_sep = SEP_3;
271 } else {
272 rand_type = TYPE_4;
273 rand_deg = DEG_4;
274 rand_sep = SEP_4;
275 }
276 state = &(((long *)arg_state)[1]); /* first location */
277 end_ptr = &state[rand_deg]; /* must set end_ptr before srandom */
278 srandom(seed);
279 if (rand_type == TYPE_0)
280 state[-1] = rand_type;
281 else
282 state[-1] = MAX_TYPES*(rptr - state) + rand_type;
283 return(ostate);
284}
285
286/*
287 * setstate:
288 *
289 * Restore the state from the given state array.
290 *
291 * Note: it is important that we also remember the locations of the pointers
292 * in the current state information, and restore the locations of the pointers
293 * from the old state information. This is done by multiplexing the pointer
294 * location into the zeroeth word of the state information.
295 *
296 * Note that due to the order in which things are done, it is OK to call
297 * setstate() with the same state as the current state.
298 *
299 * Returns a pointer to the old state information.
300 */
301char *
302setstate(arg_state)
303 const char *arg_state;
304{
305 register long *new_state = (long *)arg_state;
306 register int type = new_state[0] % MAX_TYPES;
307 register int rear = new_state[0] / MAX_TYPES;
308 char *ostate = (char *)(&state[-1]);
309
310 if (rand_type == TYPE_0)
311 state[-1] = rand_type;
312 else
313 state[-1] = MAX_TYPES * (rptr - state) + rand_type;
314 switch(type) {
315 case TYPE_0:
316 case TYPE_1:
317 case TYPE_2:
318 case TYPE_3:
319 case TYPE_4:
320 rand_type = type;
321 rand_deg = degrees[type];
322 rand_sep = seps[type];
323 break;
324 default:
325 return(NULL);
326 }
327 state = &new_state[1];
328 if (rand_type != TYPE_0) {
329 rptr = &state[rear];
330 fptr = &state[(rear + rand_sep) % rand_deg];
331 }
332 end_ptr = &state[rand_deg]; /* set end_ptr too */
333 return(ostate);
334}
335
336/*
337 * random:
338 *
339 * If we are using the trivial TYPE_0 R.N.G., just do the old linear
340 * congruential bit. Otherwise, we do our fancy trinomial stuff, which is
341 * the same in all the other cases due to all the global variables that have
342 * been set up. The basic operation is to add the number at the rear pointer
343 * into the one at the front pointer. Then both pointers are advanced to
344 * the next location cyclically in the table. The value returned is the sum
345 * generated, reduced to 31 bits by throwing away the "least random" low bit.
346 *
347 * Note: the code takes advantage of the fact that both the front and
348 * rear pointers can't wrap on the same call by not testing the rear
349 * pointer if the front one has wrapped.
350 *
351 * Returns a 31-bit random number.
352 */
353long
354random()
355{
356 long i;
357
358 if (rand_type == TYPE_0)
359 i = state[0] = (state[0] * 1103515245 + 12345) & 0x7fffffff;
360 else {
361 *fptr += *rptr;
362 i = (*fptr >> 1) & 0x7fffffff; /* chucking least random bit */
363 if (++fptr >= end_ptr) {
364 fptr = state;
365 ++rptr;
366 } else if (++rptr >= end_ptr)
367 rptr = state;
368 }
369 return(i);
370}
diff --git a/src/lib/libc/stdlib/realpath.3 b/src/lib/libc/stdlib/realpath.3
new file mode 100644
index 0000000000..cc140029e4
--- /dev/null
+++ b/src/lib/libc/stdlib/realpath.3
@@ -0,0 +1,125 @@
1.\" Copyright (c) 1994
2.\" The Regents of the University of California. All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Jan-Simon Pendry.
6.\"
7.\" Redistribution and use in source and binary forms, with or without
8.\" modification, are permitted provided that the following conditions
9.\" are met:
10.\" 1. Redistributions of source code must retain the above copyright
11.\" notice, this list of conditions and the following disclaimer.
12.\" 2. Redistributions in binary form must reproduce the above copyright
13.\" notice, this list of conditions and the following disclaimer in the
14.\" documentation and/or other materials provided with the distribution.
15.\" 3. All advertising materials mentioning features or use of this software
16.\" must display the following acknowledgement:
17.\" This product includes software developed by the University of
18.\" California, Berkeley and its contributors.
19.\" 4. Neither the name of the University nor the names of its contributors
20.\" may be used to endorse or promote products derived from this software
21.\" without specific prior written permission.
22.\"
23.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33.\" SUCH DAMAGE.
34.\"
35.\" $OpenBSD: realpath.3,v 1.3 1997/05/30 07:48:30 deraadt Exp $
36.\"
37.Dd February, 16, 1994
38.Dt REALPATH 3
39.Os
40.Sh NAME
41.Nm realpath
42.Nd returns the canonicalized absolute pathname
43.Sh SYNOPSIS
44.Fd #include <sys/param.h>
45.Fd #include <stdlib.h>
46.Ft "char *"
47.Fn realpath "const char *pathname" "char resolvedname[MAXPATHLEN]"
48.Sh DESCRIPTION
49The
50.Fn realpath
51function resolves all symbolic links, extra
52.Dq /
53characters and references to
54.Pa /./
55and
56.Pa /../
57in
58.Fa pathname ,
59and copies the resulting absolute pathname into
60the memory referenced by
61.Fa resolvedname .
62The
63.Fa resolvedname
64argument
65.Em must
66refer to a buffer capable of storing at least
67.Dv MAXPATHLEN
68characters.
69.Pp
70The
71.Fn realpath
72function will resolve both absolute and relative paths
73and return the absolute pathname corresponding to
74.Fa pathname .
75All but the last component of
76.Fa pathname
77must exist when
78.Fn realpath
79is called.
80.Sh "RETURN VALUES"
81The
82.Fn realpath
83function returns
84.Fa resolved_name
85on success.
86If an error occurs,
87.Fn realpath
88returns
89.Dv NULL ,
90and
91.Fa resolved_name
92contains the pathname which caused the problem.
93.Sh ERRORS
94The function
95.Fn realpath
96may fail and set the external variable
97.Va errno
98for any of the errors specified for the library functions
99.Xr chdir 2 ,
100.Xr close 2 ,
101.Xr fchdir 2 ,
102.Xr lstat 2 ,
103.Xr open 2 ,
104.Xr readlink 2
105and
106.Xr getcwd 3 .
107.Sh CAVEATS
108This implementation of
109.Fn realpath
110differs slightly from the Solaris implementation.
111The
112.Bx 4.4
113version always returns absolute pathnames,
114whereas the Solaris implementation will,
115under certain circumstances, return a relative
116.Fa resolved_path
117when given a relative
118.Fa pathname .
119.Sh "SEE ALSO"
120.Xr getcwd 3
121.Sh HISTORY
122The
123.Fn realpath
124function call first appeared in
125.Bx 4.4 .
diff --git a/src/lib/libc/stdlib/realpath.c b/src/lib/libc/stdlib/realpath.c
new file mode 100644
index 0000000000..0288601464
--- /dev/null
+++ b/src/lib/libc/stdlib/realpath.c
@@ -0,0 +1,163 @@
1/*
2 * Copyright (c) 1994
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Jan-Simon Pendry.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: realpath.c,v 1.4 1998/05/18 09:55:19 deraadt Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#include <sys/param.h>
42#include <sys/stat.h>
43
44#include <errno.h>
45#include <fcntl.h>
46#include <stdlib.h>
47#include <string.h>
48#include <unistd.h>
49
50/*
51 * char *realpath(const char *path, char resolved_path[MAXPATHLEN]);
52 *
53 * Find the real name of path, by removing all ".", ".." and symlink
54 * components. Returns (resolved) on success, or (NULL) on failure,
55 * in which case the path which caused trouble is left in (resolved).
56 */
57char *
58realpath(path, resolved)
59 const char *path;
60 char *resolved;
61{
62 struct stat sb;
63 int fd, n, rootd, serrno;
64 char *p, *q, wbuf[MAXPATHLEN];
65 int symlinks = 0;
66
67 /* Save the starting point. */
68 if ((fd = open(".", O_RDONLY)) < 0) {
69 (void)strcpy(resolved, ".");
70 return (NULL);
71 }
72
73 /*
74 * Find the dirname and basename from the path to be resolved.
75 * Change directory to the dirname component.
76 * lstat the basename part.
77 * if it is a symlink, read in the value and loop.
78 * if it is a directory, then change to that directory.
79 * get the current directory name and append the basename.
80 */
81 (void)strncpy(resolved, path, MAXPATHLEN - 1);
82 resolved[MAXPATHLEN - 1] = '\0';
83loop:
84 q = strrchr(resolved, '/');
85 if (q != NULL) {
86 p = q + 1;
87 if (q == resolved)
88 q = "/";
89 else {
90 do {
91 --q;
92 } while (q > resolved && *q == '/');
93 q[1] = '\0';
94 q = resolved;
95 }
96 if (chdir(q) < 0)
97 goto err1;
98 } else
99 p = resolved;
100
101 /* Deal with the last component. */
102 if (lstat(p, &sb) == 0) {
103 if (S_ISLNK(sb.st_mode)) {
104 if (++symlinks > MAXSYMLINKS) {
105 errno = ELOOP;
106 goto err1;
107 }
108 n = readlink(p, resolved, MAXPATHLEN-1);
109 if (n < 0)
110 goto err1;
111 resolved[n] = '\0';
112 goto loop;
113 }
114 if (S_ISDIR(sb.st_mode)) {
115 if (chdir(p) < 0)
116 goto err1;
117 p = "";
118 }
119 }
120
121 /*
122 * Save the last component name and get the full pathname of
123 * the current directory.
124 */
125 (void)strcpy(wbuf, p);
126 if (getcwd(resolved, MAXPATHLEN) == 0)
127 goto err1;
128
129 /*
130 * Join the two strings together, ensuring that the right thing
131 * happens if the last component is empty, or the dirname is root.
132 */
133 if (resolved[0] == '/' && resolved[1] == '\0')
134 rootd = 1;
135 else
136 rootd = 0;
137
138 if (*wbuf) {
139 if (strlen(resolved) + strlen(wbuf) + rootd + 1 > MAXPATHLEN) {
140 errno = ENAMETOOLONG;
141 goto err1;
142 }
143 if (rootd == 0)
144 (void)strcat(resolved, "/");
145 (void)strcat(resolved, wbuf);
146 }
147
148 /* Go back to where we came from. */
149 if (fchdir(fd) < 0) {
150 serrno = errno;
151 goto err2;
152 }
153
154 /* It's okay if the close fails, what's an fd more or less? */
155 (void)close(fd);
156 return (resolved);
157
158err1: serrno = errno;
159 (void)fchdir(fd);
160err2: (void)close(fd);
161 errno = serrno;
162 return (NULL);
163}
diff --git a/src/lib/libc/stdlib/seed48.c b/src/lib/libc/stdlib/seed48.c
new file mode 100644
index 0000000000..c4dcd0ead8
--- /dev/null
+++ b/src/lib/libc/stdlib/seed48.c
@@ -0,0 +1,40 @@
1/*
2 * Copyright (c) 1993 Martin Birgmeier
3 * All rights reserved.
4 *
5 * You may redistribute unmodified or modified versions of this source
6 * code provided that the above copyright notice and this and the
7 * following conditions are retained.
8 *
9 * This software is provided ``as is'', and comes with no warranties
10 * of any kind. I shall in no event be liable for anything that happens
11 * to anyone/anything when using this software.
12 */
13
14#if defined(LIBC_SCCS) && !defined(lint)
15static char rcsid[] = "$OpenBSD: seed48.c,v 1.2 1996/08/19 08:33:48 tholo Exp $";
16#endif /* LIBC_SCCS and not lint */
17
18#include "rand48.h"
19
20extern unsigned short __rand48_seed[3];
21extern unsigned short __rand48_mult[3];
22extern unsigned short __rand48_add;
23
24unsigned short *
25seed48(unsigned short xseed[3])
26{
27 static unsigned short sseed[3];
28
29 sseed[0] = __rand48_seed[0];
30 sseed[1] = __rand48_seed[1];
31 sseed[2] = __rand48_seed[2];
32 __rand48_seed[0] = xseed[0];
33 __rand48_seed[1] = xseed[1];
34 __rand48_seed[2] = xseed[2];
35 __rand48_mult[0] = RAND48_MULT_0;
36 __rand48_mult[1] = RAND48_MULT_1;
37 __rand48_mult[2] = RAND48_MULT_2;
38 __rand48_add = RAND48_ADD;
39 return sseed;
40}
diff --git a/src/lib/libc/stdlib/setenv.c b/src/lib/libc/stdlib/setenv.c
new file mode 100644
index 0000000000..b6f261e61c
--- /dev/null
+++ b/src/lib/libc/stdlib/setenv.c
@@ -0,0 +1,120 @@
1/*
2 * Copyright (c) 1987 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: setenv.c,v 1.3 1998/02/02 22:44:53 millert Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <stdlib.h>
39#include <string.h>
40
41/*
42 * setenv --
43 * Set the value of the environmental variable "name" to be
44 * "value". If rewrite is set, replace any current value.
45 */
46int
47setenv(name, value, rewrite)
48 register const char *name;
49 register const char *value;
50 int rewrite;
51{
52 extern char **environ;
53 static int alloced; /* if allocated space before */
54 register char *C;
55 int l_value, offset;
56 char *__findenv();
57
58 if (*value == '=') /* no `=' in value */
59 ++value;
60 l_value = strlen(value);
61 if ((C = __findenv(name, &offset))) { /* find if already exists */
62 if (!rewrite)
63 return (0);
64 if (strlen(C) >= l_value) { /* old larger; copy over */
65 while (*C++ = *value++);
66 return (0);
67 }
68 } else { /* create new slot */
69 register int cnt;
70 register char **P;
71
72 for (P = environ, cnt = 0; *P; ++P, ++cnt);
73 if (alloced) { /* just increase size */
74 P = (char **)realloc((void *)environ,
75 (size_t)(sizeof(char *) * (cnt + 2)));
76 if (!P)
77 return (-1);
78 environ = P;
79 }
80 else { /* get new space */
81 alloced = 1; /* copy old entries into it */
82 P = (char **)malloc((size_t)(sizeof(char *) *
83 (cnt + 2)));
84 if (!P)
85 return (-1);
86 bcopy(environ, P, cnt * sizeof(char *));
87 environ = P;
88 }
89 environ[cnt + 1] = NULL;
90 offset = cnt;
91 }
92 for (C = (char *)name; *C && *C != '='; ++C); /* no `=' in name */
93 if (!(environ[offset] = /* name + `=' + value */
94 malloc((size_t)((int)(C - name) + l_value + 2))))
95 return (-1);
96 for (C = environ[offset]; (*C = *name++) && *C != '='; ++C)
97 ;
98 for (*C++ = '='; *C++ = *value++; )
99 ;
100 return (0);
101}
102
103/*
104 * unsetenv(name) --
105 * Delete environmental variable "name".
106 */
107void
108unsetenv(name)
109 const char *name;
110{
111 extern char **environ;
112 register char **P;
113 int offset;
114 char *__findenv();
115
116 while (__findenv(name, &offset)) /* if set multiple times */
117 for (P = &environ[offset];; ++P)
118 if (!(*P = *(P + 1)))
119 break;
120}
diff --git a/src/lib/libc/stdlib/srand48.c b/src/lib/libc/stdlib/srand48.c
new file mode 100644
index 0000000000..fcff8a172e
--- /dev/null
+++ b/src/lib/libc/stdlib/srand48.c
@@ -0,0 +1,34 @@
1/*
2 * Copyright (c) 1993 Martin Birgmeier
3 * All rights reserved.
4 *
5 * You may redistribute unmodified or modified versions of this source
6 * code provided that the above copyright notice and this and the
7 * following conditions are retained.
8 *
9 * This software is provided ``as is'', and comes with no warranties
10 * of any kind. I shall in no event be liable for anything that happens
11 * to anyone/anything when using this software.
12 */
13
14#if defined(LIBC_SCCS) && !defined(lint)
15static char rcsid[] = "$OpenBSD: srand48.c,v 1.2 1996/08/19 08:33:49 tholo Exp $";
16#endif /* LIBC_SCCS and not lint */
17
18#include "rand48.h"
19
20extern unsigned short __rand48_seed[3];
21extern unsigned short __rand48_mult[3];
22extern unsigned short __rand48_add;
23
24void
25srand48(long seed)
26{
27 __rand48_seed[0] = RAND48_SEED_0;
28 __rand48_seed[1] = (unsigned short) seed;
29 __rand48_seed[2] = (unsigned short) (seed >> 16);
30 __rand48_mult[0] = RAND48_MULT_0;
31 __rand48_mult[1] = RAND48_MULT_1;
32 __rand48_mult[2] = RAND48_MULT_2;
33 __rand48_add = RAND48_ADD;
34}
diff --git a/src/lib/libc/stdlib/strtod.3 b/src/lib/libc/stdlib/strtod.3
new file mode 100644
index 0000000000..3476fa41d6
--- /dev/null
+++ b/src/lib/libc/stdlib/strtod.3
@@ -0,0 +1,113 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: strtod.3,v 1.2 1996/08/19 08:33:49 tholo Exp $
37.\"
38.Dd June 29, 1991
39.Dt STRTOD 3
40.Os
41.Sh NAME
42.Nm strtod
43.Nd convert
44.Tn ASCII
45string to double
46.Sh SYNOPSIS
47.Fd #include <stdlib.h>
48.Ft double
49.Fn strtod "const char *nptr" "char **endptr"
50.Sh DESCRIPTION
51The
52.Fn strtod
53function converts the initial portion of the string
54pointed to by
55.Fa nptr
56to
57.Em double
58representation.
59.Pp
60The expected form of the string is an optional plus (``+'') or minus
61sign (``-'') followed by a sequence of digits optionally containing
62a decimal-point character, optionally followed by an exponent.
63An exponent consists of an ``E'' or ``e'', followed by an optional plus
64or minus sign, followed by a sequence of digits.
65.Pp
66Leading white-space characters in the string (as defined by the
67.Xr isspace 3
68function) are skipped.
69.Sh RETURN VALUES
70The
71.Fn strtod
72function returns the converted value, if any.
73.Pp
74If
75.Fa endptr
76is not
77.Dv NULL ,
78a pointer to the character after the last character used
79in the conversion is stored in the location referenced by
80.Fa endptr .
81.Pp
82If no conversion is performed, zero is returned and the value of
83.Fa nptr
84is stored in the location referenced by
85.Fa endptr .
86.Pp
87If the correct value would cause overflow, plus or minus
88.Dv HUGE_VAL
89is returned (according to the sign of the value), and
90.Dv ERANGE
91is stored in
92.Va errno .
93If the correct value would cause underflow, zero is
94returned and
95.Dv ERANGE
96is stored in
97.Va errno .
98.Sh ERRORS
99.Bl -tag -width Er
100.It Bq Er ERANGE
101Overflow or underflow occurred.
102.Sh SEE ALSO
103.Xr atof 3 ,
104.Xr atoi 3 ,
105.Xr atol 3 ,
106.Xr strtol 3 ,
107.Xr strtoul 3
108.Sh STANDARDS
109The
110.Fn strtod
111function
112conforms to
113.St -ansiC .
diff --git a/src/lib/libc/stdlib/strtod.c b/src/lib/libc/stdlib/strtod.c
new file mode 100644
index 0000000000..55d9e91224
--- /dev/null
+++ b/src/lib/libc/stdlib/strtod.c
@@ -0,0 +1,2529 @@
1/****************************************************************
2 *
3 * The author of this software is David M. Gay.
4 *
5 * Copyright (c) 1991 by AT&T.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose without fee is hereby granted, provided that this entire notice
9 * is included in all copies of any software which is or includes a copy
10 * or modification of this software and in all copies of the supporting
11 * documentation for such software.
12 *
13 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
14 * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY
15 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
16 * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
17 *
18 ***************************************************************/
19
20/* Please send bug reports to
21 David M. Gay
22 AT&T Bell Laboratories, Room 2C-463
23 600 Mountain Avenue
24 Murray Hill, NJ 07974-2070
25 U.S.A.
26 dmg@research.att.com or research!dmg
27 */
28
29/* strtod for IEEE-, VAX-, and IBM-arithmetic machines.
30 *
31 * This strtod returns a nearest machine number to the input decimal
32 * string (or sets errno to ERANGE). With IEEE arithmetic, ties are
33 * broken by the IEEE round-even rule. Otherwise ties are broken by
34 * biased rounding (add half and chop).
35 *
36 * Inspired loosely by William D. Clinger's paper "How to Read Floating
37 * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101].
38 *
39 * Modifications:
40 *
41 * 1. We only require IEEE, IBM, or VAX double-precision
42 * arithmetic (not IEEE double-extended).
43 * 2. We get by with floating-point arithmetic in a case that
44 * Clinger missed -- when we're computing d * 10^n
45 * for a small integer d and the integer n is not too
46 * much larger than 22 (the maximum integer k for which
47 * we can represent 10^k exactly), we may be able to
48 * compute (d*10^k) * 10^(e-k) with just one roundoff.
49 * 3. Rather than a bit-at-a-time adjustment of the binary
50 * result in the hard case, we use floating-point
51 * arithmetic to determine the adjustment to within
52 * one bit; only in really hard cases do we need to
53 * compute a second residual.
54 * 4. Because of 3., we don't need a large table of powers of 10
55 * for ten-to-e (just some small tables, e.g. of 10^k
56 * for 0 <= k <= 22).
57 */
58
59/*
60 * #define IEEE_LITTLE_ENDIAN for IEEE-arithmetic machines where the least
61 * significant byte has the lowest address.
62 * #define IEEE_BIG_ENDIAN for IEEE-arithmetic machines where the most
63 * significant byte has the lowest address.
64 * #define Long int on machines with 32-bit ints and 64-bit longs.
65 * #define Sudden_Underflow for IEEE-format machines without gradual
66 * underflow (i.e., that flush to zero on underflow).
67 * #define IBM for IBM mainframe-style floating-point arithmetic.
68 * #define VAX for VAX-style floating-point arithmetic.
69 * #define Unsigned_Shifts if >> does treats its left operand as unsigned.
70 * #define No_leftright to omit left-right logic in fast floating-point
71 * computation of dtoa.
72 * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3.
73 * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines
74 * that use extended-precision instructions to compute rounded
75 * products and quotients) with IBM.
76 * #define ROUND_BIASED for IEEE-format with biased rounding.
77 * #define Inaccurate_Divide for IEEE-format with correctly rounded
78 * products but inaccurate quotients, e.g., for Intel i860.
79 * #define Just_16 to store 16 bits per 32-bit Long when doing high-precision
80 * integer arithmetic. Whether this speeds things up or slows things
81 * down depends on the machine and the number being converted.
82 * #define KR_headers for old-style C function headers.
83 * #define Bad_float_h if your system lacks a float.h or if it does not
84 * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP,
85 * FLT_RADIX, FLT_ROUNDS, and DBL_MAX.
86 * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n)
87 * if memory is available and otherwise does something you deem
88 * appropriate. If MALLOC is undefined, malloc will be invoked
89 * directly -- and assumed always to succeed.
90 */
91
92#if defined(LIBC_SCCS) && !defined(lint)
93static char *rcsid = "$OpenBSD: strtod.c,v 1.12 1998/08/28 20:49:24 mickey Exp $";
94#endif /* LIBC_SCCS and not lint */
95
96#if defined(__m68k__) || defined(__sparc__) || defined(__i386__) || \
97 defined(__mips__) || defined(__ns32k__) || defined(__alpha__) || \
98 defined(__powerpc__) || defined(__m88k__) || defined(__hppa__)
99#include <sys/types.h>
100#if BYTE_ORDER == BIG_ENDIAN
101#define IEEE_BIG_ENDIAN
102#else
103#define IEEE_LITTLE_ENDIAN
104#endif
105#endif
106
107#ifdef __arm32__
108/*
109 * Although the CPU is little endian the FP has different
110 * byte and word endianness. The byte order is still little endian
111 * but the word order is big endian.
112 */
113#define IEEE_BIG_ENDIAN
114#endif
115
116#ifdef vax
117#define VAX
118#endif
119
120#define Long int32_t
121#define ULong u_int32_t
122
123#ifdef DEBUG
124#include "stdio.h"
125#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);}
126#endif
127
128#ifdef __cplusplus
129#include "malloc.h"
130#include "memory.h"
131#else
132#ifndef KR_headers
133#include "stdlib.h"
134#include "string.h"
135#include "locale.h"
136#else
137#include "malloc.h"
138#include "memory.h"
139#endif
140#endif
141
142#ifdef MALLOC
143#ifdef KR_headers
144extern char *MALLOC();
145#else
146extern void *MALLOC(size_t);
147#endif
148#else
149#define MALLOC malloc
150#endif
151
152#include "ctype.h"
153#include "errno.h"
154
155#ifdef Bad_float_h
156#undef __STDC__
157#ifdef IEEE_BIG_ENDIAN
158#define IEEE_ARITHMETIC
159#endif
160#ifdef IEEE_LITTLE_ENDIAN
161#define IEEE_ARITHMETIC
162#endif
163
164#ifdef IEEE_ARITHMETIC
165#define DBL_DIG 15
166#define DBL_MAX_10_EXP 308
167#define DBL_MAX_EXP 1024
168#define FLT_RADIX 2
169#define FLT_ROUNDS 1
170#define DBL_MAX 1.7976931348623157e+308
171#endif
172
173#ifdef IBM
174#define DBL_DIG 16
175#define DBL_MAX_10_EXP 75
176#define DBL_MAX_EXP 63
177#define FLT_RADIX 16
178#define FLT_ROUNDS 0
179#define DBL_MAX 7.2370055773322621e+75
180#endif
181
182#ifdef VAX
183#define DBL_DIG 16
184#define DBL_MAX_10_EXP 38
185#define DBL_MAX_EXP 127
186#define FLT_RADIX 2
187#define FLT_ROUNDS 1
188#define DBL_MAX 1.7014118346046923e+38
189#endif
190
191#ifndef LONG_MAX
192#define LONG_MAX 2147483647
193#endif
194#else
195#include "float.h"
196#endif
197#ifndef __MATH_H__
198#include "math.h"
199#endif
200
201#ifdef __cplusplus
202extern "C" {
203#endif
204
205#ifndef CONST
206#ifdef KR_headers
207#define CONST /* blank */
208#else
209#define CONST const
210#endif
211#endif
212
213#ifdef Unsigned_Shifts
214#define Sign_Extend(a,b) if (b < 0) a |= 0xffff0000;
215#else
216#define Sign_Extend(a,b) /*no-op*/
217#endif
218
219#if defined(IEEE_LITTLE_ENDIAN) + defined(IEEE_BIG_ENDIAN) + defined(VAX) + \
220 defined(IBM) != 1
221Exactly one of IEEE_LITTLE_ENDIAN IEEE_BIG_ENDIAN, VAX, or
222IBM should be defined.
223#endif
224
225typedef union {
226 double d;
227 ULong ul[2];
228} _double;
229#define value(x) ((x).d)
230#ifdef IEEE_LITTLE_ENDIAN
231#define word0(x) ((x).ul[1])
232#define word1(x) ((x).ul[0])
233#else
234#define word0(x) ((x).ul[0])
235#define word1(x) ((x).ul[1])
236#endif
237
238/* The following definition of Storeinc is appropriate for MIPS processors.
239 * An alternative that might be better on some machines is
240 * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff)
241 */
242#if defined(IEEE_LITTLE_ENDIAN) + defined(VAX) + defined(__arm32__)
243#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \
244((unsigned short *)a)[0] = (unsigned short)c, a++)
245#else
246#define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \
247((unsigned short *)a)[1] = (unsigned short)c, a++)
248#endif
249
250/* #define P DBL_MANT_DIG */
251/* Ten_pmax = floor(P*log(2)/log(5)) */
252/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */
253/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */
254/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */
255
256#if defined(IEEE_LITTLE_ENDIAN) + defined(IEEE_BIG_ENDIAN)
257#define Exp_shift 20
258#define Exp_shift1 20
259#define Exp_msk1 0x100000
260#define Exp_msk11 0x100000
261#define Exp_mask 0x7ff00000
262#define P 53
263#define Bias 1023
264#define IEEE_Arith
265#define Emin (-1022)
266#define Exp_1 0x3ff00000
267#define Exp_11 0x3ff00000
268#define Ebits 11
269#define Frac_mask 0xfffff
270#define Frac_mask1 0xfffff
271#define Ten_pmax 22
272#define Bletch 0x10
273#define Bndry_mask 0xfffff
274#define Bndry_mask1 0xfffff
275#define LSB 1
276#define Sign_bit 0x80000000
277#define Log2P 1
278#define Tiny0 0
279#define Tiny1 1
280#define Quick_max 14
281#define Int_max 14
282#define Infinite(x) (word0(x) == 0x7ff00000) /* sufficient test for here */
283#else
284#undef Sudden_Underflow
285#define Sudden_Underflow
286#ifdef IBM
287#define Exp_shift 24
288#define Exp_shift1 24
289#define Exp_msk1 0x1000000
290#define Exp_msk11 0x1000000
291#define Exp_mask 0x7f000000
292#define P 14
293#define Bias 65
294#define Exp_1 0x41000000
295#define Exp_11 0x41000000
296#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */
297#define Frac_mask 0xffffff
298#define Frac_mask1 0xffffff
299#define Bletch 4
300#define Ten_pmax 22
301#define Bndry_mask 0xefffff
302#define Bndry_mask1 0xffffff
303#define LSB 1
304#define Sign_bit 0x80000000
305#define Log2P 4
306#define Tiny0 0x100000
307#define Tiny1 0
308#define Quick_max 14
309#define Int_max 15
310#else /* VAX */
311#define Exp_shift 23
312#define Exp_shift1 7
313#define Exp_msk1 0x80
314#define Exp_msk11 0x800000
315#define Exp_mask 0x7f80
316#define P 56
317#define Bias 129
318#define Exp_1 0x40800000
319#define Exp_11 0x4080
320#define Ebits 8
321#define Frac_mask 0x7fffff
322#define Frac_mask1 0xffff007f
323#define Ten_pmax 24
324#define Bletch 2
325#define Bndry_mask 0xffff007f
326#define Bndry_mask1 0xffff007f
327#define LSB 0x10000
328#define Sign_bit 0x8000
329#define Log2P 1
330#define Tiny0 0x80
331#define Tiny1 0
332#define Quick_max 15
333#define Int_max 15
334#endif
335#endif
336
337#ifndef IEEE_Arith
338#define ROUND_BIASED
339#endif
340
341#ifdef RND_PRODQUOT
342#define rounded_product(a,b) a = rnd_prod(a, b)
343#define rounded_quotient(a,b) a = rnd_quot(a, b)
344#ifdef KR_headers
345extern double rnd_prod(), rnd_quot();
346#else
347extern double rnd_prod(double, double), rnd_quot(double, double);
348#endif
349#else
350#define rounded_product(a,b) a *= b
351#define rounded_quotient(a,b) a /= b
352#endif
353
354#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1))
355#define Big1 0xffffffff
356
357#ifndef Just_16
358/* When Pack_32 is not defined, we store 16 bits per 32-bit Long.
359 * This makes some inner loops simpler and sometimes saves work
360 * during multiplications, but it often seems to make things slightly
361 * slower. Hence the default is now to store 32 bits per Long.
362 */
363#ifndef Pack_32
364#define Pack_32
365#endif
366#endif
367
368#define Kmax 15
369
370#ifdef __cplusplus
371extern "C" double strtod(const char *s00, char **se);
372extern "C" char *__dtoa(double d, int mode, int ndigits,
373 int *decpt, int *sign, char **rve);
374#endif
375
376 struct
377Bigint {
378 struct Bigint *next;
379 int k, maxwds, sign, wds;
380 ULong x[1];
381 };
382
383 typedef struct Bigint Bigint;
384
385 static Bigint *freelist[Kmax+1];
386
387 static Bigint *
388Balloc
389#ifdef KR_headers
390 (k) int k;
391#else
392 (int k)
393#endif
394{
395 int x;
396 Bigint *rv;
397
398 if (rv = freelist[k]) {
399 freelist[k] = rv->next;
400 }
401 else {
402 x = 1 << k;
403 rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(Long));
404 rv->k = k;
405 rv->maxwds = x;
406 }
407 rv->sign = rv->wds = 0;
408 return rv;
409 }
410
411 static void
412Bfree
413#ifdef KR_headers
414 (v) Bigint *v;
415#else
416 (Bigint *v)
417#endif
418{
419 if (v) {
420 v->next = freelist[v->k];
421 freelist[v->k] = v;
422 }
423 }
424
425#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \
426y->wds*sizeof(Long) + 2*sizeof(int))
427
428 static Bigint *
429multadd
430#ifdef KR_headers
431 (b, m, a) Bigint *b; int m, a;
432#else
433 (Bigint *b, int m, int a) /* multiply by m and add a */
434#endif
435{
436 int i, wds;
437 ULong *x, y;
438#ifdef Pack_32
439 ULong xi, z;
440#endif
441 Bigint *b1;
442
443 wds = b->wds;
444 x = b->x;
445 i = 0;
446 do {
447#ifdef Pack_32
448 xi = *x;
449 y = (xi & 0xffff) * m + a;
450 z = (xi >> 16) * m + (y >> 16);
451 a = (int)(z >> 16);
452 *x++ = (z << 16) + (y & 0xffff);
453#else
454 y = *x * m + a;
455 a = (int)(y >> 16);
456 *x++ = y & 0xffff;
457#endif
458 }
459 while(++i < wds);
460 if (a) {
461 if (wds >= b->maxwds) {
462 b1 = Balloc(b->k+1);
463 Bcopy(b1, b);
464 Bfree(b);
465 b = b1;
466 }
467 b->x[wds++] = a;
468 b->wds = wds;
469 }
470 return b;
471 }
472
473 static Bigint *
474s2b
475#ifdef KR_headers
476 (s, nd0, nd, y9) CONST char *s; int nd0, nd; ULong y9;
477#else
478 (CONST char *s, int nd0, int nd, ULong y9)
479#endif
480{
481 Bigint *b;
482 int i, k;
483 Long x, y;
484
485 x = (nd + 8) / 9;
486 for(k = 0, y = 1; x > y; y <<= 1, k++) ;
487#ifdef Pack_32
488 b = Balloc(k);
489 b->x[0] = y9;
490 b->wds = 1;
491#else
492 b = Balloc(k+1);
493 b->x[0] = y9 & 0xffff;
494 b->wds = (b->x[1] = y9 >> 16) ? 2 : 1;
495#endif
496
497 i = 9;
498 if (9 < nd0) {
499 s += 9;
500 do b = multadd(b, 10, *s++ - '0');
501 while(++i < nd0);
502 s++;
503 }
504 else
505 s += 10;
506 for(; i < nd; i++)
507 b = multadd(b, 10, *s++ - '0');
508 return b;
509 }
510
511 static int
512hi0bits
513#ifdef KR_headers
514 (x) register ULong x;
515#else
516 (register ULong x)
517#endif
518{
519 register int k = 0;
520
521 if (!(x & 0xffff0000)) {
522 k = 16;
523 x <<= 16;
524 }
525 if (!(x & 0xff000000)) {
526 k += 8;
527 x <<= 8;
528 }
529 if (!(x & 0xf0000000)) {
530 k += 4;
531 x <<= 4;
532 }
533 if (!(x & 0xc0000000)) {
534 k += 2;
535 x <<= 2;
536 }
537 if (!(x & 0x80000000)) {
538 k++;
539 if (!(x & 0x40000000))
540 return 32;
541 }
542 return k;
543 }
544
545 static int
546lo0bits
547#ifdef KR_headers
548 (y) ULong *y;
549#else
550 (ULong *y)
551#endif
552{
553 register int k;
554 register ULong x = *y;
555
556 if (x & 7) {
557 if (x & 1)
558 return 0;
559 if (x & 2) {
560 *y = x >> 1;
561 return 1;
562 }
563 *y = x >> 2;
564 return 2;
565 }
566 k = 0;
567 if (!(x & 0xffff)) {
568 k = 16;
569 x >>= 16;
570 }
571 if (!(x & 0xff)) {
572 k += 8;
573 x >>= 8;
574 }
575 if (!(x & 0xf)) {
576 k += 4;
577 x >>= 4;
578 }
579 if (!(x & 0x3)) {
580 k += 2;
581 x >>= 2;
582 }
583 if (!(x & 1)) {
584 k++;
585 x >>= 1;
586 if (!x & 1)
587 return 32;
588 }
589 *y = x;
590 return k;
591 }
592
593 static Bigint *
594i2b
595#ifdef KR_headers
596 (i) int i;
597#else
598 (int i)
599#endif
600{
601 Bigint *b;
602
603 b = Balloc(1);
604 b->x[0] = i;
605 b->wds = 1;
606 return b;
607 }
608
609 static Bigint *
610mult
611#ifdef KR_headers
612 (a, b) Bigint *a, *b;
613#else
614 (Bigint *a, Bigint *b)
615#endif
616{
617 Bigint *c;
618 int k, wa, wb, wc;
619 ULong carry, y, z;
620 ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
621#ifdef Pack_32
622 ULong z2;
623#endif
624
625 if (a->wds < b->wds) {
626 c = a;
627 a = b;
628 b = c;
629 }
630 k = a->k;
631 wa = a->wds;
632 wb = b->wds;
633 wc = wa + wb;
634 if (wc > a->maxwds)
635 k++;
636 c = Balloc(k);
637 for(x = c->x, xa = x + wc; x < xa; x++)
638 *x = 0;
639 xa = a->x;
640 xae = xa + wa;
641 xb = b->x;
642 xbe = xb + wb;
643 xc0 = c->x;
644#ifdef Pack_32
645 for(; xb < xbe; xb++, xc0++) {
646 if (y = *xb & 0xffff) {
647 x = xa;
648 xc = xc0;
649 carry = 0;
650 do {
651 z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
652 carry = z >> 16;
653 z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
654 carry = z2 >> 16;
655 Storeinc(xc, z2, z);
656 }
657 while(x < xae);
658 *xc = carry;
659 }
660 if (y = *xb >> 16) {
661 x = xa;
662 xc = xc0;
663 carry = 0;
664 z2 = *xc;
665 do {
666 z = (*x & 0xffff) * y + (*xc >> 16) + carry;
667 carry = z >> 16;
668 Storeinc(xc, z, z2);
669 z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
670 carry = z2 >> 16;
671 }
672 while(x < xae);
673 *xc = z2;
674 }
675 }
676#else
677 for(; xb < xbe; xc0++) {
678 if (y = *xb++) {
679 x = xa;
680 xc = xc0;
681 carry = 0;
682 do {
683 z = *x++ * y + *xc + carry;
684 carry = z >> 16;
685 *xc++ = z & 0xffff;
686 }
687 while(x < xae);
688 *xc = carry;
689 }
690 }
691#endif
692 for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ;
693 c->wds = wc;
694 return c;
695 }
696
697 static Bigint *p5s;
698
699 static Bigint *
700pow5mult
701#ifdef KR_headers
702 (b, k) Bigint *b; int k;
703#else
704 (Bigint *b, int k)
705#endif
706{
707 Bigint *b1, *p5, *p51;
708 int i;
709 static int p05[3] = { 5, 25, 125 };
710
711 if (i = k & 3)
712 b = multadd(b, p05[i-1], 0);
713
714 if (!(k >>= 2))
715 return b;
716 if (!(p5 = p5s)) {
717 /* first time */
718 p5 = p5s = i2b(625);
719 p5->next = 0;
720 }
721 for(;;) {
722 if (k & 1) {
723 b1 = mult(b, p5);
724 Bfree(b);
725 b = b1;
726 }
727 if (!(k >>= 1))
728 break;
729 if (!(p51 = p5->next)) {
730 p51 = p5->next = mult(p5,p5);
731 p51->next = 0;
732 }
733 p5 = p51;
734 }
735 return b;
736 }
737
738 static Bigint *
739lshift
740#ifdef KR_headers
741 (b, k) Bigint *b; int k;
742#else
743 (Bigint *b, int k)
744#endif
745{
746 int i, k1, n, n1;
747 Bigint *b1;
748 ULong *x, *x1, *xe, z;
749
750#ifdef Pack_32
751 n = k >> 5;
752#else
753 n = k >> 4;
754#endif
755 k1 = b->k;
756 n1 = n + b->wds + 1;
757 for(i = b->maxwds; n1 > i; i <<= 1)
758 k1++;
759 b1 = Balloc(k1);
760 x1 = b1->x;
761 for(i = 0; i < n; i++)
762 *x1++ = 0;
763 x = b->x;
764 xe = x + b->wds;
765#ifdef Pack_32
766 if (k &= 0x1f) {
767 k1 = 32 - k;
768 z = 0;
769 do {
770 *x1++ = *x << k | z;
771 z = *x++ >> k1;
772 }
773 while(x < xe);
774 if (*x1 = z)
775 ++n1;
776 }
777#else
778 if (k &= 0xf) {
779 k1 = 16 - k;
780 z = 0;
781 do {
782 *x1++ = *x << k & 0xffff | z;
783 z = *x++ >> k1;
784 }
785 while(x < xe);
786 if (*x1 = z)
787 ++n1;
788 }
789#endif
790 else do
791 *x1++ = *x++;
792 while(x < xe);
793 b1->wds = n1 - 1;
794 Bfree(b);
795 return b1;
796 }
797
798 static int
799cmp
800#ifdef KR_headers
801 (a, b) Bigint *a, *b;
802#else
803 (Bigint *a, Bigint *b)
804#endif
805{
806 ULong *xa, *xa0, *xb, *xb0;
807 int i, j;
808
809 i = a->wds;
810 j = b->wds;
811#ifdef DEBUG
812 if (i > 1 && !a->x[i-1])
813 Bug("cmp called with a->x[a->wds-1] == 0");
814 if (j > 1 && !b->x[j-1])
815 Bug("cmp called with b->x[b->wds-1] == 0");
816#endif
817 if (i -= j)
818 return i;
819 xa0 = a->x;
820 xa = xa0 + j;
821 xb0 = b->x;
822 xb = xb0 + j;
823 for(;;) {
824 if (*--xa != *--xb)
825 return *xa < *xb ? -1 : 1;
826 if (xa <= xa0)
827 break;
828 }
829 return 0;
830 }
831
832 static Bigint *
833diff
834#ifdef KR_headers
835 (a, b) Bigint *a, *b;
836#else
837 (Bigint *a, Bigint *b)
838#endif
839{
840 Bigint *c;
841 int i, wa, wb;
842 Long borrow, y; /* We need signed shifts here. */
843 ULong *xa, *xae, *xb, *xbe, *xc;
844#ifdef Pack_32
845 Long z;
846#endif
847
848 i = cmp(a,b);
849 if (!i) {
850 c = Balloc(0);
851 c->wds = 1;
852 c->x[0] = 0;
853 return c;
854 }
855 if (i < 0) {
856 c = a;
857 a = b;
858 b = c;
859 i = 1;
860 }
861 else
862 i = 0;
863 c = Balloc(a->k);
864 c->sign = i;
865 wa = a->wds;
866 xa = a->x;
867 xae = xa + wa;
868 wb = b->wds;
869 xb = b->x;
870 xbe = xb + wb;
871 xc = c->x;
872 borrow = 0;
873#ifdef Pack_32
874 do {
875 y = (*xa & 0xffff) - (*xb & 0xffff) + borrow;
876 borrow = y >> 16;
877 Sign_Extend(borrow, y);
878 z = (*xa++ >> 16) - (*xb++ >> 16) + borrow;
879 borrow = z >> 16;
880 Sign_Extend(borrow, z);
881 Storeinc(xc, z, y);
882 }
883 while(xb < xbe);
884 while(xa < xae) {
885 y = (*xa & 0xffff) + borrow;
886 borrow = y >> 16;
887 Sign_Extend(borrow, y);
888 z = (*xa++ >> 16) + borrow;
889 borrow = z >> 16;
890 Sign_Extend(borrow, z);
891 Storeinc(xc, z, y);
892 }
893#else
894 do {
895 y = *xa++ - *xb++ + borrow;
896 borrow = y >> 16;
897 Sign_Extend(borrow, y);
898 *xc++ = y & 0xffff;
899 }
900 while(xb < xbe);
901 while(xa < xae) {
902 y = *xa++ + borrow;
903 borrow = y >> 16;
904 Sign_Extend(borrow, y);
905 *xc++ = y & 0xffff;
906 }
907#endif
908 while(!*--xc)
909 wa--;
910 c->wds = wa;
911 return c;
912 }
913
914 static double
915ulp
916#ifdef KR_headers
917 (_x) double _x;
918#else
919 (double _x)
920#endif
921{
922 _double x;
923 register Long L;
924 _double a;
925
926 value(x) = _x;
927 L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1;
928#ifndef Sudden_Underflow
929 if (L > 0) {
930#endif
931#ifdef IBM
932 L |= Exp_msk1 >> 4;
933#endif
934 word0(a) = L;
935 word1(a) = 0;
936#ifndef Sudden_Underflow
937 }
938 else {
939 L = -L >> Exp_shift;
940 if (L < Exp_shift) {
941 word0(a) = 0x80000 >> L;
942 word1(a) = 0;
943 }
944 else {
945 word0(a) = 0;
946 L -= Exp_shift;
947 word1(a) = L >= 31 ? 1 : 1 << 31 - L;
948 }
949 }
950#endif
951 return value(a);
952 }
953
954 static double
955b2d
956#ifdef KR_headers
957 (a, e) Bigint *a; int *e;
958#else
959 (Bigint *a, int *e)
960#endif
961{
962 ULong *xa, *xa0, w, y, z;
963 int k;
964 _double d;
965#ifdef VAX
966 ULong d0, d1;
967#else
968#define d0 word0(d)
969#define d1 word1(d)
970#endif
971
972 xa0 = a->x;
973 xa = xa0 + a->wds;
974 y = *--xa;
975#ifdef DEBUG
976 if (!y) Bug("zero y in b2d");
977#endif
978 k = hi0bits(y);
979 *e = 32 - k;
980#ifdef Pack_32
981 if (k < Ebits) {
982 d0 = Exp_1 | y >> Ebits - k;
983 w = xa > xa0 ? *--xa : 0;
984 d1 = y << (32-Ebits) + k | w >> Ebits - k;
985 goto ret_d;
986 }
987 z = xa > xa0 ? *--xa : 0;
988 if (k -= Ebits) {
989 d0 = Exp_1 | y << k | z >> 32 - k;
990 y = xa > xa0 ? *--xa : 0;
991 d1 = z << k | y >> 32 - k;
992 }
993 else {
994 d0 = Exp_1 | y;
995 d1 = z;
996 }
997#else
998 if (k < Ebits + 16) {
999 z = xa > xa0 ? *--xa : 0;
1000 d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k;
1001 w = xa > xa0 ? *--xa : 0;
1002 y = xa > xa0 ? *--xa : 0;
1003 d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k;
1004 goto ret_d;
1005 }
1006 z = xa > xa0 ? *--xa : 0;
1007 w = xa > xa0 ? *--xa : 0;
1008 k -= Ebits + 16;
1009 d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k;
1010 y = xa > xa0 ? *--xa : 0;
1011 d1 = w << k + 16 | y << k;
1012#endif
1013 ret_d:
1014#ifdef VAX
1015 word0(d) = d0 >> 16 | d0 << 16;
1016 word1(d) = d1 >> 16 | d1 << 16;
1017#else
1018#undef d0
1019#undef d1
1020#endif
1021 return value(d);
1022 }
1023
1024 static Bigint *
1025d2b
1026#ifdef KR_headers
1027 (_d, e, bits) double d; int *e, *bits;
1028#else
1029 (double _d, int *e, int *bits)
1030#endif
1031{
1032 Bigint *b;
1033 int de, i, k;
1034 ULong *x, y, z;
1035 _double d;
1036#ifdef VAX
1037 ULong d0, d1;
1038#endif
1039
1040 value(d) = _d;
1041#ifdef VAX
1042 d0 = word0(d) >> 16 | word0(d) << 16;
1043 d1 = word1(d) >> 16 | word1(d) << 16;
1044#else
1045#define d0 word0(d)
1046#define d1 word1(d)
1047#endif
1048
1049#ifdef Pack_32
1050 b = Balloc(1);
1051#else
1052 b = Balloc(2);
1053#endif
1054 x = b->x;
1055
1056 z = d0 & Frac_mask;
1057 d0 &= 0x7fffffff; /* clear sign bit, which we ignore */
1058#ifdef Sudden_Underflow
1059 de = (int)(d0 >> Exp_shift);
1060#ifndef IBM
1061 z |= Exp_msk11;
1062#endif
1063#else
1064 if (de = (int)(d0 >> Exp_shift))
1065 z |= Exp_msk1;
1066#endif
1067#ifdef Pack_32
1068 if (y = d1) {
1069 if (k = lo0bits(&y)) {
1070 x[0] = y | z << 32 - k;
1071 z >>= k;
1072 }
1073 else
1074 x[0] = y;
1075 i = b->wds = (x[1] = z) ? 2 : 1;
1076 }
1077 else {
1078#ifdef DEBUG
1079 if (!z)
1080 Bug("Zero passed to d2b");
1081#endif
1082 k = lo0bits(&z);
1083 x[0] = z;
1084 i = b->wds = 1;
1085 k += 32;
1086 }
1087#else
1088 if (y = d1) {
1089 if (k = lo0bits(&y))
1090 if (k >= 16) {
1091 x[0] = y | z << 32 - k & 0xffff;
1092 x[1] = z >> k - 16 & 0xffff;
1093 x[2] = z >> k;
1094 i = 2;
1095 }
1096 else {
1097 x[0] = y & 0xffff;
1098 x[1] = y >> 16 | z << 16 - k & 0xffff;
1099 x[2] = z >> k & 0xffff;
1100 x[3] = z >> k+16;
1101 i = 3;
1102 }
1103 else {
1104 x[0] = y & 0xffff;
1105 x[1] = y >> 16;
1106 x[2] = z & 0xffff;
1107 x[3] = z >> 16;
1108 i = 3;
1109 }
1110 }
1111 else {
1112#ifdef DEBUG
1113 if (!z)
1114 Bug("Zero passed to d2b");
1115#endif
1116 k = lo0bits(&z);
1117 if (k >= 16) {
1118 x[0] = z;
1119 i = 0;
1120 }
1121 else {
1122 x[0] = z & 0xffff;
1123 x[1] = z >> 16;
1124 i = 1;
1125 }
1126 k += 32;
1127 }
1128 while(!x[i])
1129 --i;
1130 b->wds = i + 1;
1131#endif
1132#ifndef Sudden_Underflow
1133 if (de) {
1134#endif
1135#ifdef IBM
1136 *e = (de - Bias - (P-1) << 2) + k;
1137 *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask);
1138#else
1139 *e = de - Bias - (P-1) + k;
1140 *bits = P - k;
1141#endif
1142#ifndef Sudden_Underflow
1143 }
1144 else {
1145 *e = de - Bias - (P-1) + 1 + k;
1146#ifdef Pack_32
1147 *bits = 32*i - hi0bits(x[i-1]);
1148#else
1149 *bits = (i+2)*16 - hi0bits(x[i]);
1150#endif
1151 }
1152#endif
1153 return b;
1154 }
1155#undef d0
1156#undef d1
1157
1158 static double
1159ratio
1160#ifdef KR_headers
1161 (a, b) Bigint *a, *b;
1162#else
1163 (Bigint *a, Bigint *b)
1164#endif
1165{
1166 _double da, db;
1167 int k, ka, kb;
1168
1169 value(da) = b2d(a, &ka);
1170 value(db) = b2d(b, &kb);
1171#ifdef Pack_32
1172 k = ka - kb + 32*(a->wds - b->wds);
1173#else
1174 k = ka - kb + 16*(a->wds - b->wds);
1175#endif
1176#ifdef IBM
1177 if (k > 0) {
1178 word0(da) += (k >> 2)*Exp_msk1;
1179 if (k &= 3)
1180 da *= 1 << k;
1181 }
1182 else {
1183 k = -k;
1184 word0(db) += (k >> 2)*Exp_msk1;
1185 if (k &= 3)
1186 db *= 1 << k;
1187 }
1188#else
1189 if (k > 0)
1190 word0(da) += k*Exp_msk1;
1191 else {
1192 k = -k;
1193 word0(db) += k*Exp_msk1;
1194 }
1195#endif
1196 return value(da) / value(db);
1197 }
1198
1199static CONST double
1200tens[] = {
1201 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
1202 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
1203 1e20, 1e21, 1e22
1204#ifdef VAX
1205 , 1e23, 1e24
1206#endif
1207 };
1208
1209#ifdef IEEE_Arith
1210static CONST double bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
1211static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256 };
1212#define n_bigtens 5
1213#else
1214#ifdef IBM
1215static CONST double bigtens[] = { 1e16, 1e32, 1e64 };
1216static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 };
1217#define n_bigtens 3
1218#else
1219static CONST double bigtens[] = { 1e16, 1e32 };
1220static CONST double tinytens[] = { 1e-16, 1e-32 };
1221#define n_bigtens 2
1222#endif
1223#endif
1224
1225 double
1226strtod
1227#ifdef KR_headers
1228 (s00, se) CONST char *s00; char **se;
1229#else
1230 (CONST char *s00, char **se)
1231#endif
1232{
1233 int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign,
1234 e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
1235 CONST char *s, *s0, *s1;
1236 double aadj, aadj1, adj;
1237 _double rv, rv0;
1238 Long L;
1239 ULong y, z;
1240 Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
1241
1242#ifndef KR_headers
1243 CONST char decimal_point = localeconv()->decimal_point[0];
1244#else
1245 CONST char decimal_point = '.';
1246#endif
1247
1248 sign = nz0 = nz = 0;
1249 value(rv) = 0.;
1250
1251
1252 for(s = s00; isspace((unsigned char) *s); s++)
1253 ;
1254
1255 if (*s == '-') {
1256 sign = 1;
1257 s++;
1258 } else if (*s == '+') {
1259 s++;
1260 }
1261
1262 if (*s == '\0') {
1263 s = s00;
1264 goto ret;
1265 }
1266
1267 if (*s == '0') {
1268 nz0 = 1;
1269 while(*++s == '0') ;
1270 if (!*s)
1271 goto ret;
1272 }
1273 s0 = s;
1274 y = z = 0;
1275 for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
1276 if (nd < 9)
1277 y = 10*y + c - '0';
1278 else if (nd < 16)
1279 z = 10*z + c - '0';
1280 nd0 = nd;
1281 if (c == decimal_point) {
1282 c = *++s;
1283 if (!nd) {
1284 for(; c == '0'; c = *++s)
1285 nz++;
1286 if (c > '0' && c <= '9') {
1287 s0 = s;
1288 nf += nz;
1289 nz = 0;
1290 goto have_dig;
1291 }
1292 goto dig_done;
1293 }
1294 for(; c >= '0' && c <= '9'; c = *++s) {
1295 have_dig:
1296 nz++;
1297 if (c -= '0') {
1298 nf += nz;
1299 for(i = 1; i < nz; i++)
1300 if (nd++ < 9)
1301 y *= 10;
1302 else if (nd <= DBL_DIG + 1)
1303 z *= 10;
1304 if (nd++ < 9)
1305 y = 10*y + c;
1306 else if (nd <= DBL_DIG + 1)
1307 z = 10*z + c;
1308 nz = 0;
1309 }
1310 }
1311 }
1312 dig_done:
1313 e = 0;
1314 if (c == 'e' || c == 'E') {
1315 if (!nd && !nz && !nz0) {
1316 s = s00;
1317 goto ret;
1318 }
1319 s00 = s;
1320 esign = 0;
1321 switch(c = *++s) {
1322 case '-':
1323 esign = 1;
1324 case '+':
1325 c = *++s;
1326 }
1327 if (c >= '0' && c <= '9') {
1328 while(c == '0')
1329 c = *++s;
1330 if (c > '0' && c <= '9') {
1331 L = c - '0';
1332 s1 = s;
1333 while((c = *++s) >= '0' && c <= '9')
1334 L = 10*L + c - '0';
1335 if (s - s1 > 8 || L > 19999)
1336 /* Avoid confusion from exponents
1337 * so large that e might overflow.
1338 */
1339 e = 19999; /* safe for 16 bit ints */
1340 else
1341 e = (int)L;
1342 if (esign)
1343 e = -e;
1344 }
1345 else
1346 e = 0;
1347 }
1348 else
1349 s = s00;
1350 }
1351 if (!nd) {
1352 if (!nz && !nz0)
1353 s = s00;
1354 goto ret;
1355 }
1356 e1 = e -= nf;
1357
1358 /* Now we have nd0 digits, starting at s0, followed by a
1359 * decimal point, followed by nd-nd0 digits. The number we're
1360 * after is the integer represented by those digits times
1361 * 10**e */
1362
1363 if (!nd0)
1364 nd0 = nd;
1365 k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
1366 value(rv) = y;
1367 if (k > 9)
1368 value(rv) = tens[k - 9] * value(rv) + z;
1369 bd0 = 0;
1370 if (nd <= DBL_DIG
1371#ifndef RND_PRODQUOT
1372 && FLT_ROUNDS == 1
1373#endif
1374 ) {
1375 if (!e)
1376 goto ret;
1377 if (e > 0) {
1378 if (e <= Ten_pmax) {
1379#ifdef VAX
1380 goto vax_ovfl_check;
1381#else
1382 /* value(rv) = */ rounded_product(value(rv),
1383 tens[e]);
1384 goto ret;
1385#endif
1386 }
1387 i = DBL_DIG - nd;
1388 if (e <= Ten_pmax + i) {
1389 /* A fancier test would sometimes let us do
1390 * this for larger i values.
1391 */
1392 e -= i;
1393 value(rv) *= tens[i];
1394#ifdef VAX
1395 /* VAX exponent range is so narrow we must
1396 * worry about overflow here...
1397 */
1398 vax_ovfl_check:
1399 word0(rv) -= P*Exp_msk1;
1400 /* value(rv) = */ rounded_product(value(rv),
1401 tens[e]);
1402 if ((word0(rv) & Exp_mask)
1403 > Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
1404 goto ovfl;
1405 word0(rv) += P*Exp_msk1;
1406#else
1407 /* value(rv) = */ rounded_product(value(rv),
1408 tens[e]);
1409#endif
1410 goto ret;
1411 }
1412 }
1413#ifndef Inaccurate_Divide
1414 else if (e >= -Ten_pmax) {
1415 /* value(rv) = */ rounded_quotient(value(rv),
1416 tens[-e]);
1417 goto ret;
1418 }
1419#endif
1420 }
1421 e1 += nd - k;
1422
1423 /* Get starting approximation = rv * 10**e1 */
1424
1425 if (e1 > 0) {
1426 if (i = e1 & 15)
1427 value(rv) *= tens[i];
1428 if (e1 &= ~15) {
1429 if (e1 > DBL_MAX_10_EXP) {
1430 ovfl:
1431 errno = ERANGE;
1432#ifdef __STDC__
1433 value(rv) = HUGE_VAL;
1434#else
1435 /* Can't trust HUGE_VAL */
1436#ifdef IEEE_Arith
1437 word0(rv) = Exp_mask;
1438 word1(rv) = 0;
1439#else
1440 word0(rv) = Big0;
1441 word1(rv) = Big1;
1442#endif
1443#endif
1444 if (bd0)
1445 goto retfree;
1446 goto ret;
1447 }
1448 if (e1 >>= 4) {
1449 for(j = 0; e1 > 1; j++, e1 >>= 1)
1450 if (e1 & 1)
1451 value(rv) *= bigtens[j];
1452 /* The last multiplication could overflow. */
1453 word0(rv) -= P*Exp_msk1;
1454 value(rv) *= bigtens[j];
1455 if ((z = word0(rv) & Exp_mask)
1456 > Exp_msk1*(DBL_MAX_EXP+Bias-P))
1457 goto ovfl;
1458 if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) {
1459 /* set to largest number */
1460 /* (Can't trust DBL_MAX) */
1461 word0(rv) = Big0;
1462 word1(rv) = Big1;
1463 }
1464 else
1465 word0(rv) += P*Exp_msk1;
1466 }
1467
1468 }
1469 }
1470 else if (e1 < 0) {
1471 e1 = -e1;
1472 if (i = e1 & 15)
1473 value(rv) /= tens[i];
1474 if (e1 &= ~15) {
1475 e1 >>= 4;
1476 if (e1 >= 1 << n_bigtens)
1477 goto undfl;
1478 for(j = 0; e1 > 1; j++, e1 >>= 1)
1479 if (e1 & 1)
1480 value(rv) *= tinytens[j];
1481 /* The last multiplication could underflow. */
1482 value(rv0) = value(rv);
1483 value(rv) *= tinytens[j];
1484 if (!value(rv)) {
1485 value(rv) = 2.*value(rv0);
1486 value(rv) *= tinytens[j];
1487 if (!value(rv)) {
1488 undfl:
1489 value(rv) = 0.;
1490 errno = ERANGE;
1491 if (bd0)
1492 goto retfree;
1493 goto ret;
1494 }
1495 word0(rv) = Tiny0;
1496 word1(rv) = Tiny1;
1497 /* The refinement below will clean
1498 * this approximation up.
1499 */
1500 }
1501 }
1502 }
1503
1504 /* Now the hard part -- adjusting rv to the correct value.*/
1505
1506 /* Put digits into bd: true value = bd * 10^e */
1507
1508 bd0 = s2b(s0, nd0, nd, y);
1509
1510 for(;;) {
1511 bd = Balloc(bd0->k);
1512 Bcopy(bd, bd0);
1513 bb = d2b(value(rv), &bbe, &bbbits); /* rv = bb * 2^bbe */
1514 bs = i2b(1);
1515
1516 if (e >= 0) {
1517 bb2 = bb5 = 0;
1518 bd2 = bd5 = e;
1519 }
1520 else {
1521 bb2 = bb5 = -e;
1522 bd2 = bd5 = 0;
1523 }
1524 if (bbe >= 0)
1525 bb2 += bbe;
1526 else
1527 bd2 -= bbe;
1528 bs2 = bb2;
1529#ifdef Sudden_Underflow
1530#ifdef IBM
1531 j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3);
1532#else
1533 j = P + 1 - bbbits;
1534#endif
1535#else
1536 i = bbe + bbbits - 1; /* logb(rv) */
1537 if (i < Emin) /* denormal */
1538 j = bbe + (P-Emin);
1539 else
1540 j = P + 1 - bbbits;
1541#endif
1542 bb2 += j;
1543 bd2 += j;
1544 i = bb2 < bd2 ? bb2 : bd2;
1545 if (i > bs2)
1546 i = bs2;
1547 if (i > 0) {
1548 bb2 -= i;
1549 bd2 -= i;
1550 bs2 -= i;
1551 }
1552 if (bb5 > 0) {
1553 bs = pow5mult(bs, bb5);
1554 bb1 = mult(bs, bb);
1555 Bfree(bb);
1556 bb = bb1;
1557 }
1558 if (bb2 > 0)
1559 bb = lshift(bb, bb2);
1560 if (bd5 > 0)
1561 bd = pow5mult(bd, bd5);
1562 if (bd2 > 0)
1563 bd = lshift(bd, bd2);
1564 if (bs2 > 0)
1565 bs = lshift(bs, bs2);
1566 delta = diff(bb, bd);
1567 dsign = delta->sign;
1568 delta->sign = 0;
1569 i = cmp(delta, bs);
1570 if (i < 0) {
1571 /* Error is less than half an ulp -- check for
1572 * special case of mantissa a power of two.
1573 */
1574 if (dsign || word1(rv) || word0(rv) & Bndry_mask)
1575 break;
1576 delta = lshift(delta,Log2P);
1577 if (cmp(delta, bs) > 0)
1578 goto drop_down;
1579 break;
1580 }
1581 if (i == 0) {
1582 /* exactly half-way between */
1583 if (dsign) {
1584 if ((word0(rv) & Bndry_mask1) == Bndry_mask1
1585 && word1(rv) == 0xffffffff) {
1586 /*boundary case -- increment exponent*/
1587 word0(rv) = (word0(rv) & Exp_mask)
1588 + Exp_msk1
1589#ifdef IBM
1590 | Exp_msk1 >> 4
1591#endif
1592 ;
1593 word1(rv) = 0;
1594 break;
1595 }
1596 }
1597 else if (!(word0(rv) & Bndry_mask) && !word1(rv)) {
1598 drop_down:
1599 /* boundary case -- decrement exponent */
1600#ifdef Sudden_Underflow
1601 L = word0(rv) & Exp_mask;
1602#ifdef IBM
1603 if (L < Exp_msk1)
1604#else
1605 if (L <= Exp_msk1)
1606#endif
1607 goto undfl;
1608 L -= Exp_msk1;
1609#else
1610 L = (word0(rv) & Exp_mask) - Exp_msk1;
1611#endif
1612 word0(rv) = L | Bndry_mask1;
1613 word1(rv) = 0xffffffff;
1614#ifdef IBM
1615 goto cont;
1616#else
1617 break;
1618#endif
1619 }
1620#ifndef ROUND_BIASED
1621 if (!(word1(rv) & LSB))
1622 break;
1623#endif
1624 if (dsign)
1625 value(rv) += ulp(value(rv));
1626#ifndef ROUND_BIASED
1627 else {
1628 value(rv) -= ulp(value(rv));
1629#ifndef Sudden_Underflow
1630 if (!value(rv))
1631 goto undfl;
1632#endif
1633 }
1634#endif
1635 break;
1636 }
1637 if ((aadj = ratio(delta, bs)) <= 2.) {
1638 if (dsign)
1639 aadj = aadj1 = 1.;
1640 else if (word1(rv) || word0(rv) & Bndry_mask) {
1641#ifndef Sudden_Underflow
1642 if (word1(rv) == Tiny1 && !word0(rv))
1643 goto undfl;
1644#endif
1645 aadj = 1.;
1646 aadj1 = -1.;
1647 }
1648 else {
1649 /* special case -- power of FLT_RADIX to be */
1650 /* rounded down... */
1651
1652 if (aadj < 2./FLT_RADIX)
1653 aadj = 1./FLT_RADIX;
1654 else
1655 aadj *= 0.5;
1656 aadj1 = -aadj;
1657 }
1658 }
1659 else {
1660 aadj *= 0.5;
1661 aadj1 = dsign ? aadj : -aadj;
1662#ifdef Check_FLT_ROUNDS
1663 switch(FLT_ROUNDS) {
1664 case 2: /* towards +infinity */
1665 aadj1 -= 0.5;
1666 break;
1667 case 0: /* towards 0 */
1668 case 3: /* towards -infinity */
1669 aadj1 += 0.5;
1670 }
1671#else
1672 if (FLT_ROUNDS == 0)
1673 aadj1 += 0.5;
1674#endif
1675 }
1676 y = word0(rv) & Exp_mask;
1677
1678 /* Check for overflow */
1679
1680 if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
1681 value(rv0) = value(rv);
1682 word0(rv) -= P*Exp_msk1;
1683 adj = aadj1 * ulp(value(rv));
1684 value(rv) += adj;
1685 if ((word0(rv) & Exp_mask) >=
1686 Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
1687 if (word0(rv0) == Big0 && word1(rv0) == Big1)
1688 goto ovfl;
1689 word0(rv) = Big0;
1690 word1(rv) = Big1;
1691 goto cont;
1692 }
1693 else
1694 word0(rv) += P*Exp_msk1;
1695 }
1696 else {
1697#ifdef Sudden_Underflow
1698 if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
1699 value(rv0) = value(rv);
1700 word0(rv) += P*Exp_msk1;
1701 adj = aadj1 * ulp(value(rv));
1702 value(rv) += adj;
1703#ifdef IBM
1704 if ((word0(rv) & Exp_mask) < P*Exp_msk1)
1705#else
1706 if ((word0(rv) & Exp_mask) <= P*Exp_msk1)
1707#endif
1708 {
1709 if (word0(rv0) == Tiny0
1710 && word1(rv0) == Tiny1)
1711 goto undfl;
1712 word0(rv) = Tiny0;
1713 word1(rv) = Tiny1;
1714 goto cont;
1715 }
1716 else
1717 word0(rv) -= P*Exp_msk1;
1718 }
1719 else {
1720 adj = aadj1 * ulp(value(rv));
1721 value(rv) += adj;
1722 }
1723#else
1724 /* Compute adj so that the IEEE rounding rules will
1725 * correctly round rv + adj in some half-way cases.
1726 * If rv * ulp(rv) is denormalized (i.e.,
1727 * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
1728 * trouble from bits lost to denormalization;
1729 * example: 1.2e-307 .
1730 */
1731 if (y <= (P-1)*Exp_msk1 && aadj >= 1.) {
1732 aadj1 = (double)(int)(aadj + 0.5);
1733 if (!dsign)
1734 aadj1 = -aadj1;
1735 }
1736 adj = aadj1 * ulp(value(rv));
1737 value(rv) += adj;
1738#endif
1739 }
1740 z = word0(rv) & Exp_mask;
1741 if (y == z) {
1742 /* Can we stop now? */
1743 L = aadj;
1744 aadj -= L;
1745 /* The tolerances below are conservative. */
1746 if (dsign || word1(rv) || word0(rv) & Bndry_mask) {
1747 if (aadj < .4999999 || aadj > .5000001)
1748 break;
1749 }
1750 else if (aadj < .4999999/FLT_RADIX)
1751 break;
1752 }
1753 cont:
1754 Bfree(bb);
1755 Bfree(bd);
1756 Bfree(bs);
1757 Bfree(delta);
1758 }
1759 retfree:
1760 Bfree(bb);
1761 Bfree(bd);
1762 Bfree(bs);
1763 Bfree(bd0);
1764 Bfree(delta);
1765 ret:
1766 if (se)
1767 *se = (char *)s;
1768 return sign ? -value(rv) : value(rv);
1769 }
1770
1771 static int
1772quorem
1773#ifdef KR_headers
1774 (b, S) Bigint *b, *S;
1775#else
1776 (Bigint *b, Bigint *S)
1777#endif
1778{
1779 int n;
1780 Long borrow, y;
1781 ULong carry, q, ys;
1782 ULong *bx, *bxe, *sx, *sxe;
1783#ifdef Pack_32
1784 Long z;
1785 ULong si, zs;
1786#endif
1787
1788 n = S->wds;
1789#ifdef DEBUG
1790 /*debug*/ if (b->wds > n)
1791 /*debug*/ Bug("oversize b in quorem");
1792#endif
1793 if (b->wds < n)
1794 return 0;
1795 sx = S->x;
1796 sxe = sx + --n;
1797 bx = b->x;
1798 bxe = bx + n;
1799 q = *bxe / (*sxe + 1); /* ensure q <= true quotient */
1800#ifdef DEBUG
1801 /*debug*/ if (q > 9)
1802 /*debug*/ Bug("oversized quotient in quorem");
1803#endif
1804 if (q) {
1805 borrow = 0;
1806 carry = 0;
1807 do {
1808#ifdef Pack_32
1809 si = *sx++;
1810 ys = (si & 0xffff) * q + carry;
1811 zs = (si >> 16) * q + (ys >> 16);
1812 carry = zs >> 16;
1813 y = (*bx & 0xffff) - (ys & 0xffff) + borrow;
1814 borrow = y >> 16;
1815 Sign_Extend(borrow, y);
1816 z = (*bx >> 16) - (zs & 0xffff) + borrow;
1817 borrow = z >> 16;
1818 Sign_Extend(borrow, z);
1819 Storeinc(bx, z, y);
1820#else
1821 ys = *sx++ * q + carry;
1822 carry = ys >> 16;
1823 y = *bx - (ys & 0xffff) + borrow;
1824 borrow = y >> 16;
1825 Sign_Extend(borrow, y);
1826 *bx++ = y & 0xffff;
1827#endif
1828 }
1829 while(sx <= sxe);
1830 if (!*bxe) {
1831 bx = b->x;
1832 while(--bxe > bx && !*bxe)
1833 --n;
1834 b->wds = n;
1835 }
1836 }
1837 if (cmp(b, S) >= 0) {
1838 q++;
1839 borrow = 0;
1840 carry = 0;
1841 bx = b->x;
1842 sx = S->x;
1843 do {
1844#ifdef Pack_32
1845 si = *sx++;
1846 ys = (si & 0xffff) + carry;
1847 zs = (si >> 16) + (ys >> 16);
1848 carry = zs >> 16;
1849 y = (*bx & 0xffff) - (ys & 0xffff) + borrow;
1850 borrow = y >> 16;
1851 Sign_Extend(borrow, y);
1852 z = (*bx >> 16) - (zs & 0xffff) + borrow;
1853 borrow = z >> 16;
1854 Sign_Extend(borrow, z);
1855 Storeinc(bx, z, y);
1856#else
1857 ys = *sx++ + carry;
1858 carry = ys >> 16;
1859 y = *bx - (ys & 0xffff) + borrow;
1860 borrow = y >> 16;
1861 Sign_Extend(borrow, y);
1862 *bx++ = y & 0xffff;
1863#endif
1864 }
1865 while(sx <= sxe);
1866 bx = b->x;
1867 bxe = bx + n;
1868 if (!*bxe) {
1869 while(--bxe > bx && !*bxe)
1870 --n;
1871 b->wds = n;
1872 }
1873 }
1874 return q;
1875 }
1876
1877/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
1878 *
1879 * Inspired by "How to Print Floating-Point Numbers Accurately" by
1880 * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101].
1881 *
1882 * Modifications:
1883 * 1. Rather than iterating, we use a simple numeric overestimate
1884 * to determine k = floor(log10(d)). We scale relevant
1885 * quantities using O(log2(k)) rather than O(k) multiplications.
1886 * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
1887 * try to generate digits strictly left to right. Instead, we
1888 * compute with fewer bits and propagate the carry if necessary
1889 * when rounding the final digit up. This is often faster.
1890 * 3. Under the assumption that input will be rounded nearest,
1891 * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
1892 * That is, we allow equality in stopping tests when the
1893 * round-nearest rule will give the same floating-point value
1894 * as would satisfaction of the stopping test with strict
1895 * inequality.
1896 * 4. We remove common factors of powers of 2 from relevant
1897 * quantities.
1898 * 5. When converting floating-point integers less than 1e16,
1899 * we use floating-point arithmetic rather than resorting
1900 * to multiple-precision integers.
1901 * 6. When asked to produce fewer than 15 digits, we first try
1902 * to get by with floating-point arithmetic; we resort to
1903 * multiple-precision integer arithmetic only if we cannot
1904 * guarantee that the floating-point calculation has given
1905 * the correctly rounded result. For k requested digits and
1906 * "uniformly" distributed input, the probability is
1907 * something like 10^(k-15) that we must resort to the Long
1908 * calculation.
1909 */
1910
1911 char *
1912__dtoa
1913#ifdef KR_headers
1914 (_d, mode, ndigits, decpt, sign, rve)
1915 double _d; int mode, ndigits, *decpt, *sign; char **rve;
1916#else
1917 (double _d, int mode, int ndigits, int *decpt, int *sign, char **rve)
1918#endif
1919{
1920 /* Arguments ndigits, decpt, sign are similar to those
1921 of ecvt and fcvt; trailing zeros are suppressed from
1922 the returned string. If not null, *rve is set to point
1923 to the end of the return value. If d is +-Infinity or NaN,
1924 then *decpt is set to 9999.
1925
1926 mode:
1927 0 ==> shortest string that yields d when read in
1928 and rounded to nearest.
1929 1 ==> like 0, but with Steele & White stopping rule;
1930 e.g. with IEEE P754 arithmetic , mode 0 gives
1931 1e23 whereas mode 1 gives 9.999999999999999e22.
1932 2 ==> max(1,ndigits) significant digits. This gives a
1933 return value similar to that of ecvt, except
1934 that trailing zeros are suppressed.
1935 3 ==> through ndigits past the decimal point. This
1936 gives a return value similar to that from fcvt,
1937 except that trailing zeros are suppressed, and
1938 ndigits can be negative.
1939 4-9 should give the same return values as 2-3, i.e.,
1940 4 <= mode <= 9 ==> same return as mode
1941 2 + (mode & 1). These modes are mainly for
1942 debugging; often they run slower but sometimes
1943 faster than modes 2-3.
1944 4,5,8,9 ==> left-to-right digit generation.
1945 6-9 ==> don't try fast floating-point estimate
1946 (if applicable).
1947
1948 Values of mode other than 0-9 are treated as mode 0.
1949
1950 Sufficient space is allocated to the return value
1951 to hold the suppressed trailing zeros.
1952 */
1953
1954 int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1,
1955 j, j1, k, k0, k_check, leftright, m2, m5, s2, s5,
1956 spec_case, try_quick;
1957 Long L;
1958#ifndef Sudden_Underflow
1959 int denorm;
1960 ULong x;
1961#endif
1962 Bigint *b, *b1, *delta, *mlo, *mhi, *S;
1963 double ds;
1964 char *s, *s0;
1965 static Bigint *result;
1966 static int result_k;
1967 _double d, d2, eps;
1968
1969 value(d) = _d;
1970 if (result) {
1971 result->k = result_k;
1972 result->maxwds = 1 << result_k;
1973 Bfree(result);
1974 result = 0;
1975 }
1976
1977 if (word0(d) & Sign_bit) {
1978 /* set sign for everything, including 0's and NaNs */
1979 *sign = 1;
1980 word0(d) &= ~Sign_bit; /* clear sign bit */
1981 }
1982 else
1983 *sign = 0;
1984
1985#if defined(IEEE_Arith) + defined(VAX)
1986#ifdef IEEE_Arith
1987 if ((word0(d) & Exp_mask) == Exp_mask)
1988#else
1989 if (word0(d) == 0x8000)
1990#endif
1991 {
1992 /* Infinity or NaN */
1993 *decpt = 9999;
1994 s =
1995#ifdef IEEE_Arith
1996 !word1(d) && !(word0(d) & 0xfffff) ? "Infinity" :
1997#endif
1998 "NaN";
1999 if (rve)
2000 *rve =
2001#ifdef IEEE_Arith
2002 s[3] ? s + 8 :
2003#endif
2004 s + 3;
2005 return s;
2006 }
2007#endif
2008#ifdef IBM
2009 value(d) += 0; /* normalize */
2010#endif
2011 if (!value(d)) {
2012 *decpt = 1;
2013 s = "0";
2014 if (rve)
2015 *rve = s + 1;
2016 return s;
2017 }
2018
2019 b = d2b(value(d), &be, &bbits);
2020#ifdef Sudden_Underflow
2021 i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
2022#else
2023 if (i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) {
2024#endif
2025 value(d2) = value(d);
2026 word0(d2) &= Frac_mask1;
2027 word0(d2) |= Exp_11;
2028#ifdef IBM
2029 if (j = 11 - hi0bits(word0(d2) & Frac_mask))
2030 value(d2) /= 1 << j;
2031#endif
2032
2033 /* log(x) ~=~ log(1.5) + (x-1.5)/1.5
2034 * log10(x) = log(x) / log(10)
2035 * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
2036 * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)
2037 *
2038 * This suggests computing an approximation k to log10(d) by
2039 *
2040 * k = (i - Bias)*0.301029995663981
2041 * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
2042 *
2043 * We want k to be too large rather than too small.
2044 * The error in the first-order Taylor series approximation
2045 * is in our favor, so we just round up the constant enough
2046 * to compensate for any error in the multiplication of
2047 * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
2048 * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
2049 * adding 1e-13 to the constant term more than suffices.
2050 * Hence we adjust the constant term to 0.1760912590558.
2051 * (We could get a more accurate k by invoking log10,
2052 * but this is probably not worthwhile.)
2053 */
2054
2055 i -= Bias;
2056#ifdef IBM
2057 i <<= 2;
2058 i += j;
2059#endif
2060#ifndef Sudden_Underflow
2061 denorm = 0;
2062 }
2063 else {
2064 /* d is denormalized */
2065
2066 i = bbits + be + (Bias + (P-1) - 1);
2067 x = i > 32 ? word0(d) << 64 - i | word1(d) >> i - 32
2068 : word1(d) << 32 - i;
2069 value(d2) = x;
2070 word0(d2) -= 31*Exp_msk1; /* adjust exponent */
2071 i -= (Bias + (P-1) - 1) + 1;
2072 denorm = 1;
2073 }
2074#endif
2075 ds = (value(d2)-1.5)*0.289529654602168 + 0.1760912590558 +
2076 i*0.301029995663981;
2077 k = (int)ds;
2078 if (ds < 0. && ds != k)
2079 k--; /* want k = floor(ds) */
2080 k_check = 1;
2081 if (k >= 0 && k <= Ten_pmax) {
2082 if (value(d) < tens[k])
2083 k--;
2084 k_check = 0;
2085 }
2086 j = bbits - i - 1;
2087 if (j >= 0) {
2088 b2 = 0;
2089 s2 = j;
2090 }
2091 else {
2092 b2 = -j;
2093 s2 = 0;
2094 }
2095 if (k >= 0) {
2096 b5 = 0;
2097 s5 = k;
2098 s2 += k;
2099 }
2100 else {
2101 b2 -= k;
2102 b5 = -k;
2103 s5 = 0;
2104 }
2105 if (mode < 0 || mode > 9)
2106 mode = 0;
2107 try_quick = 1;
2108 if (mode > 5) {
2109 mode -= 4;
2110 try_quick = 0;
2111 }
2112 leftright = 1;
2113 switch(mode) {
2114 case 0:
2115 case 1:
2116 ilim = ilim1 = -1;
2117 i = 18;
2118 ndigits = 0;
2119 break;
2120 case 2:
2121 leftright = 0;
2122 /* no break */
2123 case 4:
2124 if (ndigits <= 0)
2125 ndigits = 1;
2126 ilim = ilim1 = i = ndigits;
2127 break;
2128 case 3:
2129 leftright = 0;
2130 /* no break */
2131 case 5:
2132 i = ndigits + k + 1;
2133 ilim = i;
2134 ilim1 = i - 1;
2135 if (i <= 0)
2136 i = 1;
2137 }
2138 j = sizeof(ULong);
2139 for(result_k = 0; sizeof(Bigint) - sizeof(ULong) + j <= i;
2140 j <<= 1) result_k++;
2141 result = Balloc(result_k);
2142 s = s0 = (char *)result;
2143
2144 if (ilim >= 0 && ilim <= Quick_max && try_quick) {
2145
2146 /* Try to get by with floating-point arithmetic. */
2147
2148 i = 0;
2149 value(d2) = value(d);
2150 k0 = k;
2151 ilim0 = ilim;
2152 ieps = 2; /* conservative */
2153 if (k > 0) {
2154 ds = tens[k&0xf];
2155 j = k >> 4;
2156 if (j & Bletch) {
2157 /* prevent overflows */
2158 j &= Bletch - 1;
2159 value(d) /= bigtens[n_bigtens-1];
2160 ieps++;
2161 }
2162 for(; j; j >>= 1, i++)
2163 if (j & 1) {
2164 ieps++;
2165 ds *= bigtens[i];
2166 }
2167 value(d) /= ds;
2168 }
2169 else if (j1 = -k) {
2170 value(d) *= tens[j1 & 0xf];
2171 for(j = j1 >> 4; j; j >>= 1, i++)
2172 if (j & 1) {
2173 ieps++;
2174 value(d) *= bigtens[i];
2175 }
2176 }
2177 if (k_check && value(d) < 1. && ilim > 0) {
2178 if (ilim1 <= 0)
2179 goto fast_failed;
2180 ilim = ilim1;
2181 k--;
2182 value(d) *= 10.;
2183 ieps++;
2184 }
2185 value(eps) = ieps*value(d) + 7.;
2186 word0(eps) -= (P-1)*Exp_msk1;
2187 if (ilim == 0) {
2188 S = mhi = 0;
2189 value(d) -= 5.;
2190 if (value(d) > value(eps))
2191 goto one_digit;
2192 if (value(d) < -value(eps))
2193 goto no_digits;
2194 goto fast_failed;
2195 }
2196#ifndef No_leftright
2197 if (leftright) {
2198 /* Use Steele & White method of only
2199 * generating digits needed.
2200 */
2201 value(eps) = 0.5/tens[ilim-1] - value(eps);
2202 for(i = 0;;) {
2203 L = value(d);
2204 value(d) -= L;
2205 *s++ = '0' + (int)L;
2206 if (value(d) < value(eps))
2207 goto ret1;
2208 if (1. - value(d) < value(eps))
2209 goto bump_up;
2210 if (++i >= ilim)
2211 break;
2212 value(eps) *= 10.;
2213 value(d) *= 10.;
2214 }
2215 }
2216 else {
2217#endif
2218 /* Generate ilim digits, then fix them up. */
2219 value(eps) *= tens[ilim-1];
2220 for(i = 1;; i++, value(d) *= 10.) {
2221 L = value(d);
2222 value(d) -= L;
2223 *s++ = '0' + (int)L;
2224 if (i == ilim) {
2225 if (value(d) > 0.5 + value(eps))
2226 goto bump_up;
2227 else if (value(d) < 0.5 - value(eps)) {
2228 while(*--s == '0');
2229 s++;
2230 goto ret1;
2231 }
2232 break;
2233 }
2234 }
2235#ifndef No_leftright
2236 }
2237#endif
2238 fast_failed:
2239 s = s0;
2240 value(d) = value(d2);
2241 k = k0;
2242 ilim = ilim0;
2243 }
2244
2245 /* Do we have a "small" integer? */
2246
2247 if (be >= 0 && k <= Int_max) {
2248 /* Yes. */
2249 ds = tens[k];
2250 if (ndigits < 0 && ilim <= 0) {
2251 S = mhi = 0;
2252 if (ilim < 0 || value(d) <= 5*ds)
2253 goto no_digits;
2254 goto one_digit;
2255 }
2256 for(i = 1;; i++) {
2257 L = value(d) / ds;
2258 value(d) -= L*ds;
2259#ifdef Check_FLT_ROUNDS
2260 /* If FLT_ROUNDS == 2, L will usually be high by 1 */
2261 if (value(d) < 0) {
2262 L--;
2263 value(d) += ds;
2264 }
2265#endif
2266 *s++ = '0' + (int)L;
2267 if (i == ilim) {
2268 value(d) += value(d);
2269 if (value(d) > ds || value(d) == ds && L & 1) {
2270 bump_up:
2271 while(*--s == '9')
2272 if (s == s0) {
2273 k++;
2274 *s = '0';
2275 break;
2276 }
2277 ++*s++;
2278 }
2279 break;
2280 }
2281 if (!(value(d) *= 10.))
2282 break;
2283 }
2284 goto ret1;
2285 }
2286
2287 m2 = b2;
2288 m5 = b5;
2289 mhi = mlo = 0;
2290 if (leftright) {
2291 if (mode < 2) {
2292 i =
2293#ifndef Sudden_Underflow
2294 denorm ? be + (Bias + (P-1) - 1 + 1) :
2295#endif
2296#ifdef IBM
2297 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3);
2298#else
2299 1 + P - bbits;
2300#endif
2301 }
2302 else {
2303 j = ilim - 1;
2304 if (m5 >= j)
2305 m5 -= j;
2306 else {
2307 s5 += j -= m5;
2308 b5 += j;
2309 m5 = 0;
2310 }
2311 if ((i = ilim) < 0) {
2312 m2 -= i;
2313 i = 0;
2314 }
2315 }
2316 b2 += i;
2317 s2 += i;
2318 mhi = i2b(1);
2319 }
2320 if (m2 > 0 && s2 > 0) {
2321 i = m2 < s2 ? m2 : s2;
2322 b2 -= i;
2323 m2 -= i;
2324 s2 -= i;
2325 }
2326 if (b5 > 0) {
2327 if (leftright) {
2328 if (m5 > 0) {
2329 mhi = pow5mult(mhi, m5);
2330 b1 = mult(mhi, b);
2331 Bfree(b);
2332 b = b1;
2333 }
2334 if (j = b5 - m5)
2335 b = pow5mult(b, j);
2336 }
2337 else
2338 b = pow5mult(b, b5);
2339 }
2340 S = i2b(1);
2341 if (s5 > 0)
2342 S = pow5mult(S, s5);
2343
2344 /* Check for special case that d is a normalized power of 2. */
2345
2346 if (mode < 2) {
2347 if (!word1(d) && !(word0(d) & Bndry_mask)
2348#ifndef Sudden_Underflow
2349 && word0(d) & Exp_mask
2350#endif
2351 ) {
2352 /* The special case */
2353 b2 += Log2P;
2354 s2 += Log2P;
2355 spec_case = 1;
2356 }
2357 else
2358 spec_case = 0;
2359 }
2360
2361 /* Arrange for convenient computation of quotients:
2362 * shift left if necessary so divisor has 4 leading 0 bits.
2363 *
2364 * Perhaps we should just compute leading 28 bits of S once
2365 * and for all and pass them and a shift to quorem, so it
2366 * can do shifts and ors to compute the numerator for q.
2367 */
2368#ifdef Pack_32
2369 if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f)
2370 i = 32 - i;
2371#else
2372 if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf)
2373 i = 16 - i;
2374#endif
2375 if (i > 4) {
2376 i -= 4;
2377 b2 += i;
2378 m2 += i;
2379 s2 += i;
2380 }
2381 else if (i < 4) {
2382 i += 28;
2383 b2 += i;
2384 m2 += i;
2385 s2 += i;
2386 }
2387 if (b2 > 0)
2388 b = lshift(b, b2);
2389 if (s2 > 0)
2390 S = lshift(S, s2);
2391 if (k_check) {
2392 if (cmp(b,S) < 0) {
2393 k--;
2394 b = multadd(b, 10, 0); /* we botched the k estimate */
2395 if (leftright)
2396 mhi = multadd(mhi, 10, 0);
2397 ilim = ilim1;
2398 }
2399 }
2400 if (ilim <= 0 && mode > 2) {
2401 if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) {
2402 /* no digits, fcvt style */
2403 no_digits:
2404 k = -1 - ndigits;
2405 goto ret;
2406 }
2407 one_digit:
2408 *s++ = '1';
2409 k++;
2410 goto ret;
2411 }
2412 if (leftright) {
2413 if (m2 > 0)
2414 mhi = lshift(mhi, m2);
2415
2416 /* Compute mlo -- check for special case
2417 * that d is a normalized power of 2.
2418 */
2419
2420 mlo = mhi;
2421 if (spec_case) {
2422 mhi = Balloc(mhi->k);
2423 Bcopy(mhi, mlo);
2424 mhi = lshift(mhi, Log2P);
2425 }
2426
2427 for(i = 1;;i++) {
2428 dig = quorem(b,S) + '0';
2429 /* Do we yet have the shortest decimal string
2430 * that will round to d?
2431 */
2432 j = cmp(b, mlo);
2433 delta = diff(S, mhi);
2434 j1 = delta->sign ? 1 : cmp(b, delta);
2435 Bfree(delta);
2436#ifndef ROUND_BIASED
2437 if (j1 == 0 && !mode && !(word1(d) & 1)) {
2438 if (dig == '9')
2439 goto round_9_up;
2440 if (j > 0)
2441 dig++;
2442 *s++ = dig;
2443 goto ret;
2444 }
2445#endif
2446 if (j < 0 || j == 0 && !mode
2447#ifndef ROUND_BIASED
2448 && !(word1(d) & 1)
2449#endif
2450 ) {
2451 if (j1 > 0) {
2452 b = lshift(b, 1);
2453 j1 = cmp(b, S);
2454 if ((j1 > 0 || j1 == 0 && dig & 1)
2455 && dig++ == '9')
2456 goto round_9_up;
2457 }
2458 *s++ = dig;
2459 goto ret;
2460 }
2461 if (j1 > 0) {
2462 if (dig == '9') { /* possible if i == 1 */
2463 round_9_up:
2464 *s++ = '9';
2465 goto roundoff;
2466 }
2467 *s++ = dig + 1;
2468 goto ret;
2469 }
2470 *s++ = dig;
2471 if (i == ilim)
2472 break;
2473 b = multadd(b, 10, 0);
2474 if (mlo == mhi)
2475 mlo = mhi = multadd(mhi, 10, 0);
2476 else {
2477 mlo = multadd(mlo, 10, 0);
2478 mhi = multadd(mhi, 10, 0);
2479 }
2480 }
2481 }
2482 else
2483 for(i = 1;; i++) {
2484 *s++ = dig = quorem(b,S) + '0';
2485 if (i >= ilim)
2486 break;
2487 b = multadd(b, 10, 0);
2488 }
2489
2490 /* Round off last digit */
2491
2492 b = lshift(b, 1);
2493 j = cmp(b, S);
2494 if (j > 0 || j == 0 && dig & 1) {
2495 roundoff:
2496 while(*--s == '9')
2497 if (s == s0) {
2498 k++;
2499 *s++ = '1';
2500 goto ret;
2501 }
2502 ++*s++;
2503 }
2504 else {
2505 while(*--s == '0');
2506 s++;
2507 }
2508 ret:
2509 Bfree(S);
2510 if (mhi) {
2511 if (mlo && mlo != mhi)
2512 Bfree(mlo);
2513 Bfree(mhi);
2514 }
2515 ret1:
2516 Bfree(b);
2517 if (s == s0) { /* don't return empty string */
2518 *s++ = '0';
2519 k = 0;
2520 }
2521 *s = 0;
2522 *decpt = k + 1;
2523 if (rve)
2524 *rve = s;
2525 return s0;
2526 }
2527#ifdef __cplusplus
2528}
2529#endif
diff --git a/src/lib/libc/stdlib/strtol.3 b/src/lib/libc/stdlib/strtol.3
new file mode 100644
index 0000000000..b7d2cd1225
--- /dev/null
+++ b/src/lib/libc/stdlib/strtol.3
@@ -0,0 +1,168 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: strtol.3,v 1.3 1996/08/19 08:33:51 tholo Exp $
37.\"
38.Dd June 25, 1992
39.Dt STRTOL 3
40.Os
41.Sh NAME
42.Nm strtol, strtoq
43.Nd convert string value to a long or quad_t integer
44.Sh SYNOPSIS
45.Fd #include <stdlib.h>
46.Fd #include <limits.h>
47.Ft long
48.Fn strtol "const char *nptr" "char **endptr" "int base"
49
50.Fd #include <sys/types.h>
51.Fd #include <stdlib.h>
52.Fd #include <limits.h>
53.Ft quad_t
54.Fn strtoq "const char *nptr" "char **endptr" "int base"
55.Sh DESCRIPTION
56The
57.Fn strtol
58function
59converts the string in
60.Fa nptr
61to a
62.Em long
63value.
64The
65.Fn strtoq
66function
67converts the string in
68.Fa nptr
69to a
70.Em quad_t
71value.
72The conversion is done according to the given
73.Fa base ,
74which must be between 2 and 36 inclusive,
75or be the special value 0.
76.Pp
77The string may begin with an arbitrary amount of white space
78(as determined by
79.Xr isspace 3 )
80followed by a single optional
81.Ql +
82or
83.Ql -
84sign.
85If
86.Fa base
87is zero or 16,
88the string may then include a
89.Ql 0x
90prefix,
91and the number will be read in base 16; otherwise, a zero
92.Fa base
93is taken as 10 (decimal) unless the next character is
94.Ql 0 ,
95in which case it is taken as 8 (octal).
96.Pp
97The remainder of the string is converted to a
98.Em long
99value in the obvious manner,
100stopping at the first character which is not a valid digit
101in the given base.
102(In bases above 10, the letter
103.Ql A
104in either upper or lower case
105represents 10,
106.Ql B
107represents 11, and so forth, with
108.Ql Z
109representing 35.)
110.Pp
111If
112.Fa endptr
113is non nil,
114.Fn strtol
115stores the address of the first invalid character in
116.Fa *endptr .
117If there were no digits at all, however,
118.Fn strtol
119stores the original value of
120.Fa nptr
121in
122.Fa *endptr .
123(Thus, if
124.Fa *nptr
125is not
126.Ql \e0
127but
128.Fa **endptr
129is
130.Ql \e0
131on return, the entire string was valid.)
132.Sh RETURN VALUES
133The
134.Fn strtol
135function
136returns the result of the conversion,
137unless the value would underflow or overflow.
138If an underflow occurs,
139.Fn strtol
140returns
141.Dv LONG_MIN .
142If an overflow occurs,
143.Fn strtol
144returns
145.Dv LONG_MAX .
146In both cases,
147.Va errno
148is set to
149.Er ERANGE .
150.Sh ERRORS
151.Bl -tag -width Er
152.It Bq Er ERANGE
153The given string was out of range; the value converted has been clamped.
154.El
155.Sh SEE ALSO
156.Xr atof 3 ,
157.Xr atoi 3 ,
158.Xr atol 3 ,
159.Xr strtod 3 ,
160.Xr strtoul 3
161.Sh STANDARDS
162The
163.Fn strtol
164function
165conforms to
166.St -ansiC .
167.Sh BUGS
168Ignores the current locale.
diff --git a/src/lib/libc/stdlib/strtol.c b/src/lib/libc/stdlib/strtol.c
new file mode 100644
index 0000000000..e4ad557fd5
--- /dev/null
+++ b/src/lib/libc/stdlib/strtol.c
@@ -0,0 +1,150 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: strtol.c,v 1.4 1996/08/19 08:33:51 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <ctype.h>
39#include <errno.h>
40#include <limits.h>
41#include <stdlib.h>
42
43
44/*
45 * Convert a string to a long integer.
46 *
47 * Ignores `locale' stuff. Assumes that the upper and lower case
48 * alphabets and digits are each contiguous.
49 */
50long
51strtol(nptr, endptr, base)
52 const char *nptr;
53 char **endptr;
54 register int base;
55{
56 register const char *s;
57 register long acc, cutoff;
58 register int c;
59 register int neg, any, cutlim;
60
61 /*
62 * Skip white space and pick up leading +/- sign if any.
63 * If base is 0, allow 0x for hex and 0 for octal, else
64 * assume decimal; if base is already 16, allow 0x.
65 */
66 s = nptr;
67 do {
68 c = (unsigned char) *s++;
69 } while (isspace(c));
70 if (c == '-') {
71 neg = 1;
72 c = *s++;
73 } else {
74 neg = 0;
75 if (c == '+')
76 c = *s++;
77 }
78 if ((base == 0 || base == 16) &&
79 c == '0' && (*s == 'x' || *s == 'X')) {
80 c = s[1];
81 s += 2;
82 base = 16;
83 }
84 if (base == 0)
85 base = c == '0' ? 8 : 10;
86
87 /*
88 * Compute the cutoff value between legal numbers and illegal
89 * numbers. That is the largest legal value, divided by the
90 * base. An input number that is greater than this value, if
91 * followed by a legal input character, is too big. One that
92 * is equal to this value may be valid or not; the limit
93 * between valid and invalid numbers is then based on the last
94 * digit. For instance, if the range for longs is
95 * [-2147483648..2147483647] and the input base is 10,
96 * cutoff will be set to 214748364 and cutlim to either
97 * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
98 * a value > 214748364, or equal but the next digit is > 7 (or 8),
99 * the number is too big, and we will return a range error.
100 *
101 * Set any if any `digits' consumed; make it negative to indicate
102 * overflow.
103 */
104 cutoff = neg ? LONG_MIN : LONG_MAX;
105 cutlim = cutoff % base;
106 cutoff /= base;
107 if (neg) {
108 if (cutlim > 0) {
109 cutlim -= base;
110 cutoff += 1;
111 }
112 cutlim = -cutlim;
113 }
114 for (acc = 0, any = 0;; c = (unsigned char) *s++) {
115 if (isdigit(c))
116 c -= '0';
117 else if (isalpha(c))
118 c -= isupper(c) ? 'A' - 10 : 'a' - 10;
119 else
120 break;
121 if (c >= base)
122 break;
123 if (any < 0)
124 continue;
125 if (neg) {
126 if (acc < cutoff || acc == cutoff && c > cutlim) {
127 any = -1;
128 acc = LONG_MIN;
129 errno = ERANGE;
130 } else {
131 any = 1;
132 acc *= base;
133 acc -= c;
134 }
135 } else {
136 if (acc > cutoff || acc == cutoff && c > cutlim) {
137 any = -1;
138 acc = LONG_MAX;
139 errno = ERANGE;
140 } else {
141 any = 1;
142 acc *= base;
143 acc += c;
144 }
145 }
146 }
147 if (endptr != 0)
148 *endptr = (char *) (any ? s - 1 : nptr);
149 return (acc);
150}
diff --git a/src/lib/libc/stdlib/strtoq.c b/src/lib/libc/stdlib/strtoq.c
new file mode 100644
index 0000000000..44aabd73f0
--- /dev/null
+++ b/src/lib/libc/stdlib/strtoq.c
@@ -0,0 +1,152 @@
1/*-
2 * Copyright (c) 1992 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: strtoq.c,v 1.4 1996/08/19 08:33:52 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/types.h>
39
40#include <ctype.h>
41#include <errno.h>
42#include <limits.h>
43#include <stdlib.h>
44
45/*
46 * Convert a string to a quad integer.
47 *
48 * Ignores `locale' stuff. Assumes that the upper and lower case
49 * alphabets and digits are each contiguous.
50 */
51quad_t
52strtoq(nptr, endptr, base)
53 const char *nptr;
54 char **endptr;
55 register int base;
56{
57 register const char *s;
58 register quad_t acc, cutoff;
59 register int c;
60 register int neg, any, cutlim;
61
62 /*
63 * Skip white space and pick up leading +/- sign if any.
64 * If base is 0, allow 0x for hex and 0 for octal, else
65 * assume decimal; if base is already 16, allow 0x.
66 */
67 s = nptr;
68 do {
69 c = (unsigned char) *s++;
70 } while (isspace(c));
71 if (c == '-') {
72 neg = 1;
73 c = *s++;
74 } else {
75 neg = 0;
76 if (c == '+')
77 c = *s++;
78 }
79 if ((base == 0 || base == 16) &&
80 c == '0' && (*s == 'x' || *s == 'X')) {
81 c = s[1];
82 s += 2;
83 base = 16;
84 }
85 if (base == 0)
86 base = c == '0' ? 8 : 10;
87
88 /*
89 * Compute the cutoff value between legal numbers and illegal
90 * numbers. That is the largest legal value, divided by the
91 * base. An input number that is greater than this value, if
92 * followed by a legal input character, is too big. One that
93 * is equal to this value may be valid or not; the limit
94 * between valid and invalid numbers is then based on the last
95 * digit. For instance, if the range for quads is
96 * [-9223372036854775808..9223372036854775807] and the input base
97 * is 10, cutoff will be set to 922337203685477580 and cutlim to
98 * either 7 (neg==0) or 8 (neg==1), meaning that if we have
99 * accumulated a value > 922337203685477580, or equal but the
100 * next digit is > 7 (or 8), the number is too big, and we will
101 * return a range error.
102 *
103 * Set any if any `digits' consumed; make it negative to indicate
104 * overflow.
105 */
106 cutoff = neg ? QUAD_MIN : QUAD_MAX;
107 cutlim = cutoff % base;
108 cutoff /= base;
109 if (neg) {
110 if (cutlim > 0) {
111 cutlim -= base;
112 cutoff += 1;
113 }
114 cutlim = -cutlim;
115 }
116 for (acc = 0, any = 0;; c = (unsigned char) *s++) {
117 if (isdigit(c))
118 c -= '0';
119 else if (isalpha(c))
120 c -= isupper(c) ? 'A' - 10 : 'a' - 10;
121 else
122 break;
123 if (c >= base)
124 break;
125 if (any < 0)
126 continue;
127 if (neg) {
128 if (acc < cutoff || acc == cutoff && c > cutlim) {
129 any = -1;
130 acc = QUAD_MIN;
131 errno = ERANGE;
132 } else {
133 any = 1;
134 acc *= base;
135 acc -= c;
136 }
137 } else {
138 if (acc > cutoff || acc == cutoff && c > cutlim) {
139 any = -1;
140 acc = QUAD_MAX;
141 errno = ERANGE;
142 } else {
143 any = 1;
144 acc *= base;
145 acc += c;
146 }
147 }
148 }
149 if (endptr != 0)
150 *endptr = (char *) (any ? s - 1 : nptr);
151 return (acc);
152}
diff --git a/src/lib/libc/stdlib/strtoul.3 b/src/lib/libc/stdlib/strtoul.3
new file mode 100644
index 0000000000..b8234122a2
--- /dev/null
+++ b/src/lib/libc/stdlib/strtoul.3
@@ -0,0 +1,163 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: strtoul.3,v 1.2 1996/08/19 08:33:52 tholo Exp $
37.\"
38.Dd June 25, 1992
39.Dt STRTOUL 3
40.Os
41.Sh NAME
42.Nm strtoul, strtouq
43.Nd convert a string to an unsigned long or uquad_t integer
44.Sh SYNOPSIS
45.Fd #include <stdlib.h>
46.Fd #include <limits.h>
47.Ft unsigned long
48.Fn strtoul "const char *nptr" "char **endptr" "int base"
49
50.Fd #include <sys/types.h>
51.Fd #include <stdlib.h>
52.Fd #include <limits.h>
53.Ft u_quad_t
54.Fn strtouq "const char *nptr" "char **endptr" "int base"
55.Sh DESCRIPTION
56The
57.Fn strtoul
58function
59converts the string in
60.Fa nptr
61to an
62.Em unsigned long
63value.
64The
65.Fn strtouq
66function
67converts the string in
68.Fa nptr
69to a
70.Em u_quad_t
71value.
72The conversion is done according to the given
73.Fa base ,
74which must be between 2 and 36 inclusive,
75or be the special value 0.
76.Pp
77The string may begin with an arbitrary amount of white space
78(as determined by
79.Xr isspace 3 )
80followed by a single optional
81.Ql +
82or
83.Ql -
84sign.
85If
86.Fa base
87is zero or 16,
88the string may then include a
89.Ql 0x
90prefix,
91and the number will be read in base 16; otherwise, a zero
92.Fa base
93is taken as 10 (decimal) unless the next character is
94.Ql 0 ,
95in which case it is taken as 8 (octal).
96.Pp
97The remainder of the string is converted to an
98.Em unsigned long
99value in the obvious manner,
100stopping at the end of the string
101or at the first character that does not produce a valid digit
102in the given base.
103(In bases above 10, the letter
104.Ql A
105in either upper or lower case
106represents 10,
107.Ql B
108represents 11, and so forth, with
109.Ql Z
110representing 35.)
111.Pp
112If
113.Fa endptr
114is non nil,
115.Fn strtoul
116stores the address of the first invalid character in
117.Fa *endptr .
118If there were no digits at all, however,
119.Fn strtoul
120stores the original value of
121.Fa nptr
122in
123.Fa *endptr .
124(Thus, if
125.Fa *nptr
126is not
127.Ql \e0
128but
129.Fa **endptr
130is
131.Ql \e0
132on return, the entire string was valid.)
133.Sh RETURN VALUES
134The
135.Fn strtoul
136function
137returns either the result of the conversion
138or, if there was a leading minus sign,
139the negation of the result of the conversion,
140unless the original (non-negated) value would overflow;
141in the latter case,
142.Fn strtoul
143returns
144.Dv ULONG_MAX
145and sets the global variable
146.Va errno
147to
148.Er ERANGE .
149.Sh ERRORS
150.Bl -tag -width Er
151.It Bq Er ERANGE
152The given string was out of range; the value converted has been clamped.
153.El
154.Sh SEE ALSO
155.Xr strtol 3
156.Sh STANDARDS
157The
158.Fn strtoul
159function
160conforms to
161.St -ansiC .
162.Sh BUGS
163Ignores the current locale.
diff --git a/src/lib/libc/stdlib/strtoul.c b/src/lib/libc/stdlib/strtoul.c
new file mode 100644
index 0000000000..d3b363fa04
--- /dev/null
+++ b/src/lib/libc/stdlib/strtoul.c
@@ -0,0 +1,112 @@
1/*
2 * Copyright (c) 1990 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: strtoul.c,v 1.4 1996/08/19 08:33:52 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <ctype.h>
39#include <errno.h>
40#include <limits.h>
41#include <stdlib.h>
42
43/*
44 * Convert a string to an unsigned long integer.
45 *
46 * Ignores `locale' stuff. Assumes that the upper and lower case
47 * alphabets and digits are each contiguous.
48 */
49unsigned long
50strtoul(nptr, endptr, base)
51 const char *nptr;
52 char **endptr;
53 register int base;
54{
55 register const char *s;
56 register unsigned long acc, cutoff;
57 register int c;
58 register int neg, any, cutlim;
59
60 /*
61 * See strtol for comments as to the logic used.
62 */
63 s = nptr;
64 do {
65 c = (unsigned char) *s++;
66 } while (isspace(c));
67 if (c == '-') {
68 neg = 1;
69 c = *s++;
70 } else {
71 neg = 0;
72 if (c == '+')
73 c = *s++;
74 }
75 if ((base == 0 || base == 16) &&
76 c == '0' && (*s == 'x' || *s == 'X')) {
77 c = s[1];
78 s += 2;
79 base = 16;
80 }
81 if (base == 0)
82 base = c == '0' ? 8 : 10;
83
84 cutoff = ULONG_MAX / (unsigned long)base;
85 cutlim = ULONG_MAX % (unsigned long)base;
86 for (acc = 0, any = 0;; c = (unsigned char) *s++) {
87 if (isdigit(c))
88 c -= '0';
89 else if (isalpha(c))
90 c -= isupper(c) ? 'A' - 10 : 'a' - 10;
91 else
92 break;
93 if (c >= base)
94 break;
95 if (any < 0)
96 continue;
97 if (acc > cutoff || acc == cutoff && c > cutlim) {
98 any = -1;
99 acc = ULONG_MAX;
100 errno = ERANGE;
101 } else {
102 any = 1;
103 acc *= (unsigned long)base;
104 acc += c;
105 }
106 }
107 if (neg && any > 0)
108 acc = -acc;
109 if (endptr != 0)
110 *endptr = (char *) (any ? s - 1 : nptr);
111 return (acc);
112}
diff --git a/src/lib/libc/stdlib/strtouq.c b/src/lib/libc/stdlib/strtouq.c
new file mode 100644
index 0000000000..1f29a22f33
--- /dev/null
+++ b/src/lib/libc/stdlib/strtouq.c
@@ -0,0 +1,114 @@
1/*-
2 * Copyright (c) 1992 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: strtouq.c,v 1.4 1996/08/19 08:33:53 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/types.h>
39
40#include <ctype.h>
41#include <errno.h>
42#include <limits.h>
43#include <stdlib.h>
44
45/*
46 * Convert a string to an unsigned quad integer.
47 *
48 * Ignores `locale' stuff. Assumes that the upper and lower case
49 * alphabets and digits are each contiguous.
50 */
51u_quad_t
52strtouq(nptr, endptr, base)
53 const char *nptr;
54 char **endptr;
55 register int base;
56{
57 register const char *s;
58 register u_quad_t acc, cutoff;
59 register int c;
60 register int neg, any, cutlim;
61
62 /*
63 * See strtoq for comments as to the logic used.
64 */
65 s = nptr;
66 do {
67 c = (unsigned char) *s++;
68 } while (isspace(c));
69 if (c == '-') {
70 neg = 1;
71 c = *s++;
72 } else {
73 neg = 0;
74 if (c == '+')
75 c = *s++;
76 }
77 if ((base == 0 || base == 16) &&
78 c == '0' && (*s == 'x' || *s == 'X')) {
79 c = s[1];
80 s += 2;
81 base = 16;
82 }
83 if (base == 0)
84 base = c == '0' ? 8 : 10;
85
86 cutoff = UQUAD_MAX / (u_quad_t)base;
87 cutlim = UQUAD_MAX % (u_quad_t)base;
88 for (acc = 0, any = 0;; c = (unsigned char) *s++) {
89 if (isdigit(c))
90 c -= '0';
91 else if (isalpha(c))
92 c -= isupper(c) ? 'A' - 10 : 'a' - 10;
93 else
94 break;
95 if (c >= base)
96 break;
97 if (any < 0)
98 continue;
99 if (acc > cutoff || acc == cutoff && c > cutlim) {
100 any = -1;
101 acc = UQUAD_MAX;
102 errno = ERANGE;
103 } else {
104 any = 1;
105 acc *= (u_quad_t)base;
106 acc += c;
107 }
108 }
109 if (neg && any > 0)
110 acc = -acc;
111 if (endptr != 0)
112 *endptr = (char *) (any ? s - 1 : nptr);
113 return (acc);
114}
diff --git a/src/lib/libc/stdlib/system.3 b/src/lib/libc/stdlib/system.3
new file mode 100644
index 0000000000..985adb07de
--- /dev/null
+++ b/src/lib/libc/stdlib/system.3
@@ -0,0 +1,98 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: system.3,v 1.5 1996/12/11 23:09:53 tholo Exp $
37.\"
38.Dd June 29, 1991
39.Dt SYSTEM 3
40.Os
41.Sh NAME
42.Nm system
43.Nd pass a command to the shell
44.Sh SYNOPSIS
45.Fd #include <stdlib.h>
46.Ft int
47.Fn system "const char *string"
48.Sh DESCRIPTION
49The
50.Fn system
51function
52hands the argument
53.Fa string
54to the command interpreter
55.Xr sh 1 .
56The calling process waits for the shell to finish executing the command,
57ignoring
58.Dv SIGINT
59and
60.Dv SIGQUIT ,
61and blocking
62.Dv SIGCHLD .
63.Pp
64If
65.Fa string
66is a
67.Dv NULL
68pointer,
69.Fn system
70will return non-zero.
71Otherwise,
72.Fn system
73returns the termination status of the shell in the format specified by
74.Xr waitpid 2 .
75.Sh RETURN VALUES
76If a child process cannot be created, or the termination status of
77the shell cannot be obtained,
78.Fn system
79returns -1 and sets
80.Va errno
81to indicate the error.
82If execution of the shell fails,
83.Fn system
84returns the termination status for a program that terminates with a call of
85.Fn exit 127 .
86.Sh SEE ALSO
87.Xr sh 1 ,
88.Xr execve 2 ,
89.Xr waitpid 2 ,
90.Xr popen 3
91.Sh STANDARDS
92The
93.Fn system
94function
95conforms to
96.St -ansiC
97and
98.St -p1003.2-92 .
diff --git a/src/lib/libc/stdlib/system.c b/src/lib/libc/stdlib/system.c
new file mode 100644
index 0000000000..3e1b047393
--- /dev/null
+++ b/src/lib/libc/stdlib/system.c
@@ -0,0 +1,80 @@
1/*
2 * Copyright (c) 1988 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: system.c,v 1.3 1996/09/15 09:31:52 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/types.h>
39#include <sys/wait.h>
40#include <signal.h>
41#include <stdlib.h>
42#include <unistd.h>
43#include <paths.h>
44
45extern char **environ;
46
47int
48system(command)
49 const char *command;
50{
51 pid_t pid;
52 sig_t intsave, quitsave;
53 int omask;
54 int pstat;
55 char *argp[] = {"sh", "-c", NULL, NULL};
56
57 if (!command) /* just checking... */
58 return(1);
59
60 argp[2] = (char *)command;
61
62 omask = sigblock(sigmask(SIGCHLD));
63 switch(pid = vfork()) {
64 case -1: /* error */
65 (void)sigsetmask(omask);
66 return(-1);
67 case 0: /* child */
68 (void)sigsetmask(omask);
69 execve(_PATH_BSHELL, argp, environ);
70 _exit(127);
71 }
72
73 intsave = signal(SIGINT, SIG_IGN);
74 quitsave = signal(SIGQUIT, SIG_IGN);
75 pid = waitpid(pid, (int *)&pstat, 0);
76 (void)sigsetmask(omask);
77 (void)signal(SIGINT, intsave);
78 (void)signal(SIGQUIT, quitsave);
79 return(pid == -1 ? -1 : pstat);
80}
diff --git a/src/lib/libc/stdlib/tfind.c b/src/lib/libc/stdlib/tfind.c
new file mode 100644
index 0000000000..9e5bd4b0f2
--- /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) __P((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..dbdae7943c
--- /dev/null
+++ b/src/lib/libc/stdlib/tsearch.3
@@ -0,0 +1,116 @@
1.\" Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
2.\" All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\" notice, this list of conditions and the following disclaimer.
9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\" notice, this list of conditions and the following disclaimer in the
11.\" documentation and/or other materials provided with the distribution.
12.\" 3. The name of the author may not be used to endorse or promote products
13.\" derived from this software without specific prior written permission.
14.\"
15.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
16.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
17.\" AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
18.\" THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19.\" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20.\" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21.\" OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25.\"
26.\" $OpenBSD: tsearch.3,v 1.2 1998/06/21 22:13:49 millert Exp $
27.\"
28.Dd June 15, 1997
29.Dt TSEARCH 3
30.Os
31.Sh NAME
32.Nm tsearch, tfind, tdelete, twalk
33.Nd manipulate binary search trees
34.Sh SYNOPSIS
35.Fd #include <search.h>
36.Ft void *
37.Fn tdelete "const void *key" "void **rootp", "int (*compar) (const void *, const void *)"
38.Ft void *
39.Fn tfind "const void *key" "void * const *rootp", "int (*compar) (const void *, const void *)"
40.Ft void *
41.Fn tsearch "const void *key" "void **rootp", "int (*compar) (const void *, const void *)"
42.Ft void
43.Fn twalk "const void *root" "void (*compar) (const void *, VISIT, int)"
44.Sh DESCRIPTION
45The
46.Fn tdelete ,
47.Fn tfind ,
48.Fn tsearch ,
49and
50.Fn twalk
51functions manage binary search trees based on algorithms T and D
52from Knuth (6.2.2). The comparison function passed in by
53the user has the same style of return values as
54.Xr strcmp 3 .
55.Pp
56.Fn Tfind
57searches for the datum matched by the argument
58.Fa key
59in the binary tree rooted at
60.Fa rootp ,
61returning a pointer to the datum if it is found and NULL
62if it is not.
63.Pp
64.Fn Tsearch
65is identical to
66.Fn tfind
67except that if no match is found,
68.Fa key
69is inserted into the tree and a pointer to it is returned. If
70.Fa rootp
71points to a NULL value a new binary search tree is created.
72.Pp
73.Fn Tdelete
74deletes a node from the specified binary search tree and returns
75a pointer to the parent of the node to be deleted.
76It takes the same arguments as
77.Fn tfind
78and
79.Fn tsearch .
80If the node to be deleted is the root of the binary search tree,
81.Fa rootp
82will be adjusted.
83.Pp
84.Fn Twalk
85walks the binary search tree rooted in
86.fa root
87and calls the function
88.Fa action
89on each node.
90.Fa Action
91is called with three arguments: a pointer to the current node,
92a value from the enum
93.Sy "typedef enum { preorder, postorder, endorder, leaf } VISIT;"
94specifying the traversal type, and a node level (where level
95zero is the root of the tree).
96.Sh SEE ALSO
97.Xr bsearch 3 ,
98.Xr hsearch 3 ,
99.Xr lsearch 3
100.Sh RETURN VALUES
101The
102.Fn tsearch
103function returns NULL if allocation of a new node fails (usually
104due to a lack of free memory).
105.Pp
106.Fn Tfind ,
107.Fn tsearch ,
108and
109.Fn tdelete
110return NULL if
111.Fa rootp
112is NULL or the datum cannot be found.
113.Pp
114The
115.Fn twalk
116function returns no value.
diff --git a/src/lib/libc/stdlib/tsearch.c b/src/lib/libc/stdlib/tsearch.c
new file mode 100644
index 0000000000..562ace1845
--- /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) __P((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) __P((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) __P((const void *, VISIT, int));
121{
122 node *root = (node *)vroot;
123
124 if (root != (node *)0 && action != (void(*)())0)
125 trecurse(root, action, 0);
126}
diff --git a/src/lib/libc/string/Makefile.inc b/src/lib/libc/string/Makefile.inc
new file mode 100644
index 0000000000..076db78945
--- /dev/null
+++ b/src/lib/libc/string/Makefile.inc
@@ -0,0 +1,128 @@
1# $OpenBSD: Makefile.inc,v 1.5 1998/07/01 01:29:44 millert Exp $
2
3# string sources
4.PATH: ${.CURDIR}/arch/${MACHINE_ARCH}/string ${.CURDIR}/string
5
6SRCS+= bm.c memccpy.c strcasecmp.c strcoll.c strdup.c strerror.c \
7 strlcat.c strlcpy.c strmode.c strsignal.c strtok.c strxfrm.c \
8 __strerror.c __strsignal.c
9
10# machine-dependent net sources
11# m-d Makefile.inc must include sources for:
12# bcmp() bcopy() bzero() ffs() index() memchr() memcmp() memset()
13# rindex() strcat() strcmp() strcpy() strcspn() strlen()
14# strncat() strncmp() strncpy() strpbrk() strsep()
15# strspn() strstr() swav()
16# m-d Makefile.inc may include sources for:
17# memcpy() memmove() strchr() strrchr()
18
19.include "${.CURDIR}/arch/${MACHINE_ARCH}/string/Makefile.inc"
20
21# if no machine specific memmove(3), build one out of bcopy(3).
22.if empty(SRCS:Mmemmove.S)
23OBJS+= memmove.o
24memmove.o: bcopy.c
25 ${CC} -DMEMMOVE ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} -o ${.TARGET}
26 @${LD} -x -r ${.TARGET}
27 @mv a.out ${.TARGET}
28
29memmove.po: bcopy.c
30 ${CC} -DMEMMOVE ${CFLAGS} ${CPPFLAGS} -c -p ${.ALLSRC} -o ${.TARGET}
31 @${LD} -X -r ${.TARGET}
32 @mv a.out ${.TARGET}
33
34memmove.so: bcopy.c
35 ${CC} ${PICFLAG} -DPIC -DMEMMOVE ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} \
36 -o ${.TARGET}
37.endif
38
39# if no machine specific memcpy(3), build one out of bcopy(3).
40# if there is a machine specific memmove(3), we'll assume it aliases
41# memcpy(3).
42.if empty(SRCS:Mmemcpy.S)
43.if empty(SRCS:Mmemmove.S)
44OBJS+= memcpy.o
45memcpy.o: bcopy.c
46 ${CC} -DMEMCOPY ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} -o ${.TARGET}
47 @${LD} -x -r ${.TARGET}
48 @mv a.out ${.TARGET}
49
50memcpy.po: bcopy.c
51 ${CC} -DMEMCOPY ${CFLAGS} ${CPPFLAGS} -c -p ${.ALLSRC} -o ${.TARGET}
52 @${LD} -X -r ${.TARGET}
53 @mv a.out ${.TARGET}
54
55memcpy.so: bcopy.c
56 ${CC} ${PICFLAG} -DPIC -DMEMCOPY ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} \
57 -o ${.TARGET}
58.endif
59.endif
60
61# if no machine specific strchr(3), build one out of index(3).
62.if empty(SRCS:Mstrchr.S)
63OBJS+= strchr.o
64strchr.o: index.c
65 ${CC} -DSTRCHR ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} -o ${.TARGET}
66 @${LD} -x -r ${.TARGET}
67 @mv a.out ${.TARGET}
68
69strchr.po: index.c
70 ${CC} -DSTRCHR ${CFLAGS} ${CPPFLAGS} -c -p ${.ALLSRC} -o ${.TARGET}
71 @${LD} -X -r ${.TARGET}
72 @mv a.out ${.TARGET}
73
74strchr.so: index.c
75 ${CC} ${PICFLAG} -DPIC -DSTRCHR ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} \
76 -o ${.TARGET}
77.endif
78
79# if no machine specific strrchr(3), build one out of rindex(3).
80.if empty(SRCS:Mstrrchr.S)
81OBJS+= strrchr.o
82strrchr.o: rindex.c
83 ${CC} -DSTRRCHR ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} -o ${.TARGET}
84 @${LD} -x -r ${.TARGET}
85 @mv a.out ${.TARGET}
86
87strrchr.po: rindex.c
88 ${CC} -DSTRRCHR ${CFLAGS} ${CPPFLAGS} -c -p ${.ALLSRC} -o ${.TARGET}
89 @${LD} -X -r ${.TARGET}
90 @mv a.out ${.TARGET}
91
92strrchr.so: rindex.c
93 ${CC} ${PICFLAG} -DPIC -DSTRRCHR ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} \
94 -o ${.TARGET}
95.endif
96
97# build .ln files for memmove, memcpy, strchr and strrchr always from
98# bcopy, index, and rindex
99LOBJS+= memmove.ln memcpy.ln strchr.ln strrchr.ln
100
101memmove.ln: bcopy.c
102 lint ${LINTFLAGS} -DMEMMOVE ${CFLAGS:M-[IDU]*} -i -o ${.TARGET} \
103 ${.CURDIR}/string/bcopy.c
104
105memcpy.ln: bcopy.c
106 lint ${LINTFLAGS} -DMEMCOPY ${CFLAGS:M-[IDU]*} -i -o ${.TARGET} \
107 ${.CURDIR}/string/bcopy.c
108
109strchr.ln: index.c
110 lint ${LINTFLAGS} -DSTRCHR ${CFLAGS:M-[IDU]*} -i -o ${.TARGET} \
111 ${.CURDIR}/string/index.c
112
113strrchr.ln: rindex.c
114 lint ${LINTFLAGS} -DSTRRCHR ${CFLAGS:M-[IDU]*} -i -o ${.TARGET} \
115 ${.CURDIR}/string/rindex.c
116
117MAN+= bm.3 bcmp.3 bcopy.3 bstring.3 bzero.3 ffs.3 index.3 memccpy.3 memchr.3 \
118 memcmp.3 memcpy.3 memmove.3 memset.3 rindex.3 strcasecmp.3 strcat.3 \
119 strchr.3 strcmp.3 strcoll.3 strcpy.3 strcspn.3 strerror.3 \
120 string.3 strlen.3 strmode.3 strdup.3 strpbrk.3 strrchr.3 strsep.3 \
121 strsignal.3 strspn.3 strstr.3 strtok.3 strxfrm.3 swab.3 strlcpy.3
122
123MLINKS+=bm.3 bm_comp.3 bm.3 bm_exec.3 bm.3 bm_free.3
124MLINKS+=strcasecmp.3 strncasecmp.3
125MLINKS+=strcat.3 strncat.3
126MLINKS+=strcmp.3 strncmp.3
127MLINKS+=strcpy.3 strncpy.3
128MLINKS+=strlcpy.3 strlcat.3
diff --git a/src/lib/libc/string/__strerror.c b/src/lib/libc/string/__strerror.c
new file mode 100644
index 0000000000..9c023f8a53
--- /dev/null
+++ b/src/lib/libc/string/__strerror.c
@@ -0,0 +1,111 @@
1/*
2 * Copyright (c) 1988 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: __strerror.c,v 1.6 1996/09/25 08:17:30 deraadt Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#ifdef NLS
39#define catclose _catclose
40#define catgets _catgets
41#define catopen _catopen
42#include <nl_types.h>
43#endif
44
45#define sys_errlist _sys_errlist
46#define sys_nerr _sys_nerr
47
48#include <errno.h>
49#include <limits.h>
50#include <stdio.h>
51#include <string.h>
52
53static char *itoa(num)
54 int num;
55{
56 static char buffer[11];
57 char *p;
58
59 p = buffer + 4;
60 while (num >= 10) {
61 *--p = (num % 10) + '0';
62 num /= 10;
63 }
64 *p = (num % 10) + '0';
65 return p;
66}
67
68/*
69 * Since perror() is not allowed to change the contents of strerror()'s
70 * static buffer, both functions supply their own buffers to the
71 * internal function __strerror().
72 */
73
74char *
75__strerror(num, buf)
76 int num;
77 char *buf;
78{
79#define UPREFIX "Unknown error: "
80 register unsigned int errnum;
81
82#ifdef NLS
83 nl_catd catd;
84 catd = catopen("libc", 0);
85#endif
86
87 errnum = num; /* convert to unsigned */
88 if (errnum < sys_nerr) {
89#ifdef NLS
90 strncpy(buf, catgets(catd, 1, errnum,
91 (char *)sys_errlist[errnum]), NL_TEXTMAX-1);
92 buf[NL_TEXTMAX - 1] = '\0';
93#else
94 return(sys_errlist[errnum]);
95#endif
96 } else {
97#ifdef NLS
98 strncpy(buf, catgets(catd, 1, 0xffff, UPREFIX), NL_TEXTMAX-1);
99 buf[NL_TEXTMAX - 1] = '\0';
100#else
101 strcpy(buf, UPREFIX);
102#endif
103 strncat(buf, itoa(errnum), NL_TEXTMAX-strlen(buf)-1);
104 }
105
106#ifdef NLS
107 catclose(catd);
108#endif
109
110 return buf;
111}
diff --git a/src/lib/libc/string/__strsignal.c b/src/lib/libc/string/__strsignal.c
new file mode 100644
index 0000000000..ae0df72cd3
--- /dev/null
+++ b/src/lib/libc/string/__strsignal.c
@@ -0,0 +1,104 @@
1/*
2 * Copyright (c) 1988 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: __strsignal.c,v 1.5 1996/09/25 13:19:01 deraadt Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#ifdef NLS
39#define catclose _catclose
40#define catgets _catgets
41#define catopen _catopen
42#include <nl_types.h>
43#endif
44
45#define sys_siglist _sys_siglist
46
47#include <stdio.h>
48#include <limits.h>
49#include <signal.h>
50#include <string.h>
51
52static char *itoa(num)
53 int num;
54{
55 static char buffer[11];
56 char *p;
57
58 p = buffer + 4;
59 while (num >= 10) {
60 *--p = (num % 10) + '0';
61 num /= 10;
62 }
63 *p = (num % 10) + '0';
64 return p;
65}
66
67char *
68__strsignal(num, buf)
69 int num;
70 char *buf;
71{
72#define UPREFIX "Unknown signal: "
73 register unsigned int signum;
74
75#ifdef NLS
76 nl_catd catd ;
77 catd = catopen("libc", 0);
78#endif
79
80 signum = num; /* convert to unsigned */
81 if (signum < NSIG) {
82#ifdef NLS
83 strncpy(buf, catgets(catd, 2, signum,
84 (char *)sys_siglist[signum]), NL_TEXTMAX-1);
85 buf[NL_TEXTMAX-1] = '\0';
86#else
87 return((char *)sys_siglist[signum]);
88#endif
89 } else {
90#ifdef NLS
91 strncpy(buf, catgets(catd, 1, 0xffff, UPREFIX), NL_TEXTMAX-1);
92 buf[NL_TEXTMAX-1] = '\0';
93#else
94 strcpy(buf, UPREFIX);
95#endif
96 strncat(buf, itoa(signum), NL_TEXTMAX-strlen(buf)-1);
97 }
98
99#ifdef NLS
100 catclose(catd);
101#endif
102
103 return buf;
104}
diff --git a/src/lib/libc/string/bcmp.3 b/src/lib/libc/string/bcmp.3
new file mode 100644
index 0000000000..9234b5739d
--- /dev/null
+++ b/src/lib/libc/string/bcmp.3
@@ -0,0 +1,71 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek.
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.\" $OpenBSD: bcmp.3,v 1.2 1996/08/19 08:33:56 tholo Exp $
35.\"
36.Dd April 19, 1991
37.Dt BCMP 3
38.Os BSD 4.2
39.Sh NAME
40.Nm bcmp
41.Nd compare byte string
42.Sh SYNOPSIS
43.Fd #include <string.h>
44.Ft int
45.Fn bcmp "const void *b1" "const void *b2" "size_t len"
46.Sh DESCRIPTION
47The
48.Fn bcmp
49function
50compares byte string
51.Fa b1
52against byte string
53.Fa b2 ,
54returning zero if they are identical, non-zero otherwise.
55Both strings are assumed to be
56.Fa len
57bytes long.
58Zero-length strings are always identical.
59.Pp
60The strings may overlap.
61.Sh SEE ALSO
62.Xr memcmp 3 ,
63.Xr strcasecmp 3 ,
64.Xr strcmp 3 ,
65.Xr strcoll 3 ,
66.Xr strxfrm 3
67.Sh HISTORY
68A
69.Fn bcmp
70function first appeared in
71.Bx 4.2 .
diff --git a/src/lib/libc/string/bcmp.c b/src/lib/libc/string/bcmp.c
new file mode 100644
index 0000000000..4ed00975a4
--- /dev/null
+++ b/src/lib/libc/string/bcmp.c
@@ -0,0 +1,63 @@
1/*
2 * Copyright (c) 1987 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: bcmp.c,v 1.4 1996/08/19 08:33:57 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#ifndef _KERNEL
39#include <string.h>
40#else
41#include <lib/libkern/libkern.h>
42#endif
43
44/*
45 * bcmp -- vax cmpc3 instruction
46 */
47int
48bcmp(b1, b2, length)
49 const void *b1, *b2;
50 register size_t length;
51{
52 register char *p1, *p2;
53
54 if (length == 0)
55 return(0);
56 p1 = (char *)b1;
57 p2 = (char *)b2;
58 do
59 if (*p1++ != *p2++)
60 break;
61 while (--length);
62 return(length);
63}
diff --git a/src/lib/libc/string/bcopy.3 b/src/lib/libc/string/bcopy.3
new file mode 100644
index 0000000000..4e841562e0
--- /dev/null
+++ b/src/lib/libc/string/bcopy.3
@@ -0,0 +1,71 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek.
6.\"
7.\" Redistribution and use in source and binary forms, with or without
8.\" modification, are permitted provided that the following conditions
9.\" are met:
10.\" 1. Redistributions of source code must retain the above copyright
11.\" notice, this list of conditions and the following disclaimer.
12.\" 2. Redistributions in binary form must reproduce the above copyright
13.\" notice, this list of conditions and the following disclaimer in the
14.\" documentation and/or other materials provided with the distribution.
15.\" 3. All advertising materials mentioning features or use of this software
16.\" must display the following acknowledgement:
17.\" This product includes software developed by the University of
18.\" California, Berkeley and its contributors.
19.\" 4. Neither the name of the University nor the names of its contributors
20.\" may be used to endorse or promote products derived from this software
21.\" without specific prior written permission.
22.\"
23.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33.\" SUCH DAMAGE.
34.\"
35.\" $OpenBSD: bcopy.3,v 1.2 1996/08/19 08:33:57 tholo Exp $
36.\"
37.Dd April 19, 1991
38.Dt BCOPY 3
39.Os BSD 4.2
40.Sh NAME
41.Nm bcopy
42.Nd copy byte string
43.Sh SYNOPSIS
44.Fd #include <string.h>
45.Ft void
46.Fn bcopy "const void *src" "void *dst" "size_t len"
47.Sh DESCRIPTION
48The
49.Fn bcopy
50function
51copies
52.Fa len
53bytes from string
54.Fa src
55to string
56.Fa dst .
57The two strings may overlap.
58If
59.Fa len
60is zero, no bytes are copied.
61.Sh SEE ALSO
62.Xr memccpy 3 ,
63.Xr memcpy 3 ,
64.Xr memmove 3 ,
65.Xr strcpy 3 ,
66.Xr strncpy 3
67.Sh HISTORY
68A
69.Fn bcopy
70function appeared in
71.Bx 4.2 .
diff --git a/src/lib/libc/string/bcopy.c b/src/lib/libc/string/bcopy.c
new file mode 100644
index 0000000000..023a3b2db2
--- /dev/null
+++ b/src/lib/libc/string/bcopy.c
@@ -0,0 +1,138 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Chris Torek.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: bcopy.c,v 1.2 1996/08/19 08:33:58 tholo Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#include <string.h>
42
43/*
44 * sizeof(word) MUST BE A POWER OF TWO
45 * SO THAT wmask BELOW IS ALL ONES
46 */
47typedef long word; /* "word" used for optimal copy speed */
48
49#define wsize sizeof(word)
50#define wmask (wsize - 1)
51
52/*
53 * Copy a block of memory, handling overlap.
54 * This is the routine that actually implements
55 * (the portable versions of) bcopy, memcpy, and memmove.
56 */
57#ifdef MEMCOPY
58void *
59memcpy(dst0, src0, length)
60#else
61#ifdef MEMMOVE
62void *
63memmove(dst0, src0, length)
64#else
65void
66bcopy(src0, dst0, length)
67#endif
68#endif
69 void *dst0;
70 const void *src0;
71 register size_t length;
72{
73 register char *dst = dst0;
74 register const char *src = src0;
75 register size_t t;
76
77 if (length == 0 || dst == src) /* nothing to do */
78 goto done;
79
80 /*
81 * Macros: loop-t-times; and loop-t-times, t>0
82 */
83#define TLOOP(s) if (t) TLOOP1(s)
84#define TLOOP1(s) do { s; } while (--t)
85
86 if ((unsigned long)dst < (unsigned long)src) {
87 /*
88 * Copy forward.
89 */
90 t = (long)src; /* only need low bits */
91 if ((t | (long)dst) & wmask) {
92 /*
93 * Try to align operands. This cannot be done
94 * unless the low bits match.
95 */
96 if ((t ^ (long)dst) & wmask || length < wsize)
97 t = length;
98 else
99 t = wsize - (t & wmask);
100 length -= t;
101 TLOOP1(*dst++ = *src++);
102 }
103 /*
104 * Copy whole words, then mop up any trailing bytes.
105 */
106 t = length / wsize;
107 TLOOP(*(word *)dst = *(word *)src; src += wsize; dst += wsize);
108 t = length & wmask;
109 TLOOP(*dst++ = *src++);
110 } else {
111 /*
112 * Copy backwards. Otherwise essentially the same.
113 * Alignment works as before, except that it takes
114 * (t&wmask) bytes to align, not wsize-(t&wmask).
115 */
116 src += length;
117 dst += length;
118 t = (long)src;
119 if ((t | (long)dst) & wmask) {
120 if ((t ^ (long)dst) & wmask || length <= wsize)
121 t = length;
122 else
123 t &= wmask;
124 length -= t;
125 TLOOP1(*--dst = *--src);
126 }
127 t = length / wsize;
128 TLOOP(src -= wsize; dst -= wsize; *(word *)dst = *(word *)src);
129 t = length & wmask;
130 TLOOP(*--dst = *--src);
131 }
132done:
133#if defined(MEMCOPY) || defined(MEMMOVE)
134 return (dst0);
135#else
136 return;
137#endif
138}
diff --git a/src/lib/libc/string/bm.3 b/src/lib/libc/string/bm.3
new file mode 100644
index 0000000000..c942930163
--- /dev/null
+++ b/src/lib/libc/string/bm.3
@@ -0,0 +1,113 @@
1.\" Copyright (c) 1994
2.\" The Regents of the University of California. All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Andrew Hume of AT&T Bell Laboratories.
6.\"
7.\" Redistribution and use in source and binary forms, with or without
8.\" modification, are permitted provided that the following conditions
9.\" are met:
10.\" 1. Redistributions of source code must retain the above copyright
11.\" notice, this list of conditions and the following disclaimer.
12.\" 2. Redistributions in binary form must reproduce the above copyright
13.\" notice, this list of conditions and the following disclaimer in the
14.\" documentation and/or other materials provided with the distribution.
15.\" 3. All advertising materials mentioning features or use of this software
16.\" must display the following acknowledgement:
17.\" This product includes software developed by the University of
18.\" California, Berkeley and its contributors.
19.\" 4. Neither the name of the University nor the names of its contributors
20.\" may be used to endorse or promote products derived from this software
21.\" without specific prior written permission.
22.\"
23.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33.\" SUCH DAMAGE.
34.\"
35.\" $OpenBSD: bm.3,v 1.2 1996/08/19 08:33:58 tholo Exp $
36.\"
37.TH BM 3
38.SH NAME
39bm_comp, bm_exec, bm_free \- Boyer-Moore string search
40.SH SYNOPSIS
41.ft B
42#include <sys/types.h>
43.br
44#include <bm.h>
45.sp
46bm_pat *
47.br
48bm_comp(u_char *pattern, size_t patlen, u_char freq[256]);
49.sp
50u_char *
51.br
52bm_exec(bm_pat *pdesc, u_char *text, size_t len);
53.sp
54void
55.br
56bm_free(bm_pat *pdesc);
57.SH DESCRIPTION
58These routines implement an efficient mechanism to find an
59occurrence of a byte string within another byte string.
60.PP
61.I Bm_comp
62evaluates the
63.I patlen
64bytes starting at
65.IR pattern ,
66and returns a pointer to a structure describing them.
67The bytes referenced by
68.I pattern
69may be of any value.
70.PP
71The search takes advantage of the frequency distribution of the
72bytes in the text to be searched.
73If specified,
74.I freq
75should be an array of 256 values,
76with higher values indicating that the corresponding character occurs
77more frequently.
78(A less than optimal frequency distribution can only result in less
79than optimal performance, not incorrect results.)
80If
81.I freq
82is NULL,
83a system default table is used.
84.PP
85.I Bm_exec
86returns a pointer to the leftmost occurrence of the string given to
87.I bm_comp
88within
89.IR text ,
90or NULL if none occurs.
91The number of bytes in
92.I text
93must be specified by
94.IR len .
95.PP
96Space allocated for the returned description is discarded
97by calling
98.I bm_free
99with the returned description as an argument.
100.PP
101The asymptotic speed of
102.I bm_exec
103is
104.RI O( len / patlen ).
105.PP
106.SH "SEE ALSO"
107.IR regexp (3),
108.IR strstr (3)
109.sp
110.IR "Fast String Searching" ,
111Hume and Sunday,
112Software Practice and Experience,
113Vol. 21, 11 (November 1991) pp. 1221-48.
diff --git a/src/lib/libc/string/bm.c b/src/lib/libc/string/bm.c
new file mode 100644
index 0000000000..b191d340f6
--- /dev/null
+++ b/src/lib/libc/string/bm.c
@@ -0,0 +1,219 @@
1/*-
2 * Copyright (c) 1994
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Andrew Hume of AT&T Bell Laboratories.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: bm.c,v 1.3 1996/08/19 08:33:59 tholo Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#include <sys/types.h>
42
43#include <bm.h>
44#include <errno.h>
45#include <stdlib.h>
46#include <string.h>
47
48/*
49 * XXX
50 * The default frequency table starts at 99 and counts down. The default
51 * table should probably be oriented toward text, and will necessarily be
52 * locale specific. This one is for English. It was derived from the
53 * OSF/1 and 4.4BSD formatted and unformatted manual pages, and about 100Mb
54 * of email and random text. Change it if you can find something better.
55 */
56static u_char const freq_def[256] = {
57 0, 0, 0, 0, 0, 0, 0, 0,
58 0, 77, 90, 0, 0, 0, 0, 0,
59 0, 0, 0, 0, 0, 0, 0, 0,
60 0, 0, 0, 0, 0, 0, 0, 0,
61 99, 28, 42, 27, 16, 14, 20, 51,
62 66, 65, 59, 24, 75, 76, 84, 56,
63 72, 74, 64, 55, 54, 47, 41, 37,
64 44, 61, 70, 43, 23, 53, 49, 22,
65 33, 58, 40, 46, 45, 57, 60, 26,
66 30, 63, 21, 12, 32, 50, 38, 39,
67 34, 11, 48, 67, 62, 35, 15, 29,
68 71, 18, 9, 17, 25, 13, 10, 52,
69 36, 95, 78, 86, 87, 98, 82, 80,
70 88, 94, 19, 68, 89, 83, 93, 96,
71 81, 7, 91, 92, 97, 85, 69, 73,
72 31, 79, 8, 5, 4, 6, 3, 0,
73 0, 0, 0, 0, 0, 0, 0, 0,
74 0, 0, 0, 0, 0, 0, 0, 0,
75 0, 0, 0, 0, 0, 0, 0, 0,
76 0, 0, 0, 0, 0, 0, 0, 0,
77 0, 0, 0, 0, 0, 0, 0, 0,
78 0, 0, 0, 0, 0, 0, 0, 0,
79 0, 0, 0, 0, 0, 0, 0, 0,
80 0, 0, 0, 0, 0, 0, 0, 0,
81 0, 0, 0, 0, 0, 0, 0, 0,
82 0, 0, 0, 0, 0, 0, 0, 0,
83 0, 0, 0, 0, 0, 0, 0, 0,
84 0, 0, 0, 0, 0, 0, 0, 0,
85 0, 0, 0, 0, 0, 0, 0, 0,
86 0, 0, 0, 0, 0, 0, 0, 0,
87 0, 0, 0, 0, 0, 0, 0, 0,
88 0, 0, 0, 0, 0, 0, 0, 0,
89};
90
91bm_pat *
92bm_comp(pb, len, freq)
93 u_char const *pb;
94 size_t len;
95 u_char const *freq;
96{
97 register u_char const *pe, *p;
98 register size_t *d, r;
99 register int j;
100 int sv_errno;
101 bm_pat *pat;
102
103 if (len == 0) {
104 errno = EINVAL;
105 return (NULL);
106 }
107 if ((pat = malloc(sizeof(*pat))) == NULL)
108 return (NULL);
109 pat->pat = NULL;
110 pat->delta = NULL;
111
112 pat->patlen = len; /* copy pattern */
113 if ((pat->pat = malloc(pat->patlen)) == NULL)
114 goto mem;
115 memcpy(pat->pat, pb, pat->patlen);
116 /* get skip delta */
117 if ((pat->delta = malloc(256 * sizeof(*d))) == NULL)
118 goto mem;
119 for (j = 0, d = pat->delta; j < 256; j++)
120 d[j] = pat->patlen;
121 for (pe = pb + pat->patlen - 1; pb <= pe; pb++)
122 d[*pb] = pe - pb;
123
124 if (freq == NULL) /* default freq table */
125 freq = freq_def;
126 r = 0; /* get guard */
127 for (pb = pat->pat, pe = pb + pat->patlen - 1; pb < pe; pb++)
128 if (freq[*pb] < freq[pat->pat[r]])
129 r = pb - pat->pat;
130 pat->rarec = pat->pat[r];
131 pat->rareoff = r - (pat->patlen - 1);
132
133 /* get md2 shift */
134 for (pe = pat->pat + pat->patlen - 1, p = pe - 1; p >= pat->pat; p--)
135 if (*p == *pe)
136 break;
137
138 /* *p is first leftward reoccurrence of *pe */
139 pat->md2 = pe - p;
140 return (pat);
141
142mem: sv_errno = errno;
143 bm_free(pat);
144 errno = sv_errno;
145 return (NULL);
146}
147
148void
149bm_free(pat)
150 bm_pat *pat;
151{
152 if (pat->pat != NULL)
153 free(pat->pat);
154 if (pat->delta != NULL)
155 free(pat->delta);
156 free(pat);
157}
158
159u_char *
160bm_exec(pat, base, n)
161 bm_pat *pat;
162 u_char *base;
163 size_t n;
164{
165 register u_char *e, *ep, *p, *q, *s;
166 register size_t *d0, k, md2, n1, ro;
167 register int rc;
168
169 if (n == 0)
170 return (NULL);
171
172 d0 = pat->delta;
173 n1 = pat->patlen - 1;
174 md2 = pat->md2;
175 ro = pat->rareoff;
176 rc = pat->rarec;
177 ep = pat->pat + pat->patlen - 1;
178 s = base + (pat->patlen - 1);
179
180 /* fast loop up to n - 3 * patlen */
181 e = base + n - 3 * pat->patlen;
182 while (s < e) {
183 k = d0[*s]; /* ufast skip loop */
184 while (k) {
185 k = d0[*(s += k)];
186 k = d0[*(s += k)];
187 }
188 if (s >= e)
189 break;
190 if (s[ro] != rc) /* guard test */
191 goto mismatch1;
192 /* fwd match */
193 for (p = pat->pat, q = s - n1; p < ep;)
194 if (*q++ != *p++)
195 goto mismatch1;
196 return (s - n1);
197
198mismatch1: s += md2; /* md2 shift */
199 }
200
201 /* slow loop up to end */
202 e = base + n;
203 while (s < e) {
204 s += d0[*s]; /* step */
205 if (s >= e)
206 break;
207 if (s[ro] != rc) /* guard test */
208 goto mismatch2;
209 /* fwd match */
210 for (p = pat->pat, q = s - n1; p <= ep;)
211 if (*q++ != *p++)
212 goto mismatch2;
213 return (s - n1);
214
215mismatch2: s += md2; /* md2 shift */
216 }
217
218 return (NULL);
219}
diff --git a/src/lib/libc/string/bstring.3 b/src/lib/libc/string/bstring.3
new file mode 100644
index 0000000000..b553fd0beb
--- /dev/null
+++ b/src/lib/libc/string/bstring.3
@@ -0,0 +1,109 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek.
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.\" $OpenBSD: bstring.3,v 1.2 1996/08/19 08:33:59 tholo Exp $
35.\"
36.Dd April 19, 1991
37.Dt BSTRING 3
38.Os
39.Sh NAME
40.Nm bcmp ,
41.Nm bcopy ,
42.Nm bzero ,
43.Nm memccpy ,
44.Nm memchr ,
45.Nm memcmp ,
46.Nm memcpy ,
47.Nm memmove,
48.Nm memset
49.Nd byte string operations
50.Sh SYNOPSIS
51.Fd #include <string.h>
52.Ft int
53.Fn bcmp "const void *b1" "const void *b2" "size_t len"
54.Ft void
55.Fn bcopy "const void *src" "void *dst" "size_t len"
56.Ft void
57.Fn bzero "void *b" "size_t len"
58.Ft void *
59.Fn memchr "const void *b" "int c" "size_t len"
60.Ft int
61.Fn memcmp "const void *b1" "const void *b2" "size_t len"
62.Ft void *
63.Fn memccpy "void *dst" "const void *src" "int c" "size_t len"
64.Ft void *
65.Fn memcpy "void *dst" "const void *src" "size_t len"
66.Ft void *
67.Fn memmove "void *dst" "const void *src" "size_t len"
68.Ft void *
69.Fn memset "void *b" "int c" "size_t len"
70.Sh DESCRIPTION
71These functions operate on variable length strings of bytes.
72They do not check for terminating null bytes as the routines
73listed in
74.Xr string 3
75do.
76.Pp
77See the specific manual pages for more information.
78.Sh SEE ALSO
79.Xr bcmp 3 ,
80.Xr bcopy 3 ,
81.Xr bzero 3 ,
82.Xr memccpy 3 ,
83.Xr memchr 3 ,
84.Xr memcmp 3 ,
85.Xr memcpy 3 ,
86.Xr memmove 3 ,
87.Xr memset 3
88.Sh STANDARDS
89The functions
90.Fn memchr ,
91.Fn memcmp ,
92.Fn memcpy ,
93.Fn memmove ,
94and
95.Fn memset
96conform to
97.St -ansiC .
98.Sh HISTORY
99The functions
100.Fn bzero
101and
102.Fn memccpy
103appeared in
104.Bx 4.3 ;
105the functions
106.Fn bcmp ,
107.Fn bcopy ,
108appeared in
109.Bx 4.2 .
diff --git a/src/lib/libc/string/bzero.3 b/src/lib/libc/string/bzero.3
new file mode 100644
index 0000000000..a8e55a63c1
--- /dev/null
+++ b/src/lib/libc/string/bzero.3
@@ -0,0 +1,67 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek.
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.\" $OpenBSD: bzero.3,v 1.2 1996/08/19 08:34:00 tholo Exp $
35.\"
36.Dd April 19, 1991
37.Dt BZERO 3
38.Os BSD 4.3
39.Sh NAME
40.Nm bzero
41.Nd write zeroes to a byte string
42.Sh SYNOPSIS
43.Fd #include <string.h>
44.Ft void
45.Fn bzero "void *b" "size_t len"
46.Sh DESCRIPTION
47The
48.Fn bzero
49function
50writes
51.Fa len
52zero bytes to the string
53.Fa b .
54If
55.Fa len
56is zero,
57.Fn bzero
58does nothing.
59.Sh SEE ALSO
60.Xr memset 3 ,
61.Xr swab 3
62.Sh HISTORY
63A
64.Fn bzero
65function
66appeared in
67.Bx 4.3 .
diff --git a/src/lib/libc/string/bzero.c b/src/lib/libc/string/bzero.c
new file mode 100644
index 0000000000..3e660a307f
--- /dev/null
+++ b/src/lib/libc/string/bzero.c
@@ -0,0 +1,56 @@
1/*
2 * Copyright (c) 1987 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: bzero.c,v 1.3 1996/08/19 08:34:00 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#ifndef _KERNEL
39#include <string.h>
40#else
41#include <lib/libkern/libkern.h>
42#endif
43
44/*
45 * bzero -- vax movc5 instruction
46 */
47void
48bzero(b, length)
49 void *b;
50 register size_t length;
51{
52 register char *p;
53
54 for (p = b; length--;)
55 *p++ = '\0';
56}
diff --git a/src/lib/libc/string/ffs.3 b/src/lib/libc/string/ffs.3
new file mode 100644
index 0000000000..9ef08aef8e
--- /dev/null
+++ b/src/lib/libc/string/ffs.3
@@ -0,0 +1,62 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek.
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.\" $OpenBSD: ffs.3,v 1.2 1996/08/19 08:34:01 tholo Exp $
35.\"
36.Dd April 19, 1991
37.Dt FFS 3
38.Os
39.Sh NAME
40.Nm ffs
41.Nd find first bit set in a bit string
42.Sh SYNOPSIS
43.Fd #include <string.h>
44.Ft int
45.Fn ffs "int value"
46.Sh DESCRIPTION
47The
48.Fn ffs
49function
50finds the first bit set in
51.Fa value
52and returns the index of that bit.
53Bits are numbered starting from 1, starting at the right-most
54bit.
55A return value of 0 means that the argument was zero.
56.Sh SEE ALSO
57.Xr bitstring 3
58.Sh HISTORY
59The
60.Fn ffs
61function appeared in
62.Bx 4.3 .
diff --git a/src/lib/libc/string/ffs.c b/src/lib/libc/string/ffs.c
new file mode 100644
index 0000000000..a0767e50ad
--- /dev/null
+++ b/src/lib/libc/string/ffs.c
@@ -0,0 +1,58 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: ffs.c,v 1.3 1996/08/19 08:34:01 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#ifndef _KERNEL
39#include <string.h>
40#else
41#include <lib/libkern/libkern.h>
42#endif
43
44/*
45 * ffs -- vax ffs instruction
46 */
47int
48ffs(mask)
49 register int mask;
50{
51 register int bit;
52
53 if (mask == 0)
54 return(0);
55 for (bit = 1; !(mask & 1); bit++)
56 mask >>= 1;
57 return(bit);
58}
diff --git a/src/lib/libc/string/index.3 b/src/lib/libc/string/index.3
new file mode 100644
index 0000000000..d236a73a48
--- /dev/null
+++ b/src/lib/libc/string/index.3
@@ -0,0 +1,82 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek.
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.\" $OpenBSD: index.3,v 1.4 1997/12/30 01:09:49 deraadt Exp $
35.\"
36.Dd April 19, 1991
37.Dt INDEX 3
38.Os
39.Sh NAME
40.Nm index
41.Nd locate character in string
42.Sh SYNOPSIS
43.Fd #include <string.h>
44.Ft char *
45.Fn index "const char *s" "int c"
46.Sh DESCRIPTION
47The
48.Fn index
49function
50locates the first character matching
51.Fa c
52(converted to a
53.Em char )
54in the null-terminated string
55.Fa s .
56.Sh RETURN VALUES
57If the character
58.Fa c
59is found, a pointer to it is returned; otherwise
60.Dv NULL
61is returned.
62If
63.Fa c
64is '\e0',
65.Fn index
66locates the terminating '\e0'.
67.Sh SEE ALSO
68.Xr memchr 3 ,
69.Xr rindex 3 ,
70.Xr strchr 3 ,
71.Xr strcspn 3 ,
72.Xr strpbrk 3 ,
73.Xr strrchr 3 ,
74.Xr strsep 3 ,
75.Xr strspn 3 ,
76.Xr strstr 3 ,
77.Xr strtok 3
78.Sh HISTORY
79An
80.Fn index
81function appeared in
82.At v6 .
diff --git a/src/lib/libc/string/index.c b/src/lib/libc/string/index.c
new file mode 100644
index 0000000000..86c4e75f12
--- /dev/null
+++ b/src/lib/libc/string/index.c
@@ -0,0 +1,55 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: index.c,v 1.2 1996/08/19 08:34:02 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <string.h>
39
40char *
41#ifdef STRCHR
42strchr(p, ch)
43#else
44index(p, ch)
45#endif
46 register const char *p, ch;
47{
48 for (;; ++p) {
49 if (*p == ch)
50 return((char *)p);
51 if (!*p)
52 return((char *)NULL);
53 }
54 /* NOTREACHED */
55}
diff --git a/src/lib/libc/string/memccpy.3 b/src/lib/libc/string/memccpy.3
new file mode 100644
index 0000000000..c2e15b1405
--- /dev/null
+++ b/src/lib/libc/string/memccpy.3
@@ -0,0 +1,75 @@
1.\" $OpenBSD: memccpy.3,v 1.4 1998/06/15 17:55:09 mickey Exp $
2.\"
3.\" Copyright (c) 1990, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.\" @(#)memccpy.3 8.1 (Berkeley) 6/9/93
35.\"
36.Dd June 9, 1993
37.Dt MEMCCPY 3
38.Os
39.Sh NAME
40.Nm memccpy
41.Nd copy string until character found
42.Sh SYNOPSIS
43.Fd #include <string.h>
44.Ft void *
45.Fn memccpy "void *dst" "const void *src" "int c" "size_t len"
46.Sh DESCRIPTION
47The
48.Fn memccpy
49function
50copies bytes from string
51.Fa src
52to string
53.Fa dst .
54If the character
55.Fa c
56(as converted to an unsigned char) occurs in the string
57.Fa src ,
58the copy stops and a pointer to the byte after the copy of
59.Fa c
60in the string
61.Fa dst
62is returned.
63Otherwise,
64.Fa len
65bytes are copied, and a NULL pointer is returned.
66.Sh SEE ALSO
67.Xr bcopy 3 ,
68.Xr memcpy 3 ,
69.Xr memmove 3 ,
70.Xr strcpy 3
71.Sh HISTORY
72The
73.Fn memccpy
74function first appeared in
75.Bx 4.4 .
diff --git a/src/lib/libc/string/memccpy.c b/src/lib/libc/string/memccpy.c
new file mode 100644
index 0000000000..020e6e5679
--- /dev/null
+++ b/src/lib/libc/string/memccpy.c
@@ -0,0 +1,64 @@
1/* $OpenBSD: memccpy.c,v 1.3 1997/08/20 04:09:39 millert Exp $ */
2
3/*-
4 * Copyright (c) 1990, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36#if defined(LIBC_SCCS) && !defined(lint)
37#if 0
38static char sccsid[] = "@(#)memccpy.c 8.1 (Berkeley) 6/4/93";
39#else
40static char *rcsid = "$OpenBSD: memccpy.c,v 1.3 1997/08/20 04:09:39 millert Exp $";
41#endif
42#endif /* LIBC_SCCS and not lint */
43
44#include <string.h>
45
46void *
47memccpy(t, f, c, n)
48 void *t;
49 const void *f;
50 int c;
51 register size_t n;
52{
53
54 if (n) {
55 register unsigned char *tp = t;
56 register const unsigned char *fp = f;
57 register unsigned char uc = c;
58 do {
59 if ((*tp++ = *fp++) == uc)
60 return (tp);
61 } while (--n != 0);
62 }
63 return (0);
64}
diff --git a/src/lib/libc/string/memchr.3 b/src/lib/libc/string/memchr.3
new file mode 100644
index 0000000000..56a2aee9ce
--- /dev/null
+++ b/src/lib/libc/string/memchr.3
@@ -0,0 +1,81 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: memchr.3,v 1.2 1996/08/19 08:34:04 tholo Exp $
37.\"
38.Dd June 29, 1991
39.Dt MEMCHR 3
40.Os
41.Sh NAME
42.Nm memchr
43.Nd locate byte in byte string
44.Sh SYNOPSIS
45.Fd #include <string.h>
46.Ft void *
47.Fn memchr "const void *b" "int c" "size_t len"
48.Sh DESCRIPTION
49The
50.Fn memchr
51function
52locates the first occurrence of
53.Fa c
54(converted to an unsigned char)
55in string
56.Fa b .
57.Sh RETURN VALUES
58The
59.Fn memchr
60function
61returns a pointer to the byte located,
62or NULL if no such byte exists within
63.Fa len
64bytes.
65.Sh SEE ALSO
66.Xr index 3 ,
67.Xr rindex 3 ,
68.Xr strchr 3 ,
69.Xr strcspn 3 ,
70.Xr strpbrk 3 ,
71.Xr strrchr 3 ,
72.Xr strsep 3 ,
73.Xr strspn 3 ,
74.Xr strstr 3 ,
75.Xr strtok 3
76.Sh STANDARDS
77The
78.Fn memchr
79function
80conforms to
81.St -ansiC .
diff --git a/src/lib/libc/string/memchr.c b/src/lib/libc/string/memchr.c
new file mode 100644
index 0000000000..2ebb5dab32
--- /dev/null
+++ b/src/lib/libc/string/memchr.c
@@ -0,0 +1,58 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Chris Torek.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: memchr.c,v 1.2 1996/08/19 08:34:04 tholo Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#include <string.h>
42
43void *
44memchr(s, c, n)
45 const void *s;
46 register unsigned char c;
47 register size_t n;
48{
49 if (n != 0) {
50 register const unsigned char *p = s;
51
52 do {
53 if (*p++ == c)
54 return ((void *)(p - 1));
55 } while (--n != 0);
56 }
57 return (NULL);
58}
diff --git a/src/lib/libc/string/memcmp.3 b/src/lib/libc/string/memcmp.3
new file mode 100644
index 0000000000..34c5f60861
--- /dev/null
+++ b/src/lib/libc/string/memcmp.3
@@ -0,0 +1,82 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: memcmp.3,v 1.3 1996/12/10 09:06:11 deraadt Exp $
37.\"
38.Dd June 29, 1991
39.Dt MEMCMP 3
40.Os
41.Sh NAME
42.Nm memcmp
43.Nd compare byte string
44.Sh SYNOPSIS
45.Fd #include <string.h>
46.Ft int
47.Fn memcmp "const void *b1" "const void *b2" "size_t len"
48.Sh DESCRIPTION
49The
50.Fn memcmp
51function
52compares byte string
53.Fa b1
54against byte string
55.Fa b2 .
56Both strings are assumed to be
57.Fa len
58bytes long.
59.Sh RETURN VALUES
60The
61.Fn memcmp
62function
63returns zero if the two strings are identical,
64otherwise returns the difference between the first two differing bytes
65(treated as unsigned char values, so that
66.Sq Li \e200
67is greater than
68.Sq Li \&\e0 ,
69for example).
70Zero-length strings are always identical.
71.Sh SEE ALSO
72.Xr bcmp 3 ,
73.Xr strcasecmp 3 ,
74.Xr strcmp 3 ,
75.Xr strcoll 3 ,
76.Xr strxfrm 3
77.Sh STANDARDS
78The
79.Fn memcmp
80function
81conforms to
82.St -ansiC .
diff --git a/src/lib/libc/string/memcmp.c b/src/lib/libc/string/memcmp.c
new file mode 100644
index 0000000000..5ce33e2998
--- /dev/null
+++ b/src/lib/libc/string/memcmp.c
@@ -0,0 +1,60 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Chris Torek.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: memcmp.c,v 1.2 1996/08/19 08:34:05 tholo Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#include <string.h>
42
43/*
44 * Compare memory regions.
45 */
46int
47memcmp(s1, s2, n)
48 const void *s1, *s2;
49 size_t n;
50{
51 if (n != 0) {
52 register const unsigned char *p1 = s1, *p2 = s2;
53
54 do {
55 if (*p1++ != *p2++)
56 return (*--p1 - *--p2);
57 } while (--n != 0);
58 }
59 return (0);
60}
diff --git a/src/lib/libc/string/memcpy.3 b/src/lib/libc/string/memcpy.3
new file mode 100644
index 0000000000..75eb00b2d5
--- /dev/null
+++ b/src/lib/libc/string/memcpy.3
@@ -0,0 +1,83 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: memcpy.3,v 1.2 1996/08/19 08:34:06 tholo Exp $
37.\"
38.Dd June 29, 1991
39.Dt MEMCPY 3
40.Os
41.Sh NAME
42.Nm memcpy
43.Nd copy byte string
44.Sh SYNOPSIS
45.Fd #include <string.h>
46.Ft void *
47.Fn memcpy "void *dst" "const void *src" "size_t len"
48.Sh DESCRIPTION
49The
50.Fn memcpy
51function
52copies
53.Fa len
54bytes from string
55.Fa src
56to string
57.Fa dst .
58.Sh RETURN VALUES
59The
60.Fn memcpy
61function
62returns the original value of
63.Fa dst .
64.Sh SEE ALSO
65.Xr bcopy 3 ,
66.Xr memccpy 3 ,
67.Xr memmove 3 ,
68.Xr strcpy 3
69.Sh STANDARDS
70The
71.Fn memcpy
72function
73conforms to
74.St -ansiC .
75.Sh BUGS
76In this implementation
77.Fn memcpy
78is implemented using
79.Xr bcopy 3 ,
80and therefore the strings may overlap.
81On other systems, copying overlapping strings may produce surprises.
82A simpler solution is to not use
83.Fn memcpy .
diff --git a/src/lib/libc/string/memmove.3 b/src/lib/libc/string/memmove.3
new file mode 100644
index 0000000000..95f6b7596c
--- /dev/null
+++ b/src/lib/libc/string/memmove.3
@@ -0,0 +1,75 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: memmove.3,v 1.2 1996/08/19 08:34:07 tholo Exp $
37.\"
38.Dd June 29, 1991
39.Dt MEMMOVE 3
40.Os
41.Sh NAME
42.Nm memmove
43.Nd copy byte string
44.Sh SYNOPSIS
45.Fd #include <string.h>
46.Ft void *
47.Fn memmove "void *dst" "const void *src" "size_t len"
48.Sh DESCRIPTION
49The
50.Fn memmove
51function
52copies
53.Fa len
54bytes from string
55.Fa src
56to string
57.Fa dst .
58The two strings may overlap;
59the copy is always done in a non-destructive manner.
60.Sh RETURN VALUES
61The
62.Fn memmove
63function returns the original value of
64.Fa dst .
65.Sh SEE ALSO
66.Xr bcopy 3 ,
67.Xr memccpy 3 ,
68.Xr memcpy 3 ,
69.Xr strcpy 3
70.Sh STANDARDS
71The
72.Fn memmove
73function
74conforms to
75.St -ansiC .
diff --git a/src/lib/libc/string/memset.3 b/src/lib/libc/string/memset.3
new file mode 100644
index 0000000000..e1d8583732
--- /dev/null
+++ b/src/lib/libc/string/memset.3
@@ -0,0 +1,72 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: memset.3,v 1.3 1997/08/24 21:56:45 deraadt Exp $
37.\"
38.Dd June 29, 1991
39.Dt MEMSET 3
40.Os
41.Sh NAME
42.Nm memset
43.Nd write a byte to byte string
44.Sh SYNOPSIS
45.Fd #include <string.h>
46.Ft void *
47.Fn memset "void *b" "int c" "size_t len"
48.Sh DESCRIPTION
49The
50.Fn memset
51function
52writes
53.Fa len
54bytes of value
55.Fa c
56(converted to an unsigned char) to the string
57.Fa b .
58.Sh RETURN VALUES
59The
60.Fn memset
61function
62returns the original value of
63.Fa b .
64.Sh SEE ALSO
65.Xr bzero 3 ,
66.Xr swab 3
67.Sh STANDARDS
68The
69.Fn memset
70function
71conforms to
72.St -ansiC .
diff --git a/src/lib/libc/string/memset.c b/src/lib/libc/string/memset.c
new file mode 100644
index 0000000000..c3373a21a9
--- /dev/null
+++ b/src/lib/libc/string/memset.c
@@ -0,0 +1,58 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Chris Torek.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: memset.c,v 1.2 1996/08/19 08:34:07 tholo Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#include <string.h>
42
43void *
44memset(dst, c, n)
45 void *dst;
46 register int c;
47 register size_t n;
48{
49
50 if (n != 0) {
51 register char *d = dst;
52
53 do
54 *d++ = c;
55 while (--n != 0);
56 }
57 return (dst);
58}
diff --git a/src/lib/libc/string/rindex.3 b/src/lib/libc/string/rindex.3
new file mode 100644
index 0000000000..db7f8e1cd8
--- /dev/null
+++ b/src/lib/libc/string/rindex.3
@@ -0,0 +1,80 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek.
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.\" $OpenBSD: rindex.3,v 1.3 1997/12/30 01:09:49 deraadt Exp $
35.\"
36.Dd April 19, 1991
37.Dt RINDEX 3
38.Os
39.Sh NAME
40.Nm rindex
41.Nd locate character in string
42.Sh SYNOPSIS
43.Fd #include <string.h>
44.Ft char *
45.Fn rindex "const char *s" "int c"
46.Sh DESCRIPTION
47The
48.Fn rindex
49function
50locates the last character
51matching
52.Fa c
53(converted to a
54.Em char )
55in the null-terminated string
56.Fa s .
57If the character c is found, a pointer to it is returned; otherwise NULL is returned.
58If
59.Fa c
60is
61.Ql \e0 ,
62.Fn rindex
63locates the terminating
64.Ql \e0 .
65.Sh SEE ALSO
66.Xr index 3 ,
67.Xr memchr 3 ,
68.Xr strchr 3 ,
69.Xr strcspn 3 ,
70.Xr strpbrk 3 ,
71.Xr strrchr 3 ,
72.Xr strsep 3 ,
73.Xr strspn 3 ,
74.Xr strstr 3 ,
75.Xr strtok 3
76.Sh HISTORY
77A
78.Fn rindex
79function appeared in
80.At v6 .
diff --git a/src/lib/libc/string/rindex.c b/src/lib/libc/string/rindex.c
new file mode 100644
index 0000000000..f18553f667
--- /dev/null
+++ b/src/lib/libc/string/rindex.c
@@ -0,0 +1,57 @@
1/*
2 * Copyright (c) 1988 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: rindex.c,v 1.2 1996/08/19 08:34:08 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <string.h>
39
40char *
41#ifdef STRRCHR
42strrchr(p, ch)
43#else
44rindex(p, ch)
45#endif
46 register const char *p, ch;
47{
48 register char *save;
49
50 for (save = NULL;; ++p) {
51 if (*p == ch)
52 save = (char *)p;
53 if (!*p)
54 return(save);
55 }
56 /* NOTREACHED */
57}
diff --git a/src/lib/libc/string/strcasecmp.3 b/src/lib/libc/string/strcasecmp.3
new file mode 100644
index 0000000000..52a13055ee
--- /dev/null
+++ b/src/lib/libc/string/strcasecmp.3
@@ -0,0 +1,89 @@
1.\" $OpenBSD: strcasecmp.3,v 1.4 1998/06/15 17:55:11 mickey Exp $
2.\"
3.\" Copyright (c) 1990, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" This code is derived from software contributed to Berkeley by
7.\" Chris Torek.
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" @(#)strcasecmp.3 8.1 (Berkeley) 6/9/93
37.\"
38.Dd June 9, 1993
39.Dt STRCASECMP 3
40.Os
41.Sh NAME
42.Nm strcasecmp
43.Nd compare strings, ignoring case
44.Sh SYNOPSIS
45.Fd #include <string.h>
46.Ft int
47.Fn strcasecmp "const char *s1" "const char *s2"
48.Ft int
49.Fn strncasecmp "const char *s1" "const char *s2" "size_t len"
50.Sh DESCRIPTION
51The
52.Fn strcasecmp
53and
54.Fn strncasecmp
55functions
56compare the null-terminated strings
57.Fa s1
58and
59.Fa s2
60and return an integer greater than, equal to, or less than 0,
61according as
62.Fa s1
63is lexicographically greater than, equal to, or less than
64.Fa s2
65after translation of each corresponding character to lower-case.
66The strings themselves are not modified.
67The comparison is done using unsigned characters, so that
68.Sq Li \e200
69is greater than
70.Ql \e0 .
71.Pp
72The
73.Fn strncasecmp
74compares at most
75.Fa len
76characters.
77.Sh SEE ALSO
78.Xr bcmp 3 ,
79.Xr memcmp 3 ,
80.Xr strcmp 3 ,
81.Xr strcoll 3 ,
82.Xr strxfrm 3
83.Sh HISTORY
84The
85.Fn strcasecmp
86and
87.Fn strncasecmp
88functions first appeared in
89.Bx 4.4 .
diff --git a/src/lib/libc/string/strcasecmp.c b/src/lib/libc/string/strcasecmp.c
new file mode 100644
index 0000000000..1f487524aa
--- /dev/null
+++ b/src/lib/libc/string/strcasecmp.c
@@ -0,0 +1,120 @@
1/* $OpenBSD: strcasecmp.c,v 1.3 1997/08/20 04:13:57 millert Exp $ */
2
3/*
4 * Copyright (c) 1987, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36#include <string.h>
37
38#if defined(LIBC_SCCS) && !defined(lint)
39#if 0
40static char sccsid[] = "@(#)strcasecmp.c 8.1 (Berkeley) 6/4/93";
41#else
42static char *rcsid = "$OpenBSD: strcasecmp.c,v 1.3 1997/08/20 04:13:57 millert Exp $";
43#endif
44#endif /* LIBC_SCCS and not lint */
45
46typedef unsigned char u_char;
47
48/*
49 * This array is designed for mapping upper and lower case letter
50 * together for a case independent comparison. The mappings are
51 * based upon ascii character sequences.
52 */
53static const u_char charmap[] = {
54 '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
55 '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
56 '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
57 '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
58 '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
59 '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
60 '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
61 '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
62 '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
63 '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
64 '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
65 '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
66 '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
67 '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
68 '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
69 '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
70 '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
71 '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
72 '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
73 '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
74 '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
75 '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
76 '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
77 '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
78 '\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307',
79 '\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317',
80 '\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327',
81 '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337',
82 '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
83 '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
84 '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
85 '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
86};
87
88int
89strcasecmp(s1, s2)
90 const char *s1, *s2;
91{
92 register const u_char *cm = charmap,
93 *us1 = (const u_char *)s1,
94 *us2 = (const u_char *)s2;
95
96 while (cm[*us1] == cm[*us2++])
97 if (*us1++ == '\0')
98 return (0);
99 return (cm[*us1] - cm[*--us2]);
100}
101
102int
103strncasecmp(s1, s2, n)
104 const char *s1, *s2;
105 register size_t n;
106{
107 if (n != 0) {
108 register const u_char *cm = charmap,
109 *us1 = (const u_char *)s1,
110 *us2 = (const u_char *)s2;
111
112 do {
113 if (cm[*us1] != cm[*us2++])
114 return (cm[*us1] - cm[*--us2]);
115 if (*us1++ == '\0')
116 break;
117 } while (--n != 0);
118 }
119 return (0);
120}
diff --git a/src/lib/libc/string/strcat.3 b/src/lib/libc/string/strcat.3
new file mode 100644
index 0000000000..686afd3f2e
--- /dev/null
+++ b/src/lib/libc/string/strcat.3
@@ -0,0 +1,96 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: strcat.3,v 1.3 1997/07/09 00:19:53 millert Exp $
37.\"
38.Dd July 8, 1997
39.Dt STRCAT 3
40.Os
41.Sh NAME
42.Nm strcat
43.Nd concatenate strings
44.Sh SYNOPSIS
45.Fd #include <string.h>
46.Ft char *
47.Fn strcat "char *s" "const char *append"
48.Ft char *
49.Fn strncat "char *s" "const char *append" "size_t count"
50.Sh DESCRIPTION
51The
52.Fn strcat
53and
54.Fn strncat
55functions
56append a copy of the null-terminated string
57.Fa append
58to the end of the null-terminated string
59.Fa s ,
60then add a terminating
61.Ql \e0 .
62The string
63.Fa s
64must have sufficient space to hold the result.
65.Pp
66The
67.Fn strncat
68function
69appends not more than
70.Fa count
71characters where space for the terminating
72.Ql \e0
73should not be included in
74.Fa count .
75.Sh RETURN VALUES
76The
77.Fn strcat
78and
79.Fn strncat
80functions
81return the pointer
82.Fa s .
83.Sh SEE ALSO
84.Xr bcopy 3 ,
85.Xr memccpy 3 ,
86.Xr memcpy 3 ,
87.Xr memmove 3 ,
88.Xr strcpy 3
89.Sh STANDARDS
90The
91.Fn strcat
92and
93.Fn strncat
94functions
95conform to
96.St -ansiC .
diff --git a/src/lib/libc/string/strcat.c b/src/lib/libc/string/strcat.c
new file mode 100644
index 0000000000..374a2b7464
--- /dev/null
+++ b/src/lib/libc/string/strcat.c
@@ -0,0 +1,54 @@
1/*
2 * Copyright (c) 1988 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: strcat.c,v 1.4 1996/08/19 08:34:10 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#ifndef _KERNEL
39#include <string.h>
40#else
41#include <lib/libkern/libkern.h>
42#endif
43
44char *
45strcat(s, append)
46 register char *s;
47 register const char *append;
48{
49 char *save = s;
50
51 for (; *s; ++s);
52 while ((*s++ = *append++) != '\0');
53 return(save);
54}
diff --git a/src/lib/libc/string/strchr.3 b/src/lib/libc/string/strchr.3
new file mode 100644
index 0000000000..c3bc2f8817
--- /dev/null
+++ b/src/lib/libc/string/strchr.3
@@ -0,0 +1,87 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: strchr.3,v 1.3 1997/12/29 22:31:50 deraadt Exp $
37.\"
38.Dd June 29, 1991
39.Dt STRCHR 3
40.Os
41.Sh NAME
42.Nm strchr
43.Nd locate character in string
44.Sh SYNOPSIS
45.Fd #include <string.h>
46.Ft char *
47.Fn strchr "const char *s" "int c"
48.Sh DESCRIPTION
49The
50.Fn strchr
51function locates the first occurrence of
52.Ar c
53in the string pointed to by
54.Ar s .
55The terminating
56.Dv NUL
57character is considered part of the string.
58If
59.Fa c
60is
61.Ql \e0 ,
62.Fn strchr
63locates the terminating
64.Ql \e0 .
65.Sh RETURN VALUES
66The function
67.Fn strchr
68returns a pointer to the located character, or
69.Dv NULL
70if the character does not appear in the string.
71.Sh SEE ALSO
72.Xr index 3 ,
73.Xr memchr 3 ,
74.Xr rindex 3 ,
75.Xr strcspn 3 ,
76.Xr strpbrk 3 ,
77.Xr strrchr 3 ,
78.Xr strsep 3 ,
79.Xr strspn 3 ,
80.Xr strstr 3 ,
81.Xr strtok 3
82.Sh STANDARDS
83The
84.Fn strchr
85function
86conforms to
87.St -ansiC .
diff --git a/src/lib/libc/string/strcmp.3 b/src/lib/libc/string/strcmp.3
new file mode 100644
index 0000000000..91e51d68fc
--- /dev/null
+++ b/src/lib/libc/string/strcmp.3
@@ -0,0 +1,93 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: strcmp.3,v 1.2 1996/08/19 08:34:11 tholo Exp $
37.\"
38.Dd June 29, 1991
39.Dt STRCMP 3
40.Os
41.Sh NAME
42.Nm strcmp
43.Nd compare strings
44.Sh SYNOPSIS
45.Fd #include <string.h>
46.Ft int
47.Fn strcmp "const char *s1" "const char *s2"
48.Ft int
49.Fn strncmp "const char *s1" "const char *s2" "size_t len"
50.Sh DESCRIPTION
51The
52.Fn strcmp
53and
54.Fn strncmp
55functions
56lexicographically compare the null-terminated strings
57.Fa s1
58and
59.Fa s2 .
60.Sh RETURN VALUES
61The
62.Fn strcmp
63and
64.Fn strncmp
65return an integer greater than, equal to, or less than 0, according
66as the string
67.Fa s1
68is greater than, equal to, or less than the string
69.Fa s2 .
70The comparison is done using unsigned characters, so that
71.Ql \e200
72is greater than
73.Ql \e0 .
74.Pp
75The
76.Fn strncmp
77compares not more than
78.Fa len
79characters.
80.Sh SEE ALSO
81.Xr bcmp 3 ,
82.Xr memcmp 3 ,
83.Xr strcasecmp 3 ,
84.Xr strcoll 3 ,
85.Xr strxfrm 3
86.Sh STANDARDS
87The
88.Fn strcmp
89and
90.Fn strncmp
91functions
92conform to
93.St -ansiC .
diff --git a/src/lib/libc/string/strcmp.c b/src/lib/libc/string/strcmp.c
new file mode 100644
index 0000000000..9a5b208323
--- /dev/null
+++ b/src/lib/libc/string/strcmp.c
@@ -0,0 +1,58 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Chris Torek.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: strcmp.c,v 1.3 1996/08/19 08:34:12 tholo Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#ifndef _KERNEL
42#include <string.h>
43#else
44#include <lib/libkern/libkern.h>
45#endif
46
47/*
48 * Compare strings.
49 */
50int
51strcmp(s1, s2)
52 register const char *s1, *s2;
53{
54 while (*s1 == *s2++)
55 if (*s1++ == 0)
56 return (0);
57 return (*(unsigned char *)s1 - *(unsigned char *)--s2);
58}
diff --git a/src/lib/libc/string/strcoll.3 b/src/lib/libc/string/strcoll.3
new file mode 100644
index 0000000000..20af998885
--- /dev/null
+++ b/src/lib/libc/string/strcoll.3
@@ -0,0 +1,74 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: strcoll.3,v 1.2 1996/08/19 08:34:12 tholo Exp $
37.\"
38.Dd June 29, 1991
39.Dt STRCOLL 3
40.Os
41.Sh NAME
42.Nm strcoll
43.Nd compare strings according to current collation
44.Sh SYNOPSIS
45.Fd #include <string.h>
46.Ft int
47.Fn strcoll "const char *s1" "const char *s2"
48.Sh DESCRIPTION
49The
50.Fn strcoll
51function
52lexicographically compares the null-terminated strings
53.Fa s1
54and
55.Fa s2
56according to the current locale collation
57and returns an integer greater than, equal to, or less than 0,
58according as
59.Fa s1
60is greater than, equal to, or less than
61.Fa s2 .
62.Sh SEE ALSO
63.Xr bcmp 3 ,
64.Xr memcmp 3 ,
65.Xr setlocale 3 ,
66.Xr strcasecmp 3 ,
67.Xr strcmp 3 ,
68.Xr strxfrm 3
69.Sh STANDARDS
70The
71.Fn strcoll
72function
73conforms to
74.St -ansiC .
diff --git a/src/lib/libc/string/strcoll.c b/src/lib/libc/string/strcoll.c
new file mode 100644
index 0000000000..dca0b10d25
--- /dev/null
+++ b/src/lib/libc/string/strcoll.c
@@ -0,0 +1,52 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Chris Torek.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: strcoll.c,v 1.2 1996/08/19 08:34:13 tholo Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#include <string.h>
42
43/*
44 * Compare strings according to LC_COLLATE category of current locale.
45 */
46int
47strcoll(s1, s2)
48 const char *s1, *s2;
49{
50 /* LC_COLLATE is unimplemented, hence always "C" */
51 return (strcmp(s1, s2));
52}
diff --git a/src/lib/libc/string/strcpy.3 b/src/lib/libc/string/strcpy.3
new file mode 100644
index 0000000000..33da6e619e
--- /dev/null
+++ b/src/lib/libc/string/strcpy.3
@@ -0,0 +1,121 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: strcpy.3,v 1.2 1996/08/19 08:34:13 tholo Exp $
37.\"
38.Dd June 29, 1991
39.Dt STRCPY 3
40.Os BSD 4
41.Sh NAME
42.Nm strcpy
43.Nd copy strings
44.Sh SYNOPSIS
45.Fd #include <string.h>
46.Ft char *
47.Fn strcpy "char *dst" "const char *src"
48.Ft char *
49.Fn strncpy "char *dst" "const char *src" "size_t len"
50.Sh DESCRIPTION
51The
52.Fn strcpy
53and
54.Fn strncpy
55functions
56copy the string
57.Fa src
58to
59.Fa dst
60(including the terminating
61.Ql \e0
62character).
63.Pp
64The
65.Fn strncpy
66copies not more than
67.Fa len
68characters into
69.Fa dst ,
70appending
71.Ql \e0
72characters if
73.Fa src
74is less than
75.Fa len
76characters long, and
77.Em not
78terminating
79.Fa dst
80if
81.Fa src
82is more than
83.Fa len
84characters long.
85.Sh RETURN VALUES
86The
87.Fn strcpy
88and
89.Fn strncpy
90functions
91return
92.Fa dst .
93.Sh EXAMPLES
94The following sets
95.Dq Li chararray
96to
97.Dq Li abc\e0\e0\e0 :
98.Bd -literal -offset indent
99(void)strncpy(chararray, "abc", 6).
100.Ed
101.Pp
102The following sets
103.Dq Li chararray
104to
105.Dq Li abcdef :
106.Bd -literal -offset indent
107(void)strncpy(chararray, "abcdefgh", 6);
108.Ed
109.Sh SEE ALSO
110.Xr bcopy 3 ,
111.Xr memccpy 3 ,
112.Xr memcpy 3 ,
113.Xr memmove 3
114.Sh STANDARDS
115The
116.Fn strcpy
117and
118.Fn strncpy
119functions
120conform to
121.St -ansiC .
diff --git a/src/lib/libc/string/strcpy.c b/src/lib/libc/string/strcpy.c
new file mode 100644
index 0000000000..76b063fc10
--- /dev/null
+++ b/src/lib/libc/string/strcpy.c
@@ -0,0 +1,53 @@
1/*
2 * Copyright (c) 1988 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: strcpy.c,v 1.4 1996/08/19 08:34:14 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#ifndef _KERNEL
39#include <string.h>
40#else
41#include <lib/libkern/libkern.h>
42#endif
43
44char *
45strcpy(to, from)
46 register char *to;
47 register const char *from;
48{
49 char *save = to;
50
51 for (; (*to = *from) != '\0'; ++from, ++to);
52 return(save);
53}
diff --git a/src/lib/libc/string/strcspn.3 b/src/lib/libc/string/strcspn.3
new file mode 100644
index 0000000000..93c6d8f84c
--- /dev/null
+++ b/src/lib/libc/string/strcspn.3
@@ -0,0 +1,84 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: strcspn.3,v 1.2 1996/08/19 08:34:14 tholo Exp $
37.\"
38.Dd June 29, 1991
39.Dt STRCSPN 3
40.Os
41.Sh NAME
42.Nm strcspn
43.Nd span the complement of a string
44.Sh SYNOPSIS
45.Fd #include <string.h>
46.Ft size_t
47.Fn strcspn "const char *s" "const char *charset"
48.Sh DESCRIPTION
49The
50.Fn strcspn
51function
52spans the initial part of the null-terminated string
53.Fa s
54as long as the characters from
55.Fa s
56do not occur in string
57.Fa charset
58(it
59spans the
60.Em complement
61of
62.Fa charset ) .
63.Sh RETURN VALUES
64The
65.Fn strcspn
66function
67returns the number of characters spanned.
68.Sh SEE ALSO
69.Xr index 3 ,
70.Xr memchr 3 ,
71.Xr rindex 3 ,
72.Xr strchr 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 STANDARDS
80The
81.Fn strcspn
82function
83conforms to
84.St -ansiC .
diff --git a/src/lib/libc/string/strcspn.c b/src/lib/libc/string/strcspn.c
new file mode 100644
index 0000000000..f7261564a7
--- /dev/null
+++ b/src/lib/libc/string/strcspn.c
@@ -0,0 +1,67 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Chris Torek.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: strcspn.c,v 1.2 1996/08/19 08:34:15 tholo Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#include <string.h>
42
43/*
44 * Span the complement of string s2.
45 */
46size_t
47strcspn(s1, s2)
48 const char *s1;
49 register const char *s2;
50{
51 register const char *p, *spanp;
52 register char c, sc;
53
54 /*
55 * Stop as soon as we find any character from s2. Note that there
56 * must be a NUL in s2; it suffices to stop when we find that, too.
57 */
58 for (p = s1;;) {
59 c = *p++;
60 spanp = s2;
61 do {
62 if ((sc = *spanp++) == c)
63 return (p - 1 - s1);
64 } while (sc != 0);
65 }
66 /* NOTREACHED */
67}
diff --git a/src/lib/libc/string/strdup.3 b/src/lib/libc/string/strdup.3
new file mode 100644
index 0000000000..6abbba57cb
--- /dev/null
+++ b/src/lib/libc/string/strdup.3
@@ -0,0 +1,68 @@
1.\" $OpenBSD: strdup.3,v 1.6 1998/08/19 05:51:14 pjanzen Exp $
2.\"
3.\" Copyright (c) 1990, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.\" @(#)strdup.3 8.1 (Berkeley) 6/9/93
35.\"
36.Dd June 9, 1993
37.Dt STRDUP 3
38.Os
39.Sh NAME
40.Nm strdup
41.Nd save a copy of a string
42.Sh SYNOPSIS
43.Fd #include <string.h>
44.Ft char *
45.Fn strdup "const char *str"
46.Sh DESCRIPTION
47The
48.Fn strdup
49function
50allocates sufficient memory for a copy
51of the string
52.Fa str ,
53does the copy, and returns a pointer to it.
54The pointer may subsequently be used as an
55argument to the function
56.Xr free 3 .
57.Pp
58If insufficient memory is available, NULL is returned.
59.Sh SEE ALSO
60.Xr free 3 ,
61.Xr malloc 3 ,
62.Xr strcpy 3 ,
63.Xr strlen 3
64.Sh HISTORY
65The
66.Fn strdup
67function first appeared in
68.Bx 4.4 .
diff --git a/src/lib/libc/string/strdup.c b/src/lib/libc/string/strdup.c
new file mode 100644
index 0000000000..be7f7ad094
--- /dev/null
+++ b/src/lib/libc/string/strdup.c
@@ -0,0 +1,62 @@
1/* $OpenBSD: strdup.c,v 1.3 1997/08/20 04:18:52 millert Exp $ */
2
3/*
4 * Copyright (c) 1988, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36#if defined(LIBC_SCCS) && !defined(lint)
37#if 0
38static char sccsid[] = "@(#)strdup.c 8.1 (Berkeley) 6/4/93";
39#else
40static char *rcsid = "$OpenBSD: strdup.c,v 1.3 1997/08/20 04:18:52 millert Exp $";
41#endif
42#endif /* LIBC_SCCS and not lint */
43
44#include <sys/types.h>
45
46#include <stddef.h>
47#include <stdlib.h>
48#include <string.h>
49
50char *
51strdup(str)
52 const char *str;
53{
54 size_t siz;
55 char *copy;
56
57 siz = strlen(str) + 1;
58 if ((copy = malloc(siz)) == NULL)
59 return(NULL);
60 (void)memcpy(copy, str, siz);
61 return(copy);
62}
diff --git a/src/lib/libc/string/strerror.3 b/src/lib/libc/string/strerror.3
new file mode 100644
index 0000000000..487c2b0e9f
--- /dev/null
+++ b/src/lib/libc/string/strerror.3
@@ -0,0 +1,65 @@
1.\" Copyright (c) 1980, 1991 Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: strerror.3,v 1.2 1996/08/19 08:34:16 tholo Exp $
37.\"
38.Dd June 29, 1991
39.Dt STRERROR 3
40.Os BSD 4
41.Sh NAME
42.Nm strerror
43.Nd get error message string
44.Sh SYNOPSIS
45.Fd #include <string.h>
46.Ft char *
47.Fn strerror "int errnum"
48.Sh DESCRIPTION
49The
50.Fn strerror
51function returns a pointer to the language-dependent error message
52string affiliated with an error number.
53.Pp
54The array pointed to is not to be modified by the program, but may be
55overwritten by subsequent calls to
56.Fn strerror .
57.Sh SEE ALSO
58.Xr intro 2 ,
59.Xr perror 3 ,
60.Xr setlocale 3
61.Sh STANDARDS
62The
63.Fn strerror
64function conforms to
65.St -ansiC .
diff --git a/src/lib/libc/string/strerror.c b/src/lib/libc/string/strerror.c
new file mode 100644
index 0000000000..0e2690c3dd
--- /dev/null
+++ b/src/lib/libc/string/strerror.c
@@ -0,0 +1,55 @@
1/*
2 * Copyright (c) 1988 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: strerror.c,v 1.2 1996/08/19 08:34:17 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <string.h>
39#include <limits.h>
40
41/*
42 * Since perror() is not allowed to change the contents of strerror()'s
43 * static buffer, both functions supply their own buffers to the
44 * internal function __strerror().
45 */
46
47extern char *__strerror __P((int, char *));
48
49char *
50strerror(num)
51 int num;
52{
53 static char buf[NL_TEXTMAX];
54 return __strerror(num, buf);
55}
diff --git a/src/lib/libc/string/string.3 b/src/lib/libc/string/string.3
new file mode 100644
index 0000000000..323d4f3040
--- /dev/null
+++ b/src/lib/libc/string/string.3
@@ -0,0 +1,155 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek.
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.\" $OpenBSD: string.3,v 1.3 1998/09/06 22:23:18 aaron Exp $
35.\"
36.Dd April 19, 1991
37.Dt STRING 3
38.Os BSD 4
39.Sh NAME
40.Nm strcat ,
41.Nm strncat ,
42.Nm strchr ,
43.Nm strrchr ,
44.Nm strcmp ,
45.Nm strncmp ,
46.Nm strcasecmp,
47.Nm strncasecmp ,
48.Nm strcpy ,
49.Nm strncpy ,
50.Nm strerror ,
51.Nm strlen ,
52.Nm strpbrk ,
53.Nm strsep,
54.Nm strspn ,
55.Nm strcspn ,
56.Nm strstr ,
57.Nm strtok ,
58.Nm index ,
59.Nm rindex
60.Nd string specific functions
61.Sh SYNOPSIS
62.Fd #include <string.h>
63.Ft char *
64.Fn strcat "char *s" "const char * append"
65.Ft char *
66.Fn strncat "char *s" "const char *append" "size_t count"
67.Ft char *
68.Fn strchr "const char *s" "int c"
69.Ft char *
70.Fn strrchr "const char *s" "int c"
71.Ft int
72.Fn strcmp "const char *s1" "const char *s2"
73.Ft int
74.Fn strncmp "const char *s1" "const char *s2" "size_t count"
75.Ft int
76.Fn strcasecmp "const char *s1" "const char *s2"
77.Ft int
78.Fn strncasecmp "const char *s1" "const char *s2" "size_t count"
79.Ft char *
80.Fn strcpy "char *dst" "const char *src"
81.Ft char *
82.Fn strncpy "char *dst" "const char *src" "size_t count"
83.Ft char *
84.Fn strerror "int errno"
85.Ft size_t
86.Fn strlen "const char *s"
87.Ft char *
88.Fn strpbrk "const char *s" "const char *charset"
89.Ft char *
90.Fn strsep "char **stringp" "const char *delim"
91.Ft size_t
92.Fn strspn "const char *s" "const char *charset"
93.Ft size_t
94.Fn strcspn "const char *s" "const char *charset"
95.Ft char *
96.Fn strstr "const char *big" "const char *little"
97.Ft char *
98.Fn strtok "char *s" "const char *delim"
99.Ft char *
100.Fn index "const char *s" "int c"
101.Ft char *
102.Fn rindex "const char *s" "int c"
103.Sh DESCRIPTION
104The string functions
105manipulate strings terminated by a
106null byte.
107.Pp
108See the specific manual pages for more information.
109For manipulating variable length generic objects as byte
110strings (without the null byte check), see
111.Xr bstring 3 .
112.Pp
113Except as noted in their specific manual pages,
114the string functions do not test the destination
115for size limitations.
116.Sh SEE ALSO
117.Xr index 3 ,
118.Xr strcat 3 ,
119.Xr strchr 3 ,
120.Xr strrchr 3 ,
121.Xr strcmp 3 ,
122.Xr strcasecmp 3 ,
123.Xr strcpy 3 ,
124.Xr strerror 3 ,
125.Xr strlen 3 ,
126.Xr strpbrk 3 ,
127.Xr strsep 3 ,
128.Xr strspn 3 ,
129.Xr strcspn 3 ,
130.Xr strstr 3 ,
131.Xr strtok 3 ,
132.Xr rindex 3
133.Xr bstring 3
134.Sh STANDARDS
135The
136.Fn strcat ,
137.Fn strncat ,
138.Fn strchr ,
139.Fn strrchr ,
140.Fn strcmp ,
141.Fn strncmp ,
142.Fn strcpy ,
143.Fn strncpy ,
144.Fn strerror ,
145.Fn strlen ,
146.Fn strpbrk ,
147.Fn strsep ,
148.Fn strspn ,
149.Fn strcspn ,
150.Fn strstr ,
151and
152.Fn strtok
153functions
154conform to
155.St -ansiC .
diff --git a/src/lib/libc/string/strlcat.c b/src/lib/libc/string/strlcat.c
new file mode 100644
index 0000000000..2e8c56926e
--- /dev/null
+++ b/src/lib/libc/string/strlcat.c
@@ -0,0 +1,71 @@
1/* $OpenBSD: strlcat.c,v 1.1 1998/07/01 01:29:45 millert Exp $ */
2
3/*
4 * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
19 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
20 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#if defined(LIBC_SCCS) && !defined(lint)
31static char *rcsid = "$OpenBSD: strlcat.c,v 1.1 1998/07/01 01:29:45 millert Exp $";
32#endif /* LIBC_SCCS and not lint */
33
34#include <sys/types.h>
35#include <string.h>
36
37/*
38 * Appends src to string dst of size siz (unlike strncat, siz is the
39 * full size of dst, not space left). At most siz-1 characters
40 * will be copied. Always NUL terminates (unless siz == 0).
41 * Returns strlen(src); if retval >= siz, truncation occurred.
42 */
43size_t strlcat(dst, src, siz)
44 char *dst;
45 const char *src;
46 size_t siz;
47{
48 register char *d = dst;
49 register const char *s = src;
50 register size_t n = siz;
51 size_t dlen;
52
53 /* Find the end of dst and adjust bytes left */
54 while (*d != '\0' && n != 0)
55 d++;
56 dlen = d - dst;
57 n -= dlen;
58
59 if (n == 0)
60 return(dlen + strlen(s));
61 while (*s != '\0') {
62 if (n != 1) {
63 *d++ = *s;
64 n--;
65 }
66 s++;
67 }
68 *d = '\0';
69
70 return(dlen + (s - src)); /* count does not include NUL */
71}
diff --git a/src/lib/libc/string/strlcpy.3 b/src/lib/libc/string/strlcpy.3
new file mode 100644
index 0000000000..5ce444d6fa
--- /dev/null
+++ b/src/lib/libc/string/strlcpy.3
@@ -0,0 +1,140 @@
1.\" $OpenBSD: strlcpy.3,v 1.2 1998/07/06 19:17:21 millert Exp $
2.\"
3.\" Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
4.\" All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. The name of the author may not be used to endorse or promote products
15.\" derived from this software without specific prior written permission.
16.\"
17.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
19.\" AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
20.\" THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21.\" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22.\" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23.\" OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27.\"
28.Dd June 22, 1998
29.Dt STRLCPY 3
30.Os
31.Sh NAME
32.Nm strlcpy,
33.Nm strlcat
34.Nd size-bounded string copying and concatenation
35.Sh SYNOPSIS
36.Fd #include <string.h>
37.Ft size_t
38.Fn strlcpy "char *dst" "const char *src" "size_t size"
39.Ft size_t
40.Fn strlcat "char *dst" "const char *src" "size_t size"
41.Sh DESCRIPTION
42The
43.Fn strlcpy
44and
45.Fn strlcat
46functions copy and concatenate strings respectively. They are designed
47to be safer, more consistent, and less error prone replacements for
48.Xr strncpy 3
49and
50.Xr strncat 3 .
51Unlike those functions,
52.Fn strlcpy
53and
54.Fn strlcat
55take the full size of the buffer (not just the length) and guarantee to
56NUL-terminate the result (as long as
57.Fa size
58is larger than 0). Note that you should include a byte for the NUL in
59.Fa size .
60.Pp
61The
62.Fn strlcpy
63function copies up to
64.Fa size
65- 1 characters from the NUL-terminated string
66.Fa src
67to
68.Fa dst ,
69NUL-terminating the result.
70.Pp
71The
72.Fn strlcat
73function appends the NUL-terminated string
74.Fa src
75to the end of
76.Fa dst .
77It will append at most
78.Fa size
79- strlen(dst) - 1 bytes, NUL-terminating the result.
80.Sh RETURN VALUES
81The
82.Fn strlcpy
83and
84.Fn strlcat
85functions return the total length of the string they tried to
86create. For
87.Fn strlcpy
88that means the length of
89.Fa src .
90For
91.Fn strlcat
92that means the initial length of
93.Fa dst
94plus
95the length of
96.Fa src .
97While this may seem somewhat confusing it was done to make
98truncation detection simple.
99.Sh EXAMPLES
100The following code fragment illustrates the simple case:
101.Bd -literal -offset indent
102char *s, *p, buf[BUFSIZ];
103
104.Li ...
105
106(void)strlcpy(buf, s, sizeof(buf));
107(void)strlcat(buf, p, sizeof(buf));
108.Ed
109.Pp
110To detect truncation, perhaps while building a pathname, something
111like the following might be used:
112.Bd -literal -offset indent
113char *dir, *file, pname[MAXPATHNAMELEN];
114
115.Li ...
116
117if (strlcpy(pname, dir, sizeof(pname)) >= sizeof(pname))
118 goto toolong;
119if (strlcat(pname, file, sizeof(pname)) >= sizeof(pname))
120 goto toolong;
121.Ed
122.Pp
123Since we know how many characters we copied the first time, we can
124speed things up a bit by using a copy instead on an append:
125.Bd -literal -offset indent
126char *dir, *file, pname[MAXPATHNAMELEN];
127size_t n;
128
129.Li ...
130
131n = strlcpy(pname, dir, sizeof(pname));
132if (n >= sizeof(pname))
133 goto toolong;
134if (strlcpy(pname + n, file, sizeof(pname)) >= sizeof(pname) - n)
135 goto toolong;
136.Ed
137.Sh SEE ALSO
138.Xr snprintf 3 ,
139.Xr strncpy 3 ,
140.Xr strncat 3
diff --git a/src/lib/libc/string/strlcpy.c b/src/lib/libc/string/strlcpy.c
new file mode 100644
index 0000000000..1a60445599
--- /dev/null
+++ b/src/lib/libc/string/strlcpy.c
@@ -0,0 +1,63 @@
1/* $OpenBSD: strlcpy.c,v 1.1 1998/07/01 01:29:45 millert Exp $ */
2
3/*
4 * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
19 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
20 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#if defined(LIBC_SCCS) && !defined(lint)
31static char *rcsid = "$OpenBSD: strlcpy.c,v 1.1 1998/07/01 01:29:45 millert Exp $";
32#endif /* LIBC_SCCS and not lint */
33
34#include <sys/types.h>
35#include <string.h>
36
37/*
38 * Copy src to string dst of size siz. At most siz-1 characters
39 * will be copied. Always NUL terminates (unless siz == 0).
40 * Returns strlen(src); if retval >= siz, truncation occurred.
41 */
42size_t strlcpy(dst, src, siz)
43 char *dst;
44 char *src;
45 size_t siz;
46{
47 register char *d = dst;
48 register const char *s = src;
49 register size_t n = siz;
50
51 if (n == 0)
52 return(strlen(s));
53 while (*s != '\0') {
54 if (n != 1) {
55 *d++ = *s;
56 n--;
57 }
58 s++;
59 }
60 *d = '\0';
61
62 return(s - src); /* count does not include NUL */
63}
diff --git a/src/lib/libc/string/strlen.3 b/src/lib/libc/string/strlen.3
new file mode 100644
index 0000000000..99e7dd19c3
--- /dev/null
+++ b/src/lib/libc/string/strlen.3
@@ -0,0 +1,70 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: strlen.3,v 1.2 1996/08/19 08:34:19 tholo Exp $
37.\"
38.Dd June 29, 1991
39.Dt STRLEN 3
40.Os
41.Sh NAME
42.Nm strlen
43.Nd find length of string
44.Sh SYNOPSIS
45.Fd #include <string.h>
46.Ft size_t
47.Fn strlen "const char *s"
48.Sh DESCRIPTION
49The
50.Fn strlen
51function
52computes the length of the string
53.Fa s .
54.Sh RETURN VALUES
55The
56.Fn strlen
57function
58returns
59the number of characters that precede the
60terminating
61.Dv NUL
62character.
63.Sh SEE ALSO
64.Xr string 3
65.Sh STANDARDS
66The
67.Fn strlen
68function
69conforms to
70.St -ansiC .
diff --git a/src/lib/libc/string/strlen.c b/src/lib/libc/string/strlen.c
new file mode 100644
index 0000000000..332d5766f9
--- /dev/null
+++ b/src/lib/libc/string/strlen.c
@@ -0,0 +1,53 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: strlen.c,v 1.3 1996/08/19 08:34:19 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#ifndef _KERNEL
39#include <string.h>
40#else
41#include <lib/libkern/libkern.h>
42#endif
43
44size_t
45strlen(str)
46 const char *str;
47{
48 register const char *s;
49
50 for (s = str; *s; ++s);
51 return(s - str);
52}
53
diff --git a/src/lib/libc/string/strmode.3 b/src/lib/libc/string/strmode.3
new file mode 100644
index 0000000000..3db953704d
--- /dev/null
+++ b/src/lib/libc/string/strmode.3
@@ -0,0 +1,152 @@
1.\" $OpenBSD: strmode.3,v 1.6 1998/06/15 17:55:13 mickey Exp $
2.\"
3.\" Copyright (c) 1990, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.\" @(#)strmode.3 8.3 (Berkeley) 7/28/94
35.\"
36.Dd July 28, 1994
37.Dt STRMODE 3
38.Os
39.Sh NAME
40.Nm strmode
41.Nd convert inode status information into a symbolic string
42.Sh SYNOPSIS
43.Fd #include <string.h>
44.Ft void
45.Fn strmode "mode_t mode" "char *bp"
46.Sh DESCRIPTION
47The
48.Fn strmode
49function
50converts a file
51.Fa mode
52(the type and permission information associated with an inode, see
53.Xr stat 2 )
54into a symbolic string which is stored in the location referenced by
55.Fa bp .
56This stored string is eleven characters in length plus a trailing
57.Dv NUL .
58.Pp
59The first character is the inode type, and will be one of the following:
60.Pp
61.Bl -tag -width flag -offset indent -compact
62.It \-
63regular file
64.It b
65block special
66.It c
67character special
68.It d
69directory
70.It l
71symbolic link
72.It p
73fifo
74.It s
75socket
76.It w
77whiteout
78.It ?
79unknown inode type
80.El
81.Pp
82The next nine characters encode three sets of permissions, in three
83characters each.
84The first three characters are the permissions for the owner of the
85file, the second three for the group the file belongs to, and the
86third for the ``other'', or default, set of users.
87.Pp
88Permission checking is done as specifically as possible.
89If read permission is denied to the owner of a file in the first set
90of permissions, the owner of the file will not be able to read the file.
91This is true even if the owner is in the file's group and the group
92permissions allow reading or the ``other'' permissions allow reading.
93.Pp
94If the first character of the three character set is an ``r'', the file is
95readable for that set of users; if a dash ``\-'', it is not readable.
96.Pp
97If the second character of the three character set is a ``w'', the file is
98writable for that set of users; if a dash ``\-'', it is not writable.
99.Pp
100The third character is the first of the following characters that apply:
101.Bl -tag -width xxxx
102.It S
103If the character is part of the owner permissions and the file is not
104executable or the directory is not searchable by the owner, and the
105set-user-id bit is set.
106.It S
107If the character is part of the group permissions and the file is not
108executable or the directory is not searchable by the group, and the
109set-group-id bit is set.
110.It T
111If the character is part of the other permissions and the file is not
112executable or the directory is not searchable by others, and the ``sticky''
113.Pq Dv S_ISVTX
114bit is set.
115.It s
116If the character is part of the owner permissions and the file is
117executable or the directory searchable by the owner, and the set-user-id
118bit is set.
119.It s
120If the character is part of the group permissions and the file is
121executable or the directory searchable by the group, and the set-group-id
122bit is set.
123.It t
124If the character is part of the other permissions and the file is
125executable or the directory searchable by others, and the ``sticky''
126.Pq Dv S_ISVTX
127bit is set.
128.It x
129The file is executable or the directory is searchable.
130.It \-
131None of the above apply.
132.El
133.Pp
134The last character is a plus sign ``+'' if there are any alternate
135or additional access control methods associated with the inode, otherwise
136it will be a space.
137.Sh RETURN VALUES
138The
139.Fn strmode
140function
141always returns 0.
142.Sh SEE ALSO
143.Xr chmod 1 ,
144.Xr find 1 ,
145.Xr stat 2 ,
146.Xr getmode 3 ,
147.Xr setmode 3
148.Sh HISTORY
149The
150.Fn strmode
151function first appeared in
152.Bx 4.4 .
diff --git a/src/lib/libc/string/strmode.c b/src/lib/libc/string/strmode.c
new file mode 100644
index 0000000000..5e7f15e857
--- /dev/null
+++ b/src/lib/libc/string/strmode.c
@@ -0,0 +1,152 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: strmode.c,v 1.3 1997/06/13 13:57:20 deraadt Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/types.h>
39#include <sys/stat.h>
40#include <string.h>
41
42void
43strmode(mode, p)
44 register mode_t mode;
45 register char *p;
46{
47 /* print type */
48 switch (mode & S_IFMT) {
49 case S_IFDIR: /* directory */
50 *p++ = 'd';
51 break;
52 case S_IFCHR: /* character special */
53 *p++ = 'c';
54 break;
55 case S_IFBLK: /* block special */
56 *p++ = 'b';
57 break;
58 case S_IFREG: /* regular */
59 *p++ = '-';
60 break;
61 case S_IFLNK: /* symbolic link */
62 *p++ = 'l';
63 break;
64 case S_IFSOCK: /* socket */
65 *p++ = 's';
66 break;
67#ifdef S_IFIFO
68 case S_IFIFO: /* fifo */
69 *p++ = 'p';
70 break;
71#endif
72#ifdef S_IFWHT
73 case S_IFWHT: /* whiteout */
74 *p++ = 'w';
75 break;
76#endif
77 default: /* unknown */
78 *p++ = '?';
79 break;
80 }
81 /* usr */
82 if (mode & S_IRUSR)
83 *p++ = 'r';
84 else
85 *p++ = '-';
86 if (mode & S_IWUSR)
87 *p++ = 'w';
88 else
89 *p++ = '-';
90 switch (mode & (S_IXUSR | S_ISUID)) {
91 case 0:
92 *p++ = '-';
93 break;
94 case S_IXUSR:
95 *p++ = 'x';
96 break;
97 case S_ISUID:
98 *p++ = 'S';
99 break;
100 case S_IXUSR | S_ISUID:
101 *p++ = 's';
102 break;
103 }
104 /* group */
105 if (mode & S_IRGRP)
106 *p++ = 'r';
107 else
108 *p++ = '-';
109 if (mode & S_IWGRP)
110 *p++ = 'w';
111 else
112 *p++ = '-';
113 switch (mode & (S_IXGRP | S_ISGID)) {
114 case 0:
115 *p++ = '-';
116 break;
117 case S_IXGRP:
118 *p++ = 'x';
119 break;
120 case S_ISGID:
121 *p++ = 'S';
122 break;
123 case S_IXGRP | S_ISGID:
124 *p++ = 's';
125 break;
126 }
127 /* other */
128 if (mode & S_IROTH)
129 *p++ = 'r';
130 else
131 *p++ = '-';
132 if (mode & S_IWOTH)
133 *p++ = 'w';
134 else
135 *p++ = '-';
136 switch (mode & (S_IXOTH | S_ISVTX)) {
137 case 0:
138 *p++ = '-';
139 break;
140 case S_IXOTH:
141 *p++ = 'x';
142 break;
143 case S_ISVTX:
144 *p++ = 'T';
145 break;
146 case S_IXOTH | S_ISVTX:
147 *p++ = 't';
148 break;
149 }
150 *p++ = ' '; /* will be a '+' if ACL's implemented */
151 *p = '\0';
152}
diff --git a/src/lib/libc/string/strncat.c b/src/lib/libc/string/strncat.c
new file mode 100644
index 0000000000..27ae2ba324
--- /dev/null
+++ b/src/lib/libc/string/strncat.c
@@ -0,0 +1,67 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Chris Torek.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: strncat.c,v 1.2 1996/08/19 08:34:21 tholo Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#include <string.h>
42
43/*
44 * Concatenate src on the end of dst. At most strlen(dst)+n+1 bytes
45 * are written at dst (at most n+1 bytes being appended). Return dst.
46 */
47char *
48strncat(dst, src, n)
49 char *dst;
50 const char *src;
51 register size_t n;
52{
53 if (n != 0) {
54 register char *d = dst;
55 register const char *s = src;
56
57 while (*d != 0)
58 d++;
59 do {
60 if ((*d = *s++) == 0)
61 break;
62 d++;
63 } while (--n != 0);
64 *d = 0;
65 }
66 return (dst);
67}
diff --git a/src/lib/libc/string/strncmp.c b/src/lib/libc/string/strncmp.c
new file mode 100644
index 0000000000..0224957f8b
--- /dev/null
+++ b/src/lib/libc/string/strncmp.c
@@ -0,0 +1,59 @@
1/*
2 * Copyright (c) 1989 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: strncmp.c,v 1.3 1996/08/19 08:34:21 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#ifndef _KERNEL
39#include <string.h>
40#else
41#include <lib/libkern/libkern.h>
42#endif
43
44int
45strncmp(s1, s2, n)
46 register const char *s1, *s2;
47 register size_t n;
48{
49
50 if (n == 0)
51 return (0);
52 do {
53 if (*s1 != *s2++)
54 return (*(unsigned char *)s1 - *(unsigned char *)--s2);
55 if (*s1++ == 0)
56 break;
57 } while (--n != 0);
58 return (0);
59}
diff --git a/src/lib/libc/string/strncpy.c b/src/lib/libc/string/strncpy.c
new file mode 100644
index 0000000000..01bc8a872e
--- /dev/null
+++ b/src/lib/libc/string/strncpy.c
@@ -0,0 +1,67 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Chris Torek.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: strncpy.c,v 1.2 1996/08/19 08:34:22 tholo Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#include <string.h>
42
43/*
44 * Copy src to dst, truncating or null-padding to always copy n bytes.
45 * Return dst.
46 */
47char *
48strncpy(dst, src, n)
49 char *dst;
50 const char *src;
51 register size_t n;
52{
53 if (n != 0) {
54 register char *d = dst;
55 register const char *s = src;
56
57 do {
58 if ((*d++ = *s++) == 0) {
59 /* NUL pad the remaining n-1 bytes */
60 while (--n != 0)
61 *d++ = 0;
62 break;
63 }
64 } while (--n != 0);
65 }
66 return (dst);
67}
diff --git a/src/lib/libc/string/strpbrk.3 b/src/lib/libc/string/strpbrk.3
new file mode 100644
index 0000000000..5876f560a9
--- /dev/null
+++ b/src/lib/libc/string/strpbrk.3
@@ -0,0 +1,79 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: strpbrk.3,v 1.2 1996/08/19 08:34:22 tholo Exp $
37.\"
38.Dd June 29, 1991
39.Dt STRPBRK 3
40.Os
41.Sh NAME
42.Nm strpbrk
43.Nd locate multiple characters in string
44.Sh SYNOPSIS
45.Fd #include <string.h>
46.Ft char *
47.Fn strpbrk "const char *s" "const char *charset"
48.Sh DESCRIPTION
49The
50.Fn strpbrk
51function
52locates in the null-terminated string
53.Fa s
54the first occurrence of any character in the string
55.Fa charset
56and returns a pointer to this character.
57If no characters from
58.Fa charset
59occur anywhere in
60.Fa s
61.Fn strpbrk
62returns NULL.
63.Sh SEE ALSO
64.Xr index 3 ,
65.Xr memchr 3 ,
66.Xr rindex 3 ,
67.Xr strchr 3 ,
68.Xr strcspn 3 ,
69.Xr strrchr 3 ,
70.Xr strsep 3 ,
71.Xr strspn 3 ,
72.Xr strstr 3 ,
73.Xr strtok 3
74.Sh STANDARDS
75The
76.Fn strpbrk
77function
78conforms to
79.St -ansiC .
diff --git a/src/lib/libc/string/strpbrk.c b/src/lib/libc/string/strpbrk.c
new file mode 100644
index 0000000000..748a3a8c94
--- /dev/null
+++ b/src/lib/libc/string/strpbrk.c
@@ -0,0 +1,56 @@
1/*
2 * Copyright (c) 1985 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: strpbrk.c,v 1.2 1996/08/19 08:34:23 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <string.h>
39
40/*
41 * Find the first occurrence in s1 of a character in s2 (excluding NUL).
42 */
43char *
44strpbrk(s1, s2)
45 register const char *s1, *s2;
46{
47 register const char *scanp;
48 register int c, sc;
49
50 while ((c = *s1++) != 0) {
51 for (scanp = s2; (sc = *scanp++) != 0;)
52 if (sc == c)
53 return ((char *)(s1 - 1));
54 }
55 return (NULL);
56}
diff --git a/src/lib/libc/string/strrchr.3 b/src/lib/libc/string/strrchr.3
new file mode 100644
index 0000000000..6dd00d32fb
--- /dev/null
+++ b/src/lib/libc/string/strrchr.3
@@ -0,0 +1,90 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: strrchr.3,v 1.2 1996/08/19 08:34:23 tholo Exp $
37.\"
38.Dd June 29, 1991
39.Dt STRRCHR 3
40.Os
41.Sh NAME
42.Nm strrchr
43.Nd locate character in string
44.Sh SYNOPSIS
45.Fd #include <string.h>
46.Ft char *
47.Fn strrchr "const char *s" "int c"
48.Sh DESCRIPTION
49The
50.Fn strrchr
51function
52locates the last occurrence of
53.Fa c
54(converted to a char)
55in the string
56.Fa s .
57If
58.Fa c
59is
60.Ql \e0 ,
61.Fn strrchr
62locates the terminating
63.Ql \e0 .
64.Sh RETURN VALUES
65The
66.Fn strrchr
67function
68returns a pointer to the character,
69or a null
70pointer if
71.Fa c
72does not occur anywhere in
73.Fa s .
74.Sh SEE ALSO
75.Xr index 3 ,
76.Xr memchr 3 ,
77.Xr rindex 3 ,
78.Xr strchr 3 ,
79.Xr strcspn 3 ,
80.Xr strpbrk 3 ,
81.Xr strsep 3 ,
82.Xr strspn 3 ,
83.Xr strstr 3 ,
84.Xr strtok 3
85.Sh STANDARDS
86The
87.Fn strrchr
88function
89conforms to
90.St -ansiC .
diff --git a/src/lib/libc/string/strsep.3 b/src/lib/libc/string/strsep.3
new file mode 100644
index 0000000000..5af262a074
--- /dev/null
+++ b/src/lib/libc/string/strsep.3
@@ -0,0 +1,110 @@
1.\" $OpenBSD: strsep.3,v 1.4 1998/06/15 17:55:14 mickey Exp $
2.\"
3.\" Copyright (c) 1990, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" This code is derived from software contributed to Berkeley by
7.\" Chris Torek.
8.\"
9.\" Redistribution and use in source and binary forms, with or without
10.\" modification, are permitted provided that the following conditions
11.\" are met:
12.\" 1. Redistributions of source code must retain the above copyright
13.\" notice, this list of conditions and the following disclaimer.
14.\" 2. Redistributions in binary form must reproduce the above copyright
15.\" notice, this list of conditions and the following disclaimer in the
16.\" documentation and/or other materials provided with the distribution.
17.\" 3. All advertising materials mentioning features or use of this software
18.\" must display the following acknowledgement:
19.\" This product includes software developed by the University of
20.\" California, Berkeley and its contributors.
21.\" 4. Neither the name of the University nor the names of its contributors
22.\" may be used to endorse or promote products derived from this software
23.\" without specific prior written permission.
24.\"
25.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35.\" SUCH DAMAGE.
36.\"
37.\" @(#)strsep.3 8.1 (Berkeley) 6/9/93
38.\"
39.Dd June 9, 1993
40.Dt STRSEP 3
41.Os
42.Sh NAME
43.Nm strsep
44.Nd separate strings
45.Sh SYNOPSIS
46.Fd #include <string.h>
47.Ft char *
48.Fn strsep "char **stringp" "char *delim"
49.Sh DESCRIPTION
50The
51.Fn strsep
52function locates, in the string referenced by
53.Fa *stringp ,
54the first occurrence of any character in the string
55.Fa delim
56(or the terminating
57.Ql \e0
58character) and replaces it with a
59.Ql \e0 .
60The location of the next character after the delimiter character
61(or NULL, if the end of the string was reached) is stored in
62.Fa *stringp .
63The original value of
64.Fa *stringp
65is returned.
66.Pp
67An ``empty'' field, i.e. one caused by two adjacent delimiter characters,
68can be detected by comparing the location referenced by the pointer returned
69in
70.Fa *stringp
71to
72.Ql \e0 .
73.Pp
74If
75.Fa *stringp
76is initially
77.Dv NULL ,
78.Fn strsep
79returns
80.Dv NULL .
81.Sh EXAMPLES
82The following uses
83.Fn strsep
84to parse a string, containing tokens delimited by white space, into an
85argument vector:
86.Bd -literal -offset indent
87char **ap, *argv[10], *inputstring;
88
89for (ap = argv; (*ap = strsep(&inputstring, " \et")) != NULL;)
90 if (**ap != '\e0')
91 ++ap;
92.Ed
93.Sh HISTORY
94The
95.Fn strsep
96function
97is intended as a replacement for the
98.Fn strtok
99function.
100While the
101.Fn strtok
102function should be preferred for portability reasons (it conforms to
103.St -ansiC )
104it is unable to handle empty fields, i.e. detect fields delimited by
105two adjacent delimiter characters, or to be used for more than a single
106string at a time.
107The
108.Fn strsep
109function first appeared in
110.Bx 4.4 .
diff --git a/src/lib/libc/string/strsep.c b/src/lib/libc/string/strsep.c
new file mode 100644
index 0000000000..b69b715fc5
--- /dev/null
+++ b/src/lib/libc/string/strsep.c
@@ -0,0 +1,85 @@
1/* $OpenBSD: strsep.c,v 1.3 1997/08/20 04:28:14 millert Exp $ */
2
3/*-
4 * Copyright (c) 1990, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36#include <string.h>
37#include <stdio.h>
38
39#if defined(LIBC_SCCS) && !defined(lint)
40#if 0
41static char sccsid[] = "@(#)strsep.c 8.1 (Berkeley) 6/4/93";
42#else
43static char *rcsid = "$OpenBSD: strsep.c,v 1.3 1997/08/20 04:28:14 millert Exp $";
44#endif
45#endif /* LIBC_SCCS and not lint */
46
47/*
48 * Get next token from string *stringp, where tokens are possibly-empty
49 * strings separated by characters from delim.
50 *
51 * Writes NULs into the string at *stringp to end tokens.
52 * delim need not remain constant from call to call.
53 * On return, *stringp points past the last NUL written (if there might
54 * be further tokens), or is NULL (if there are definitely no more tokens).
55 *
56 * If *stringp is NULL, strsep returns NULL.
57 */
58char *
59strsep(stringp, delim)
60 register char **stringp;
61 register const char *delim;
62{
63 register char *s;
64 register const char *spanp;
65 register int c, sc;
66 char *tok;
67
68 if ((s = *stringp) == NULL)
69 return (NULL);
70 for (tok = s;;) {
71 c = *s++;
72 spanp = delim;
73 do {
74 if ((sc = *spanp++) == c) {
75 if (c == 0)
76 s = NULL;
77 else
78 s[-1] = 0;
79 *stringp = s;
80 return (tok);
81 }
82 } while (sc != 0);
83 }
84 /* NOTREACHED */
85}
diff --git a/src/lib/libc/string/strsignal.3 b/src/lib/libc/string/strsignal.3
new file mode 100644
index 0000000000..42e433c259
--- /dev/null
+++ b/src/lib/libc/string/strsignal.3
@@ -0,0 +1,60 @@
1.\" Copyright (c) 1980, 1991 Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: strsignal.3,v 1.2 1996/08/19 08:34:25 tholo Exp $
37.\"
38.Dd June 29, 1991
39.Dt STRSIGNAL 3
40.Os BSD 4
41.Sh NAME
42.Nm strsignal
43.Nd get signal description string
44.Sh SYNOPSIS
45.Fd #include <string.h>
46.Ft char *
47.Fn strsignal "int sig"
48.Sh DESCRIPTION
49The
50.Fn strsignal
51function returns a pointer to the language-dependent string describing
52a signal.
53.Pp
54The array pointed to is not to be modified by the program, but may be
55overwritten by subsequent calls to
56.Fn strsignal .
57.Sh SEE ALSO
58.Xr intro 2 ,
59.Xr psignal 3 ,
60.Xr setlocale 3
diff --git a/src/lib/libc/string/strsignal.c b/src/lib/libc/string/strsignal.c
new file mode 100644
index 0000000000..cf03af5963
--- /dev/null
+++ b/src/lib/libc/string/strsignal.c
@@ -0,0 +1,49 @@
1/*
2 * Copyright (c) 1988 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: strsignal.c,v 1.2 1996/08/19 08:34:25 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <string.h>
39#include <limits.h>
40
41extern char *__strsignal __P((int, char *));
42
43char *
44strsignal(sig)
45 int sig;
46{
47 static char buf[NL_TEXTMAX];
48 return __strsignal(sig, buf);
49}
diff --git a/src/lib/libc/string/strspn.3 b/src/lib/libc/string/strspn.3
new file mode 100644
index 0000000000..7d15470dee
--- /dev/null
+++ b/src/lib/libc/string/strspn.3
@@ -0,0 +1,79 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: strspn.3,v 1.3 1996/08/19 08:34:25 tholo Exp $
37.\"
38.Dd June 29, 1991
39.Dt STRSPN 3
40.Os
41.Sh NAME
42.Nm strspn
43.Nd span a string
44.Sh SYNOPSIS
45.Fd #include <string.h>
46.Ft size_t
47.Fn strspn "const char *s" "const char *charset"
48.Sh DESCRIPTION
49The
50.Fn strspn
51function
52spans the initial part of the null-terminated string
53.Fa s
54as long as the characters from
55.Fa s
56occur in string
57.Fa charset .
58.Sh RETURN VALUES
59The
60.Fn strspn
61function
62returns the number of characters spanned.
63.Sh SEE ALSO
64.Xr index 3 ,
65.Xr memchr 3 ,
66.Xr rindex 3 ,
67.Xr strchr 3 ,
68.Xr strcspn 3 ,
69.Xr strpbrk 3 ,
70.Xr strrchr 3 ,
71.Xr strsep 3 ,
72.Xr strstr 3 ,
73.Xr strtok 3
74.Sh STANDARDS
75The
76.Fn strspn
77function
78conforms to
79.St -ansiC .
diff --git a/src/lib/libc/string/strspn.c b/src/lib/libc/string/strspn.c
new file mode 100644
index 0000000000..41940f9190
--- /dev/null
+++ b/src/lib/libc/string/strspn.c
@@ -0,0 +1,60 @@
1/*
2 * Copyright (c) 1989 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: strspn.c,v 1.2 1996/08/19 08:34:26 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <string.h>
39
40/*
41 * Span the string s2 (skip characters that are in s2).
42 */
43size_t
44strspn(s1, s2)
45 const char *s1;
46 register const char *s2;
47{
48 register const char *p = s1, *spanp;
49 register char c, sc;
50
51 /*
52 * Skip any characters in s2, excluding the terminating \0.
53 */
54cont:
55 c = *p++;
56 for (spanp = s2; (sc = *spanp++) != 0;)
57 if (sc == c)
58 goto cont;
59 return (p - 1 - s1);
60}
diff --git a/src/lib/libc/string/strstr.3 b/src/lib/libc/string/strstr.3
new file mode 100644
index 0000000000..fa455b426a
--- /dev/null
+++ b/src/lib/libc/string/strstr.3
@@ -0,0 +1,88 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: strstr.3,v 1.2 1996/08/19 08:34:26 tholo Exp $
37.\"
38.Dd June 29, 1991
39.Dt STRSTR 3
40.Os
41.Sh NAME
42.Nm strstr
43.Nd locate a substring in a string
44.Sh SYNOPSIS
45.Fd #include <string.h>
46.Ft char *
47.Fn strstr "const char *big" "const char *little"
48.Sh DESCRIPTION
49The
50.Fn strstr
51function
52locates the first occurrence of the null-terminated string
53.Fa little
54in the null-terminated string
55.Fa big .
56If
57.Fa little
58is the empty string,
59.Fn strstr
60returns
61.Fa big ;
62if
63.Fa little
64occurs nowhere in
65.Fa big ,
66.Fn strstr
67returns NULL;
68otherwise
69.Fn strstr
70returns a pointer to the first character of the first occurrence of
71.Fa little .
72.Sh SEE ALSO
73.Xr index 3 ,
74.Xr memchr 3 ,
75.Xr rindex 3 ,
76.Xr strchr 3 ,
77.Xr strcspn 3 ,
78.Xr strpbrk 3 ,
79.Xr strrchr 3 ,
80.Xr strsep 3 ,
81.Xr strspn 3 ,
82.Xr strtok 3
83.Sh STANDARDS
84The
85.Fn strstr
86function
87conforms to
88.St -ansiC .
diff --git a/src/lib/libc/string/strstr.c b/src/lib/libc/string/strstr.c
new file mode 100644
index 0000000000..763c7e29d7
--- /dev/null
+++ b/src/lib/libc/string/strstr.c
@@ -0,0 +1,64 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Chris Torek.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: strstr.c,v 1.2 1996/08/19 08:34:27 tholo Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#include <string.h>
42
43/*
44 * Find the first occurrence of find in s.
45 */
46char *
47strstr(s, find)
48 register const char *s, *find;
49{
50 register char c, sc;
51 register size_t len;
52
53 if ((c = *find++) != 0) {
54 len = strlen(find);
55 do {
56 do {
57 if ((sc = *s++) == 0)
58 return (NULL);
59 } while (sc != c);
60 } while (strncmp(s, find, len) != 0);
61 s--;
62 }
63 return ((char *)s);
64}
diff --git a/src/lib/libc/string/strtok.3 b/src/lib/libc/string/strtok.3
new file mode 100644
index 0000000000..876e0eb515
--- /dev/null
+++ b/src/lib/libc/string/strtok.3
@@ -0,0 +1,112 @@
1.\" Copyright (c) 1988, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: strtok.3,v 1.3 1998/04/28 07:36:55 deraadt Exp $
37.\"
38.Dd June 29, 1991
39.Dt STRTOK 3
40.Os BSD 3
41.Sh NAME
42.Nm strtok ,
43.Nm strsep
44.Nd string token operations
45.Sh SYNOPSIS
46.Fd #include <string.h>
47.Ft char *
48.Fn strtok "char *str" "const char *sep"
49.Sh DESCRIPTION
50.Bf -symbolic
51This interface is obsoleted by
52.Xr strsep 3 .
53.Ef
54.Pp
55The
56.Fn strtok
57function
58is used to isolate sequential tokens in a null-terminated string,
59.Fa str .
60These tokens are separated in the string by at least one of the
61characters in
62.Fa sep .
63The first time that
64.Fn strtok
65is called,
66.Fa str
67should be specified; subsequent calls, wishing to obtain further tokens
68from the same string, should pass a null pointer instead.
69The separator string,
70.Fa sep ,
71must be supplied each time, and may change between calls.
72.Pp
73The
74.Fn strtok
75function
76returns a pointer to the beginning of each subsequent token in the string,
77after replacing the separator character itself with a
78.Dv NUL
79character.
80When no more tokens remain, a null pointer is returned.
81.Sh SEE ALSO
82.Xr index 3 ,
83.Xr memchr 3 ,
84.Xr rindex 3 ,
85.Xr strchr 3 ,
86.Xr strcspn 3 ,
87.Xr strpbrk 3 ,
88.Xr strrchr 3 ,
89.Xr strsep 3 ,
90.Xr strspn 3 ,
91.Xr strstr 3
92.Sh STANDARDS
93The
94.Fn strtok
95function
96conforms to
97.St -ansiC .
98.Sh BUGS
99There is no way to get tokens from multiple strings simultaneously.
100.Pp
101The System V
102.Fn strtok ,
103if handed a string containing only delimiter characters,
104will not alter the next starting point, so that a call to
105.Fn strtok
106with a different (or empty) delimiter string
107may return a
108.Pf non- Dv NULL
109value.
110Since this implementation always alters the next starting point,
111such a sequence of calls would always return
112.Dv NULL .
diff --git a/src/lib/libc/string/strtok.c b/src/lib/libc/string/strtok.c
new file mode 100644
index 0000000000..2fce04c3ad
--- /dev/null
+++ b/src/lib/libc/string/strtok.c
@@ -0,0 +1,89 @@
1/*
2 * Copyright (c) 1988 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: strtok.c,v 1.2 1996/08/19 08:34:28 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <string.h>
39
40char *
41strtok(s, delim)
42 register char *s;
43 register const char *delim;
44{
45 register char *spanp;
46 register int c, sc;
47 char *tok;
48 static char *last;
49
50
51 if (s == NULL && (s = last) == NULL)
52 return (NULL);
53
54 /*
55 * Skip (span) leading delimiters (s += strspn(s, delim), sort of).
56 */
57cont:
58 c = *s++;
59 for (spanp = (char *)delim; (sc = *spanp++) != 0;) {
60 if (c == sc)
61 goto cont;
62 }
63
64 if (c == 0) { /* no non-delimiter characters */
65 last = NULL;
66 return (NULL);
67 }
68 tok = s - 1;
69
70 /*
71 * Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
72 * Note that delim must have one NUL; we stop if we see that, too.
73 */
74 for (;;) {
75 c = *s++;
76 spanp = (char *)delim;
77 do {
78 if ((sc = *spanp++) == c) {
79 if (c == 0)
80 s = NULL;
81 else
82 s[-1] = 0;
83 last = s;
84 return (tok);
85 }
86 } while (sc != 0);
87 }
88 /* NOTREACHED */
89}
diff --git a/src/lib/libc/string/strxfrm.3 b/src/lib/libc/string/strxfrm.3
new file mode 100644
index 0000000000..3ebdd42c29
--- /dev/null
+++ b/src/lib/libc/string/strxfrm.3
@@ -0,0 +1,68 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: strxfrm.3,v 1.2 1996/08/19 08:34:28 tholo Exp $
37.\"
38.Dd June 29, 1991
39.Dt STRXFRM 3
40.Os
41.Sh NAME
42.Nm strxfrm
43.Nd transform a string under locale
44.Sh SYNOPSIS
45.Fd #include <string.h>
46.Ft size_t
47.Fn strxfrm "char *dst" "const char *src" "size_t n"
48.Sh DESCRIPTION
49The
50.Fn strxfrm
51function
52does something horrible (see
53.Tn ANSI
54standard).
55In this implementation it just copies.
56.Sh SEE ALSO
57.Xr bcmp 3 ,
58.Xr memcmp 3 ,
59.\" .Xr setlocale 3 ,
60.Xr strcasecmp 3 ,
61.Xr strcmp 3 ,
62.Xr strcoll 3
63.Sh STANDARDS
64The
65.Fn strxfrm
66function
67conforms to
68.St -ansiC .
diff --git a/src/lib/libc/string/strxfrm.c b/src/lib/libc/string/strxfrm.c
new file mode 100644
index 0000000000..6b258edecc
--- /dev/null
+++ b/src/lib/libc/string/strxfrm.c
@@ -0,0 +1,73 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Chris Torek.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: strxfrm.c,v 1.2 1996/08/19 08:34:29 tholo Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#include <string.h>
42
43/*
44 * Transform src, storing the result in dst, such that
45 * strcmp() on transformed strings returns what strcoll()
46 * on the original untransformed strings would return.
47 */
48size_t
49strxfrm(dst, src, n)
50 register char *dst;
51 register const char *src;
52 register size_t n;
53{
54 register size_t r = 0;
55 register int c;
56
57 /*
58 * Since locales are unimplemented, this is just a copy.
59 */
60 if (n != 0) {
61 while ((c = *src++) != 0) {
62 r++;
63 if (--n == 0) {
64 while (*src++ != 0)
65 r++;
66 break;
67 }
68 *dst++ = c;
69 }
70 *dst = 0;
71 }
72 return (r);
73}
diff --git a/src/lib/libc/string/swab.3 b/src/lib/libc/string/swab.3
new file mode 100644
index 0000000000..d1bfc358fb
--- /dev/null
+++ b/src/lib/libc/string/swab.3
@@ -0,0 +1,65 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\" notice, this list of conditions and the following disclaimer.
9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\" notice, this list of conditions and the following disclaimer in the
11.\" documentation and/or other materials provided with the distribution.
12.\" 3. All advertising materials mentioning features or use of this software
13.\" must display the following acknowledgement:
14.\" This product includes software developed by the University of
15.\" California, Berkeley and its contributors.
16.\" 4. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" $OpenBSD: swab.3,v 1.3 1998/02/10 02:19:48 deraadt Exp $
33.\"
34.Dd May 1, 1991
35.Dt SWAB 3
36.Os
37.Sh NAME
38.Nm swab
39.Nd swap adjacent bytes
40.Sh SYNOPSIS
41.Fd #include <unistd.h>
42.Ft void
43.Fn swab "const void *src" "void *dst" "size_t len"
44.Sh DESCRIPTION
45The function
46.Fn swab
47copies
48.Fa len
49bytes from the location referenced by
50.Fa src
51to the location referenced by
52.Fa dst ,
53swapping adjacent bytes.
54.Pp
55The argument
56.Fa len
57must be even number.
58.Sh SEE ALSO
59.Xr bzero 3 ,
60.Xr memset 3
61.Sh HISTORY
62A
63.Fn swab
64function appeared in
65.At v7 .
diff --git a/src/lib/libc/string/swab.c b/src/lib/libc/string/swab.c
new file mode 100644
index 0000000000..311cf13a53
--- /dev/null
+++ b/src/lib/libc/string/swab.c
@@ -0,0 +1,65 @@
1/*
2 * Copyright (c) 1988 Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Jeffrey Mogul.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: swab.c,v 1.3 1998/02/10 02:19:48 deraadt Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#include <unistd.h>
42
43void
44swab(from, to, len)
45 const void *from;
46 void *to;
47 size_t len;
48{
49 register unsigned long temp;
50 register int n;
51 register char *fp, *tp;
52
53 n = (len >> 1) + 1;
54 fp = (char *)from;
55 tp = (char *)to;
56#define STEP temp = *fp++,*tp++ = *fp++,*tp++ = temp
57 /* round to multiple of 8 */
58 while ((--n) & 07)
59 STEP;
60 n >>= 3;
61 while (--n >= 0) {
62 STEP; STEP; STEP; STEP;
63 STEP; STEP; STEP; STEP;
64 }
65}