diff options
Diffstat (limited to 'src/lib/libc')
339 files changed, 27046 insertions, 12706 deletions
diff --git a/src/lib/libc/crypt/Makefile.inc b/src/lib/libc/crypt/Makefile.inc new file mode 100644 index 0000000000..c852523372 --- /dev/null +++ b/src/lib/libc/crypt/Makefile.inc | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | # $OpenBSD: Makefile.inc,v 1.19 2013/10/21 20:33:23 deraadt Exp $ | ||
| 2 | |||
| 3 | .PATH: ${LIBCSRCDIR}/arch/${MACHINE_CPU}/crypt ${LIBCSRCDIR}/crypt | ||
| 4 | |||
| 5 | SRCS+= crypt.c crypt2.c md5crypt.c arc4random.c blowfish.c bcrypt.c | ||
| 6 | |||
| 7 | MAN+= crypt.3 blowfish.3 arc4random.3 | ||
| 8 | MLINKS+=crypt.3 encrypt.3 crypt.3 setkey.3 crypt.3 des_cipher.3 | ||
| 9 | MLINKS+=crypt.3 bcrypt_gensalt.3 crypt.3 bcrypt.3 crypt.3 md5crypt.3 | ||
| 10 | MLINKS+=crypt.3 des_setkey.3 blowfish.3 blf_key.3 blowfish.3 blf_enc.3 | ||
| 11 | MLINKS+=blowfish.3 blf_dec.3 blowfish.3 blf_ecb_encrypt.3 | ||
| 12 | MLINKS+=blowfish.3 blf_ecb_decrypt.3 blowfish.3 blf_cbc_encrypt.3 | ||
| 13 | MLINKS+=blowfish.3 blf_cbc_decrypt.3 | ||
| 14 | MLINKS+=arc4random.3 arc4random_buf.3 arc4random.3 arc4random_uniform.3 | ||
diff --git a/src/lib/libc/crypt/arc4random.3 b/src/lib/libc/crypt/arc4random.3 new file mode 100644 index 0000000000..476bc28017 --- /dev/null +++ b/src/lib/libc/crypt/arc4random.3 | |||
| @@ -0,0 +1,114 @@ | |||
| 1 | .\" $OpenBSD: arc4random.3,v 1.32 2013/10/22 06:51:41 jmc Exp $ | ||
| 2 | .\" | ||
| 3 | .\" Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de> | ||
| 4 | .\" All rights reserved. | ||
| 5 | .\" | ||
| 6 | .\" Redistribution and use in source and binary forms, with or without | ||
| 7 | .\" modification, are permitted provided that the following conditions | ||
| 8 | .\" are met: | ||
| 9 | .\" 1. Redistributions of source code must retain the above copyright | ||
| 10 | .\" notice, this list of conditions and the following disclaimer. | ||
| 11 | .\" 2. Redistributions in binary form must reproduce the above copyright | ||
| 12 | .\" notice, this list of conditions and the following disclaimer in the | ||
| 13 | .\" documentation and/or other materials provided with the distribution. | ||
| 14 | .\" 3. All advertising materials mentioning features or use of this software | ||
| 15 | .\" must display the following acknowledgement: | ||
| 16 | .\" This product includes software developed by Niels Provos. | ||
| 17 | .\" 4. The name of the author may not be used to endorse or promote products | ||
| 18 | .\" derived from this software without specific prior written permission. | ||
| 19 | .\" | ||
| 20 | .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | ||
| 21 | .\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
| 22 | .\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
| 23 | .\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 24 | .\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
| 25 | .\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
| 26 | .\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
| 27 | .\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| 28 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
| 29 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 30 | .\" | ||
| 31 | .\" Manual page, using -mandoc macros | ||
| 32 | .\" | ||
| 33 | .Dd $Mdocdate: October 22 2013 $ | ||
| 34 | .Dt ARC4RANDOM 3 | ||
| 35 | .Os | ||
| 36 | .Sh NAME | ||
| 37 | .Nm arc4random , | ||
| 38 | .Nm arc4random_buf , | ||
| 39 | .Nm arc4random_uniform | ||
| 40 | .Nd random number generator | ||
| 41 | .Sh SYNOPSIS | ||
| 42 | .In stdlib.h | ||
| 43 | .Ft u_int32_t | ||
| 44 | .Fn arc4random "void" | ||
| 45 | .Ft void | ||
| 46 | .Fn arc4random_buf "void *buf" "size_t nbytes" | ||
| 47 | .Ft u_int32_t | ||
| 48 | .Fn arc4random_uniform "u_int32_t upper_bound" | ||
| 49 | .Sh DESCRIPTION | ||
| 50 | This family of functions provides higher quality data than those | ||
| 51 | described in | ||
| 52 | .Xr rand 3 , | ||
| 53 | .Xr random 3 , | ||
| 54 | and | ||
| 55 | .Xr drand48 3 . | ||
| 56 | .Pp | ||
| 57 | Use of these functions is encouraged for almost all random number | ||
| 58 | consumption because the other interfaces are deficient in either | ||
| 59 | quality, portability, standardization, or availability. | ||
| 60 | These functions can be called in almost all coding environments, | ||
| 61 | including | ||
| 62 | .Xr pthreads 3 | ||
| 63 | and | ||
| 64 | .Xr chroot 2 . | ||
| 65 | .Pp | ||
| 66 | High quality 32-bit pseudo-random numbers are generated very quickly. | ||
| 67 | On each call, a cryptographic pseudo-random number generator is used | ||
| 68 | to generate a new result. | ||
| 69 | One data pool is used for all consumers in a process, so that consumption | ||
| 70 | under program flow can act as additional stirring. | ||
| 71 | The subsystem is re-seeded from the kernel random number subsystem using | ||
| 72 | .Xr sysctl 3 | ||
| 73 | on a regular basis, and also upon | ||
| 74 | .Xr fork 2 . | ||
| 75 | .Pp | ||
| 76 | The | ||
| 77 | .Fn arc4random | ||
| 78 | function returns a single 32-bit value. | ||
| 79 | .Pp | ||
| 80 | .Fn arc4random_buf | ||
| 81 | fills the region | ||
| 82 | .Fa buf | ||
| 83 | of length | ||
| 84 | .Fa nbytes | ||
| 85 | with random data. | ||
| 86 | .Pp | ||
| 87 | .Fn arc4random_uniform | ||
| 88 | will return a single 32-bit value, uniformly distributed but less than | ||
| 89 | .Fa upper_bound . | ||
| 90 | This is recommended over constructions like | ||
| 91 | .Dq Li arc4random() % upper_bound | ||
| 92 | as it avoids "modulo bias" when the upper bound is not a power of two. | ||
| 93 | In the worst case, this function may consume multiple iterations | ||
| 94 | to ensure uniformity; see the source code to understand the problem | ||
| 95 | and solution. | ||
| 96 | .Sh RETURN VALUES | ||
| 97 | These functions are always successful, and no return value is | ||
| 98 | reserved to indicate an error. | ||
| 99 | .Sh SEE ALSO | ||
| 100 | .Xr rand 3 , | ||
| 101 | .Xr rand48 3 , | ||
| 102 | .Xr random 3 | ||
| 103 | .Sh HISTORY | ||
| 104 | These functions first appeared in | ||
| 105 | .Ox 2.1 . | ||
| 106 | .Pp | ||
| 107 | The original version of this random number generator used the | ||
| 108 | RC4 (also known as ARC4) algorithm. | ||
| 109 | In | ||
| 110 | .Ox 5.5 | ||
| 111 | it was replaced with the ChaCha20 cipher, and it may be replaced | ||
| 112 | again in the future as cryptographic techniques advance. | ||
| 113 | A good mnemonic is | ||
| 114 | .Dq A Replacement Call for Random . | ||
diff --git a/src/lib/libc/crypt/arc4random.c b/src/lib/libc/crypt/arc4random.c new file mode 100644 index 0000000000..e836395803 --- /dev/null +++ b/src/lib/libc/crypt/arc4random.c | |||
| @@ -0,0 +1,236 @@ | |||
| 1 | /* $OpenBSD: arc4random.c,v 1.26 2013/10/21 20:33:23 deraadt Exp $ */ | ||
| 2 | |||
| 3 | /* | ||
| 4 | * Copyright (c) 1996, David Mazieres <dm@uun.org> | ||
| 5 | * Copyright (c) 2008, Damien Miller <djm@openbsd.org> | ||
| 6 | * Copyright (c) 2013, Markus Friedl <markus@openbsd.org> | ||
| 7 | * | ||
| 8 | * Permission to use, copy, modify, and distribute this software for any | ||
| 9 | * purpose with or without fee is hereby granted, provided that the above | ||
| 10 | * copyright notice and this permission notice appear in all copies. | ||
| 11 | * | ||
| 12 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 13 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 14 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 15 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 16 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 17 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 18 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 19 | */ | ||
| 20 | |||
| 21 | /* | ||
| 22 | * ChaCha based random number generator for OpenBSD. | ||
| 23 | */ | ||
| 24 | |||
| 25 | #include <fcntl.h> | ||
| 26 | #include <limits.h> | ||
| 27 | #include <stdlib.h> | ||
| 28 | #include <string.h> | ||
| 29 | #include <unistd.h> | ||
| 30 | #include <sys/types.h> | ||
| 31 | #include <sys/param.h> | ||
| 32 | #include <sys/time.h> | ||
| 33 | #include <sys/sysctl.h> | ||
| 34 | #include "thread_private.h" | ||
| 35 | |||
| 36 | #define KEYSTREAM_ONLY | ||
| 37 | #include "chacha_private.h" | ||
| 38 | |||
| 39 | #ifdef __GNUC__ | ||
| 40 | #define inline __inline | ||
| 41 | #else /* !__GNUC__ */ | ||
| 42 | #define inline | ||
| 43 | #endif /* !__GNUC__ */ | ||
| 44 | |||
| 45 | #define KEYSZ 32 | ||
| 46 | #define IVSZ 8 | ||
| 47 | #define BLOCKSZ 64 | ||
| 48 | #define RSBUFSZ (16*BLOCKSZ) | ||
| 49 | static int rs_initialized; | ||
| 50 | static pid_t rs_stir_pid; | ||
| 51 | static chacha_ctx rs; /* chacha context for random keystream */ | ||
| 52 | static u_char rs_buf[RSBUFSZ]; /* keystream blocks */ | ||
| 53 | static size_t rs_have; /* valid bytes at end of rs_buf */ | ||
| 54 | static size_t rs_count; /* bytes till reseed */ | ||
| 55 | |||
| 56 | static inline void _rs_rekey(u_char *dat, size_t datlen); | ||
| 57 | |||
| 58 | static inline void | ||
| 59 | _rs_init(u_char *buf, size_t n) | ||
| 60 | { | ||
| 61 | if (n < KEYSZ + IVSZ) | ||
| 62 | return; | ||
| 63 | chacha_keysetup(&rs, buf, KEYSZ * 8, 0); | ||
| 64 | chacha_ivsetup(&rs, buf + KEYSZ); | ||
| 65 | } | ||
| 66 | |||
| 67 | static void | ||
| 68 | _rs_stir(void) | ||
| 69 | { | ||
| 70 | int mib[2]; | ||
| 71 | size_t len; | ||
| 72 | u_char rnd[KEYSZ + IVSZ]; | ||
| 73 | |||
| 74 | mib[0] = CTL_KERN; | ||
| 75 | mib[1] = KERN_ARND; | ||
| 76 | |||
| 77 | len = sizeof(rnd); | ||
| 78 | sysctl(mib, 2, rnd, &len, NULL, 0); | ||
| 79 | |||
| 80 | if (!rs_initialized) { | ||
| 81 | rs_initialized = 1; | ||
| 82 | _rs_init(rnd, sizeof(rnd)); | ||
| 83 | } else | ||
| 84 | _rs_rekey(rnd, sizeof(rnd)); | ||
| 85 | memset(rnd, 0, sizeof(rnd)); | ||
| 86 | |||
| 87 | /* invalidate rs_buf */ | ||
| 88 | rs_have = 0; | ||
| 89 | memset(rs_buf, 0, RSBUFSZ); | ||
| 90 | |||
| 91 | rs_count = 1600000; | ||
| 92 | } | ||
| 93 | |||
| 94 | static inline void | ||
| 95 | _rs_stir_if_needed(size_t len) | ||
| 96 | { | ||
| 97 | pid_t pid = getpid(); | ||
| 98 | |||
| 99 | if (rs_count <= len || !rs_initialized || rs_stir_pid != pid) { | ||
| 100 | rs_stir_pid = pid; | ||
| 101 | _rs_stir(); | ||
| 102 | } else | ||
| 103 | rs_count -= len; | ||
| 104 | } | ||
| 105 | |||
| 106 | static inline void | ||
| 107 | _rs_rekey(u_char *dat, size_t datlen) | ||
| 108 | { | ||
| 109 | #ifndef KEYSTREAM_ONLY | ||
| 110 | memset(rs_buf, 0,RSBUFSZ); | ||
| 111 | #endif | ||
| 112 | /* fill rs_buf with the keystream */ | ||
| 113 | chacha_encrypt_bytes(&rs, rs_buf, rs_buf, RSBUFSZ); | ||
| 114 | /* mix in optional user provided data */ | ||
| 115 | if (dat) { | ||
| 116 | size_t i, m; | ||
| 117 | |||
| 118 | m = MIN(datlen, KEYSZ + IVSZ); | ||
| 119 | for (i = 0; i < m; i++) | ||
| 120 | rs_buf[i] ^= dat[i]; | ||
| 121 | } | ||
| 122 | /* immediately reinit for backtracking resistance */ | ||
| 123 | _rs_init(rs_buf, KEYSZ + IVSZ); | ||
| 124 | memset(rs_buf, 0, KEYSZ + IVSZ); | ||
| 125 | rs_have = RSBUFSZ - KEYSZ - IVSZ; | ||
| 126 | } | ||
| 127 | |||
| 128 | static inline void | ||
| 129 | _rs_random_buf(void *_buf, size_t n) | ||
| 130 | { | ||
| 131 | u_char *buf = (u_char *)_buf; | ||
| 132 | size_t m; | ||
| 133 | |||
| 134 | _rs_stir_if_needed(n); | ||
| 135 | while (n > 0) { | ||
| 136 | if (rs_have > 0) { | ||
| 137 | m = MIN(n, rs_have); | ||
| 138 | memcpy(buf, rs_buf + RSBUFSZ - rs_have, m); | ||
| 139 | memset(rs_buf + RSBUFSZ - rs_have, 0, m); | ||
| 140 | buf += m; | ||
| 141 | n -= m; | ||
| 142 | rs_have -= m; | ||
| 143 | } | ||
| 144 | if (rs_have == 0) | ||
| 145 | _rs_rekey(NULL, 0); | ||
| 146 | } | ||
| 147 | } | ||
| 148 | |||
| 149 | static inline void | ||
| 150 | _rs_random_u32(u_int32_t *val) | ||
| 151 | { | ||
| 152 | _rs_stir_if_needed(sizeof(*val)); | ||
| 153 | if (rs_have < sizeof(*val)) | ||
| 154 | _rs_rekey(NULL, 0); | ||
| 155 | memcpy(val, rs_buf + RSBUFSZ - rs_have, sizeof(*val)); | ||
| 156 | memset(rs_buf + RSBUFSZ - rs_have, 0, sizeof(*val)); | ||
| 157 | rs_have -= sizeof(*val); | ||
| 158 | return; | ||
| 159 | } | ||
| 160 | |||
| 161 | u_int32_t | ||
| 162 | arc4random(void) | ||
| 163 | { | ||
| 164 | u_int32_t val; | ||
| 165 | |||
| 166 | _ARC4_LOCK(); | ||
| 167 | _rs_random_u32(&val); | ||
| 168 | _ARC4_UNLOCK(); | ||
| 169 | return val; | ||
| 170 | } | ||
| 171 | |||
| 172 | void | ||
| 173 | arc4random_buf(void *buf, size_t n) | ||
| 174 | { | ||
| 175 | _ARC4_LOCK(); | ||
| 176 | _rs_random_buf(buf, n); | ||
| 177 | _ARC4_UNLOCK(); | ||
| 178 | } | ||
| 179 | |||
| 180 | /* | ||
| 181 | * Calculate a uniformly distributed random number less than upper_bound | ||
| 182 | * avoiding "modulo bias". | ||
| 183 | * | ||
| 184 | * Uniformity is achieved by generating new random numbers until the one | ||
| 185 | * returned is outside the range [0, 2**32 % upper_bound). This | ||
| 186 | * guarantees the selected random number will be inside | ||
| 187 | * [2**32 % upper_bound, 2**32) which maps back to [0, upper_bound) | ||
| 188 | * after reduction modulo upper_bound. | ||
| 189 | */ | ||
| 190 | u_int32_t | ||
| 191 | arc4random_uniform(u_int32_t upper_bound) | ||
| 192 | { | ||
| 193 | u_int32_t r, min; | ||
| 194 | |||
| 195 | if (upper_bound < 2) | ||
| 196 | return 0; | ||
| 197 | |||
| 198 | /* 2**32 % x == (2**32 - x) % x */ | ||
| 199 | min = -upper_bound % upper_bound; | ||
| 200 | |||
| 201 | /* | ||
| 202 | * This could theoretically loop forever but each retry has | ||
| 203 | * p > 0.5 (worst case, usually far better) of selecting a | ||
| 204 | * number inside the range we need, so it should rarely need | ||
| 205 | * to re-roll. | ||
| 206 | */ | ||
| 207 | for (;;) { | ||
| 208 | r = arc4random(); | ||
| 209 | if (r >= min) | ||
| 210 | break; | ||
| 211 | } | ||
| 212 | |||
| 213 | return r % upper_bound; | ||
| 214 | } | ||
| 215 | |||
| 216 | #if 0 | ||
| 217 | /*-------- Test code for i386 --------*/ | ||
| 218 | #include <stdio.h> | ||
| 219 | #include <machine/pctr.h> | ||
| 220 | int | ||
| 221 | main(int argc, char **argv) | ||
| 222 | { | ||
| 223 | const int iter = 1000000; | ||
| 224 | int i; | ||
| 225 | pctrval v; | ||
| 226 | |||
| 227 | v = rdtsc(); | ||
| 228 | for (i = 0; i < iter; i++) | ||
| 229 | arc4random(); | ||
| 230 | v = rdtsc() - v; | ||
| 231 | v /= iter; | ||
| 232 | |||
| 233 | printf("%qd cycles\n", v); | ||
| 234 | exit(0); | ||
| 235 | } | ||
| 236 | #endif | ||
diff --git a/src/lib/libc/crypt/bcrypt.c b/src/lib/libc/crypt/bcrypt.c new file mode 100644 index 0000000000..d7af344b97 --- /dev/null +++ b/src/lib/libc/crypt/bcrypt.c | |||
| @@ -0,0 +1,365 @@ | |||
| 1 | /* $OpenBSD: bcrypt.c,v 1.37 2014/04/08 20:14:25 tedu Exp $ */ | ||
| 2 | |||
| 3 | /* | ||
| 4 | * Copyright (c) 2014 Ted Unangst <tedu@openbsd.org> | ||
| 5 | * Copyright (c) 1997 Niels Provos <provos@umich.edu> | ||
| 6 | * | ||
| 7 | * Permission to use, copy, modify, and distribute this software for any | ||
| 8 | * purpose with or without fee is hereby granted, provided that the above | ||
| 9 | * copyright notice and this permission notice appear in all copies. | ||
| 10 | * | ||
| 11 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 12 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 13 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 14 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 15 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 16 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 17 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 18 | */ | ||
| 19 | /* This password hashing algorithm was designed by David Mazieres | ||
| 20 | * <dm@lcs.mit.edu> and works as follows: | ||
| 21 | * | ||
| 22 | * 1. state := InitState () | ||
| 23 | * 2. state := ExpandKey (state, salt, password) | ||
| 24 | * 3. REPEAT rounds: | ||
| 25 | * state := ExpandKey (state, 0, password) | ||
| 26 | * state := ExpandKey (state, 0, salt) | ||
| 27 | * 4. ctext := "OrpheanBeholderScryDoubt" | ||
| 28 | * 5. REPEAT 64: | ||
| 29 | * ctext := Encrypt_ECB (state, ctext); | ||
| 30 | * 6. RETURN Concatenate (salt, ctext); | ||
| 31 | * | ||
| 32 | */ | ||
| 33 | |||
| 34 | #include <stdio.h> | ||
| 35 | #include <stdlib.h> | ||
| 36 | #include <sys/types.h> | ||
| 37 | #include <string.h> | ||
| 38 | #include <pwd.h> | ||
| 39 | #include <blf.h> | ||
| 40 | |||
| 41 | /* This implementation is adaptable to current computing power. | ||
| 42 | * You can have up to 2^31 rounds which should be enough for some | ||
| 43 | * time to come. | ||
| 44 | */ | ||
| 45 | |||
| 46 | #define BCRYPT_VERSION '2' | ||
| 47 | #define BCRYPT_MAXSALT 16 /* Precomputation is just so nice */ | ||
| 48 | #define BCRYPT_BLOCKS 6 /* Ciphertext blocks */ | ||
| 49 | #define BCRYPT_MINLOGROUNDS 4 /* we have log2(rounds) in salt */ | ||
| 50 | |||
| 51 | #define BCRYPT_SALTSPACE (7 + (BCRYPT_MAXSALT * 4 + 2) / 3 + 1) | ||
| 52 | |||
| 53 | char *bcrypt_gensalt(u_int8_t); | ||
| 54 | |||
| 55 | static int encode_base64(char *, const u_int8_t *, size_t); | ||
| 56 | static int decode_base64(u_int8_t *, size_t, const char *); | ||
| 57 | |||
| 58 | /* | ||
| 59 | * Generates a salt for this version of crypt. | ||
| 60 | */ | ||
| 61 | static int | ||
| 62 | bcrypt_initsalt(int log_rounds, uint8_t *salt, size_t saltbuflen) | ||
| 63 | { | ||
| 64 | uint8_t csalt[BCRYPT_MAXSALT]; | ||
| 65 | |||
| 66 | if (saltbuflen < BCRYPT_SALTSPACE) | ||
| 67 | return -1; | ||
| 68 | |||
| 69 | arc4random_buf(csalt, sizeof(csalt)); | ||
| 70 | |||
| 71 | if (log_rounds < 4) | ||
| 72 | log_rounds = 4; | ||
| 73 | else if (log_rounds > 31) | ||
| 74 | log_rounds = 31; | ||
| 75 | |||
| 76 | snprintf(salt, saltbuflen, "$2a$%2.2u$", log_rounds); | ||
| 77 | encode_base64(salt + 7, csalt, sizeof(csalt)); | ||
| 78 | |||
| 79 | return 0; | ||
| 80 | } | ||
| 81 | |||
| 82 | /* | ||
| 83 | * the core bcrypt function | ||
| 84 | */ | ||
| 85 | static int | ||
| 86 | bcrypt_hashpass(const char *key, const char *salt, char *encrypted, | ||
| 87 | size_t encryptedlen) | ||
| 88 | { | ||
| 89 | blf_ctx state; | ||
| 90 | u_int32_t rounds, i, k; | ||
| 91 | u_int16_t j; | ||
| 92 | size_t key_len; | ||
| 93 | u_int8_t salt_len, logr, minor; | ||
| 94 | u_int8_t ciphertext[4 * BCRYPT_BLOCKS] = "OrpheanBeholderScryDoubt"; | ||
| 95 | u_int8_t csalt[BCRYPT_MAXSALT]; | ||
| 96 | u_int32_t cdata[BCRYPT_BLOCKS]; | ||
| 97 | char arounds[3]; | ||
| 98 | |||
| 99 | /* Discard "$" identifier */ | ||
| 100 | salt++; | ||
| 101 | |||
| 102 | if (*salt > BCRYPT_VERSION) { | ||
| 103 | return -1; | ||
| 104 | } | ||
| 105 | |||
| 106 | /* Check for minor versions */ | ||
| 107 | if (salt[1] != '$') { | ||
| 108 | switch (salt[1]) { | ||
| 109 | case 'a': /* 'ab' should not yield the same as 'abab' */ | ||
| 110 | case 'b': /* cap input length at 72 bytes */ | ||
| 111 | minor = salt[1]; | ||
| 112 | salt++; | ||
| 113 | break; | ||
| 114 | default: | ||
| 115 | return -1; | ||
| 116 | } | ||
| 117 | } else | ||
| 118 | minor = 0; | ||
| 119 | |||
| 120 | /* Discard version + "$" identifier */ | ||
| 121 | salt += 2; | ||
| 122 | |||
| 123 | if (salt[2] != '$') | ||
| 124 | /* Out of sync with passwd entry */ | ||
| 125 | return -1; | ||
| 126 | |||
| 127 | memcpy(arounds, salt, sizeof(arounds)); | ||
| 128 | if (arounds[sizeof(arounds) - 1] != '$') | ||
| 129 | return -1; | ||
| 130 | arounds[sizeof(arounds) - 1] = 0; | ||
| 131 | logr = strtonum(arounds, BCRYPT_MINLOGROUNDS, 31, NULL); | ||
| 132 | if (logr == 0) | ||
| 133 | return -1; | ||
| 134 | /* Computer power doesn't increase linearly, 2^x should be fine */ | ||
| 135 | rounds = 1U << logr; | ||
| 136 | |||
| 137 | /* Discard num rounds + "$" identifier */ | ||
| 138 | salt += 3; | ||
| 139 | |||
| 140 | if (strlen(salt) * 3 / 4 < BCRYPT_MAXSALT) | ||
| 141 | return -1; | ||
| 142 | |||
| 143 | /* We dont want the base64 salt but the raw data */ | ||
| 144 | decode_base64(csalt, BCRYPT_MAXSALT, salt); | ||
| 145 | salt_len = BCRYPT_MAXSALT; | ||
| 146 | if (minor <= 'a') | ||
| 147 | key_len = (u_int8_t)(strlen(key) + (minor >= 'a' ? 1 : 0)); | ||
| 148 | else { | ||
| 149 | /* strlen() returns a size_t, but the function calls | ||
| 150 | * below result in implicit casts to a narrower integer | ||
| 151 | * type, so cap key_len at the actual maximum supported | ||
| 152 | * length here to avoid integer wraparound */ | ||
| 153 | key_len = strlen(key); | ||
| 154 | if (key_len > 72) | ||
| 155 | key_len = 72; | ||
| 156 | key_len++; /* include the NUL */ | ||
| 157 | } | ||
| 158 | |||
| 159 | /* Setting up S-Boxes and Subkeys */ | ||
| 160 | Blowfish_initstate(&state); | ||
| 161 | Blowfish_expandstate(&state, csalt, salt_len, | ||
| 162 | (u_int8_t *) key, key_len); | ||
| 163 | for (k = 0; k < rounds; k++) { | ||
| 164 | Blowfish_expand0state(&state, (u_int8_t *) key, key_len); | ||
| 165 | Blowfish_expand0state(&state, csalt, salt_len); | ||
| 166 | } | ||
| 167 | |||
| 168 | /* This can be precomputed later */ | ||
| 169 | j = 0; | ||
| 170 | for (i = 0; i < BCRYPT_BLOCKS; i++) | ||
| 171 | cdata[i] = Blowfish_stream2word(ciphertext, 4 * BCRYPT_BLOCKS, &j); | ||
| 172 | |||
| 173 | /* Now do the encryption */ | ||
| 174 | for (k = 0; k < 64; k++) | ||
| 175 | blf_enc(&state, cdata, BCRYPT_BLOCKS / 2); | ||
| 176 | |||
| 177 | for (i = 0; i < BCRYPT_BLOCKS; i++) { | ||
| 178 | ciphertext[4 * i + 3] = cdata[i] & 0xff; | ||
| 179 | cdata[i] = cdata[i] >> 8; | ||
| 180 | ciphertext[4 * i + 2] = cdata[i] & 0xff; | ||
| 181 | cdata[i] = cdata[i] >> 8; | ||
| 182 | ciphertext[4 * i + 1] = cdata[i] & 0xff; | ||
| 183 | cdata[i] = cdata[i] >> 8; | ||
| 184 | ciphertext[4 * i + 0] = cdata[i] & 0xff; | ||
| 185 | } | ||
| 186 | |||
| 187 | |||
| 188 | i = 0; | ||
| 189 | encrypted[i++] = '$'; | ||
| 190 | encrypted[i++] = BCRYPT_VERSION; | ||
| 191 | if (minor) | ||
| 192 | encrypted[i++] = minor; | ||
| 193 | encrypted[i++] = '$'; | ||
| 194 | |||
| 195 | snprintf(encrypted + i, 4, "%2.2u$", logr); | ||
| 196 | |||
| 197 | encode_base64(encrypted + i + 3, csalt, BCRYPT_MAXSALT); | ||
| 198 | encode_base64(encrypted + strlen(encrypted), ciphertext, | ||
| 199 | 4 * BCRYPT_BLOCKS - 1); | ||
| 200 | memset(&state, 0, sizeof(state)); | ||
| 201 | memset(ciphertext, 0, sizeof(ciphertext)); | ||
| 202 | memset(csalt, 0, sizeof(csalt)); | ||
| 203 | memset(cdata, 0, sizeof(cdata)); | ||
| 204 | return 0; | ||
| 205 | } | ||
| 206 | |||
| 207 | /* | ||
| 208 | * user friendly functions | ||
| 209 | */ | ||
| 210 | int | ||
| 211 | bcrypt_newhash(const char *pass, int log_rounds, char *hash, size_t hashlen) | ||
| 212 | { | ||
| 213 | char salt[BCRYPT_SALTSPACE]; | ||
| 214 | |||
| 215 | if (bcrypt_initsalt(log_rounds, salt, sizeof(salt)) != 0) | ||
| 216 | return -1; | ||
| 217 | |||
| 218 | if (bcrypt_hashpass(pass, salt, hash, hashlen) != 0) | ||
| 219 | return -1; | ||
| 220 | |||
| 221 | explicit_bzero(salt, sizeof(salt)); | ||
| 222 | return 0; | ||
| 223 | } | ||
| 224 | |||
| 225 | int | ||
| 226 | bcrypt_checkpass(const char *pass, const char *goodhash) | ||
| 227 | { | ||
| 228 | char hash[_PASSWORD_LEN]; | ||
| 229 | |||
| 230 | if (bcrypt_hashpass(pass, goodhash, hash, sizeof(hash)) != 0) | ||
| 231 | return -1; | ||
| 232 | if (strlen(hash) != strlen(goodhash) || | ||
| 233 | timingsafe_bcmp(hash, goodhash, strlen(goodhash)) != 0) | ||
| 234 | return -1; | ||
| 235 | |||
| 236 | explicit_bzero(hash, sizeof(hash)); | ||
| 237 | return 0; | ||
| 238 | } | ||
| 239 | |||
| 240 | /* | ||
| 241 | * internal utilities | ||
| 242 | */ | ||
| 243 | const static u_int8_t Base64Code[] = | ||
| 244 | "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; | ||
| 245 | |||
| 246 | const static u_int8_t index_64[128] = { | ||
| 247 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | ||
| 248 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | ||
| 249 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | ||
| 250 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | ||
| 251 | 255, 255, 255, 255, 255, 255, 0, 1, 54, 55, | ||
| 252 | 56, 57, 58, 59, 60, 61, 62, 63, 255, 255, | ||
| 253 | 255, 255, 255, 255, 255, 2, 3, 4, 5, 6, | ||
| 254 | 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, | ||
| 255 | 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, | ||
| 256 | 255, 255, 255, 255, 255, 255, 28, 29, 30, | ||
| 257 | 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, | ||
| 258 | 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, | ||
| 259 | 51, 52, 53, 255, 255, 255, 255, 255 | ||
| 260 | }; | ||
| 261 | #define CHAR64(c) ( (c) > 127 ? 255 : index_64[(c)]) | ||
| 262 | |||
| 263 | /* | ||
| 264 | * read buflen (after decoding) bytes of data from b64data | ||
| 265 | */ | ||
| 266 | static int | ||
| 267 | decode_base64(u_int8_t *buffer, size_t len, const char *b64data) | ||
| 268 | { | ||
| 269 | u_int8_t *bp = buffer; | ||
| 270 | const u_int8_t *p = b64data; | ||
| 271 | u_int8_t c1, c2, c3, c4; | ||
| 272 | |||
| 273 | while (bp < buffer + len) { | ||
| 274 | c1 = CHAR64(*p); | ||
| 275 | c2 = CHAR64(*(p + 1)); | ||
| 276 | |||
| 277 | /* Invalid data */ | ||
| 278 | if (c1 == 255 || c2 == 255) | ||
| 279 | return -1; | ||
| 280 | |||
| 281 | *bp++ = (c1 << 2) | ((c2 & 0x30) >> 4); | ||
| 282 | if (bp >= buffer + len) | ||
| 283 | break; | ||
| 284 | |||
| 285 | c3 = CHAR64(*(p + 2)); | ||
| 286 | if (c3 == 255) | ||
| 287 | break; | ||
| 288 | |||
| 289 | *bp++ = ((c2 & 0x0f) << 4) | ((c3 & 0x3c) >> 2); | ||
| 290 | if (bp >= buffer + len) | ||
| 291 | break; | ||
| 292 | |||
| 293 | c4 = CHAR64(*(p + 3)); | ||
| 294 | if (c4 == 255) | ||
| 295 | break; | ||
| 296 | *bp++ = ((c3 & 0x03) << 6) | c4; | ||
| 297 | |||
| 298 | p += 4; | ||
| 299 | } | ||
| 300 | return 0; | ||
| 301 | } | ||
| 302 | |||
| 303 | /* | ||
| 304 | * Turn len bytes of data into base64 encoded data. | ||
| 305 | * This works without = padding. | ||
| 306 | */ | ||
| 307 | static int | ||
| 308 | encode_base64(char *b64buffer, const u_int8_t *data, size_t len) | ||
| 309 | { | ||
| 310 | u_int8_t *bp = b64buffer; | ||
| 311 | const u_int8_t *p = data; | ||
| 312 | u_int8_t c1, c2; | ||
| 313 | |||
| 314 | while (p < data + len) { | ||
| 315 | c1 = *p++; | ||
| 316 | *bp++ = Base64Code[(c1 >> 2)]; | ||
| 317 | c1 = (c1 & 0x03) << 4; | ||
| 318 | if (p >= data + len) { | ||
| 319 | *bp++ = Base64Code[c1]; | ||
| 320 | break; | ||
| 321 | } | ||
| 322 | c2 = *p++; | ||
| 323 | c1 |= (c2 >> 4) & 0x0f; | ||
| 324 | *bp++ = Base64Code[c1]; | ||
| 325 | c1 = (c2 & 0x0f) << 2; | ||
| 326 | if (p >= data + len) { | ||
| 327 | *bp++ = Base64Code[c1]; | ||
| 328 | break; | ||
| 329 | } | ||
| 330 | c2 = *p++; | ||
| 331 | c1 |= (c2 >> 6) & 0x03; | ||
| 332 | *bp++ = Base64Code[c1]; | ||
| 333 | *bp++ = Base64Code[c2 & 0x3f]; | ||
| 334 | } | ||
| 335 | *bp = '\0'; | ||
| 336 | return 0; | ||
| 337 | } | ||
| 338 | |||
| 339 | /* | ||
| 340 | * classic interface | ||
| 341 | */ | ||
| 342 | char * | ||
| 343 | bcrypt_gensalt(u_int8_t log_rounds) | ||
| 344 | { | ||
| 345 | static char gsalt[BCRYPT_SALTSPACE]; | ||
| 346 | |||
| 347 | bcrypt_initsalt(log_rounds, gsalt, sizeof(gsalt)); | ||
| 348 | |||
| 349 | return gsalt; | ||
| 350 | } | ||
| 351 | |||
| 352 | char * | ||
| 353 | bcrypt(const char *pass, const char *salt) | ||
| 354 | { | ||
| 355 | static char gencrypted[_PASSWORD_LEN]; | ||
| 356 | static char gerror[2]; | ||
| 357 | |||
| 358 | /* How do I handle errors ? Return ':' */ | ||
| 359 | strlcpy(gerror, ":", sizeof(gerror)); | ||
| 360 | if (bcrypt_hashpass(pass, salt, gencrypted, sizeof(gencrypted)) != 0) | ||
| 361 | return gerror; | ||
| 362 | |||
| 363 | return gencrypted; | ||
| 364 | } | ||
| 365 | |||
diff --git a/src/lib/libc/crypt/blowfish.3 b/src/lib/libc/crypt/blowfish.3 new file mode 100644 index 0000000000..d15bc8901d --- /dev/null +++ b/src/lib/libc/crypt/blowfish.3 | |||
| @@ -0,0 +1,106 @@ | |||
| 1 | .\" $OpenBSD: blowfish.3,v 1.22 2013/07/16 15:21:11 schwarze Exp $ | ||
| 2 | .\" | ||
| 3 | .\" Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de> | ||
| 4 | .\" All rights reserved. | ||
| 5 | .\" | ||
| 6 | .\" Redistribution and use in source and binary forms, with or without | ||
| 7 | .\" modification, are permitted provided that the following conditions | ||
| 8 | .\" are met: | ||
| 9 | .\" 1. Redistributions of source code must retain the above copyright | ||
| 10 | .\" notice, this list of conditions and the following disclaimer. | ||
| 11 | .\" 2. Redistributions in binary form must reproduce the above copyright | ||
| 12 | .\" notice, this list of conditions and the following disclaimer in the | ||
| 13 | .\" documentation and/or other materials provided with the distribution. | ||
| 14 | .\" 3. All advertising materials mentioning features or use of this software | ||
| 15 | .\" must display the following acknowledgement: | ||
| 16 | .\" This product includes software developed by Niels Provos. | ||
| 17 | .\" 4. The name of the author may not be used to endorse or promote products | ||
| 18 | .\" derived from this software without specific prior written permission. | ||
| 19 | .\" | ||
| 20 | .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | ||
| 21 | .\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
| 22 | .\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
| 23 | .\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 24 | .\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
| 25 | .\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
| 26 | .\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
| 27 | .\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| 28 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
| 29 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 30 | .\" | ||
| 31 | .\" Manual page, using -mandoc macros | ||
| 32 | .\" | ||
| 33 | .Dd $Mdocdate: July 16 2013 $ | ||
| 34 | .Dt BLOWFISH 3 | ||
| 35 | .Os | ||
| 36 | .Sh NAME | ||
| 37 | .Nm blf_key , | ||
| 38 | .Nm blf_enc , | ||
| 39 | .Nm blf_dec , | ||
| 40 | .Nm blf_ecb_encrypt , | ||
| 41 | .Nm blf_ecb_decrypt , | ||
| 42 | .Nm blf_cbc_encrypt , | ||
| 43 | .Nm blf_cbc_decrypt | ||
| 44 | .Nd Blowfish encryption | ||
| 45 | .Sh SYNOPSIS | ||
| 46 | .In blf.h | ||
| 47 | .Ft void | ||
| 48 | .Fn blf_key "blf_ctx *state" "const u_int8_t *key" "u_int16_t keylen" | ||
| 49 | .Ft void | ||
| 50 | .Fn blf_enc "blf_ctx *state" "u_int32_t *data" "u_int16_t blocks" | ||
| 51 | .Ft void | ||
| 52 | .Fn blf_dec "blf_ctx *state" "u_int32_t *data" "u_int16_t blocks" | ||
| 53 | .Ft void | ||
| 54 | .Fn blf_ecb_encrypt "blf_ctx *state" "u_int8_t *data" "u_int32_t datalen" | ||
| 55 | .Ft void | ||
| 56 | .Fn blf_ecb_decrypt "blf_ctx *state" "u_int8_t *data" "u_int32_t datalen" | ||
| 57 | .Ft void | ||
| 58 | .Fn blf_cbc_encrypt "blf_ctx *state" "u_int8_t *iv" "u_int8_t *data" "u_int32_t datalen" | ||
| 59 | .Ft void | ||
| 60 | .Fn blf_cbc_decrypt "blf_ctx *state" "u_int8_t *iv" "u_int8_t *data" "u_int32_t datalen" | ||
| 61 | .Sh DESCRIPTION | ||
| 62 | .Em Blowfish | ||
| 63 | is a fast unpatented block cipher designed by Bruce Schneier. | ||
| 64 | It basically consists of a 16-round Feistel network. | ||
| 65 | The block size is 64 bits and the maximum key size is 448 bits. | ||
| 66 | .Pp | ||
| 67 | The | ||
| 68 | .Fn blf_key | ||
| 69 | function initializes the 4 8-bit S-boxes and the 18 Subkeys with | ||
| 70 | the hexadecimal digits of Pi. | ||
| 71 | The key is used for further randomization. | ||
| 72 | The first argument to | ||
| 73 | .Fn blf_enc | ||
| 74 | is the initialized state derived from | ||
| 75 | .Fn blf_key . | ||
| 76 | The stream of 32-bit words is encrypted in Electronic Codebook | ||
| 77 | Mode (ECB) and | ||
| 78 | .Fa blocks | ||
| 79 | is the number of 64-bit blocks in the stream. | ||
| 80 | .Fn blf_dec | ||
| 81 | is used for decrypting Blowfish encrypted blocks. | ||
| 82 | .Pp | ||
| 83 | The functions | ||
| 84 | .Fn blf_ecb_encrypt | ||
| 85 | and | ||
| 86 | .Fn blf_ecb_decrypt | ||
| 87 | are used for encrypting and decrypting octet streams in ECB mode. | ||
| 88 | The functions | ||
| 89 | .Fn blf_cbc_encrypt | ||
| 90 | and | ||
| 91 | .Fn blf_cbc_decrypt | ||
| 92 | are used for encrypting and decrypting octet streams in | ||
| 93 | Cipherblock Chaining Mode (CBC). | ||
| 94 | For these functions | ||
| 95 | .Fa datalen | ||
| 96 | specifies the number of octets of data to encrypt or decrypt. | ||
| 97 | It must be a multiple of 8 (64-bit block). | ||
| 98 | The initialisation vector | ||
| 99 | .Fa iv | ||
| 100 | points to an 8-byte buffer. | ||
| 101 | .Sh SEE ALSO | ||
| 102 | .Xr passwd 1 , | ||
| 103 | .Xr crypt 3 , | ||
| 104 | .Xr passwd 5 | ||
| 105 | .Sh AUTHORS | ||
| 106 | .An Niels Provos Aq Mt 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..c337df8a0a --- /dev/null +++ b/src/lib/libc/crypt/blowfish.c | |||
| @@ -0,0 +1,685 @@ | |||
| 1 | /* $OpenBSD: blowfish.c,v 1.18 2004/11/02 17:23:26 hshoexer Exp $ */ | ||
| 2 | /* | ||
| 3 | * Blowfish block cipher for OpenBSD | ||
| 4 | * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de> | ||
| 5 | * All rights reserved. | ||
| 6 | * | ||
| 7 | * Implementation advice by David Mazieres <dm@lcs.mit.edu>. | ||
| 8 | * | ||
| 9 | * Redistribution and use in source and binary forms, with or without | ||
| 10 | * modification, are permitted provided that the following conditions | ||
| 11 | * are met: | ||
| 12 | * 1. Redistributions of source code must retain the above copyright | ||
| 13 | * notice, this list of conditions and the following disclaimer. | ||
| 14 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 15 | * notice, this list of conditions and the following disclaimer in the | ||
| 16 | * documentation and/or other materials provided with the distribution. | ||
| 17 | * 3. All advertising materials mentioning features or use of this software | ||
| 18 | * must display the following acknowledgement: | ||
| 19 | * This product includes software developed by Niels Provos. | ||
| 20 | * 4. The name of the author may not be used to endorse or promote products | ||
| 21 | * derived from this software without specific prior written permission. | ||
| 22 | * | ||
| 23 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | ||
| 24 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
| 25 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
| 26 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 27 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
| 28 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
| 29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
| 30 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| 31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
| 32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 33 | */ | ||
| 34 | |||
| 35 | /* | ||
| 36 | * This code is derived from section 14.3 and the given source | ||
| 37 | * in section V of Applied Cryptography, second edition. | ||
| 38 | * Blowfish is an unpatented fast block cipher designed by | ||
| 39 | * Bruce Schneier. | ||
| 40 | */ | ||
| 41 | |||
| 42 | #if 0 | ||
| 43 | #include <stdio.h> /* used for debugging */ | ||
| 44 | #include <string.h> | ||
| 45 | #endif | ||
| 46 | |||
| 47 | #include <sys/types.h> | ||
| 48 | #include <blf.h> | ||
| 49 | |||
| 50 | #undef inline | ||
| 51 | #ifdef __GNUC__ | ||
| 52 | #define inline __inline | ||
| 53 | #else /* !__GNUC__ */ | ||
| 54 | #define inline | ||
| 55 | #endif /* !__GNUC__ */ | ||
| 56 | |||
| 57 | /* Function for Feistel Networks */ | ||
| 58 | |||
| 59 | #define F(s, x) ((((s)[ (((x)>>24)&0xFF)] \ | ||
| 60 | + (s)[0x100 + (((x)>>16)&0xFF)]) \ | ||
| 61 | ^ (s)[0x200 + (((x)>> 8)&0xFF)]) \ | ||
| 62 | + (s)[0x300 + ( (x) &0xFF)]) | ||
| 63 | |||
| 64 | #define BLFRND(s,p,i,j,n) (i ^= F(s,j) ^ (p)[n]) | ||
| 65 | |||
| 66 | void | ||
| 67 | Blowfish_encipher(blf_ctx *c, u_int32_t *xl, u_int32_t *xr) | ||
| 68 | { | ||
| 69 | u_int32_t Xl; | ||
| 70 | u_int32_t Xr; | ||
| 71 | u_int32_t *s = c->S[0]; | ||
| 72 | u_int32_t *p = c->P; | ||
| 73 | |||
| 74 | Xl = *xl; | ||
| 75 | Xr = *xr; | ||
| 76 | |||
| 77 | Xl ^= p[0]; | ||
| 78 | BLFRND(s, p, Xr, Xl, 1); BLFRND(s, p, Xl, Xr, 2); | ||
| 79 | BLFRND(s, p, Xr, Xl, 3); BLFRND(s, p, Xl, Xr, 4); | ||
| 80 | BLFRND(s, p, Xr, Xl, 5); BLFRND(s, p, Xl, Xr, 6); | ||
| 81 | BLFRND(s, p, Xr, Xl, 7); BLFRND(s, p, Xl, Xr, 8); | ||
| 82 | BLFRND(s, p, Xr, Xl, 9); BLFRND(s, p, Xl, Xr, 10); | ||
| 83 | BLFRND(s, p, Xr, Xl, 11); BLFRND(s, p, Xl, Xr, 12); | ||
| 84 | BLFRND(s, p, Xr, Xl, 13); BLFRND(s, p, Xl, Xr, 14); | ||
| 85 | BLFRND(s, p, Xr, Xl, 15); BLFRND(s, p, Xl, Xr, 16); | ||
| 86 | |||
| 87 | *xl = Xr ^ p[17]; | ||
| 88 | *xr = Xl; | ||
| 89 | } | ||
| 90 | |||
| 91 | void | ||
| 92 | Blowfish_decipher(blf_ctx *c, u_int32_t *xl, u_int32_t *xr) | ||
| 93 | { | ||
| 94 | u_int32_t Xl; | ||
| 95 | u_int32_t Xr; | ||
| 96 | u_int32_t *s = c->S[0]; | ||
| 97 | u_int32_t *p = c->P; | ||
| 98 | |||
| 99 | Xl = *xl; | ||
| 100 | Xr = *xr; | ||
| 101 | |||
| 102 | Xl ^= p[17]; | ||
| 103 | BLFRND(s, p, Xr, Xl, 16); BLFRND(s, p, Xl, Xr, 15); | ||
| 104 | BLFRND(s, p, Xr, Xl, 14); BLFRND(s, p, Xl, Xr, 13); | ||
| 105 | BLFRND(s, p, Xr, Xl, 12); BLFRND(s, p, Xl, Xr, 11); | ||
| 106 | BLFRND(s, p, Xr, Xl, 10); BLFRND(s, p, Xl, Xr, 9); | ||
| 107 | BLFRND(s, p, Xr, Xl, 8); BLFRND(s, p, Xl, Xr, 7); | ||
| 108 | BLFRND(s, p, Xr, Xl, 6); BLFRND(s, p, Xl, Xr, 5); | ||
| 109 | BLFRND(s, p, Xr, Xl, 4); BLFRND(s, p, Xl, Xr, 3); | ||
| 110 | BLFRND(s, p, Xr, Xl, 2); BLFRND(s, p, Xl, Xr, 1); | ||
| 111 | |||
| 112 | *xl = Xr ^ p[0]; | ||
| 113 | *xr = Xl; | ||
| 114 | } | ||
| 115 | |||
| 116 | void | ||
| 117 | Blowfish_initstate(blf_ctx *c) | ||
| 118 | { | ||
| 119 | /* P-box and S-box tables initialized with digits of Pi */ | ||
| 120 | |||
| 121 | static const blf_ctx initstate = | ||
| 122 | { { | ||
| 123 | { | ||
| 124 | 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, | ||
| 125 | 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, | ||
| 126 | 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, | ||
| 127 | 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, | ||
| 128 | 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, | ||
| 129 | 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, | ||
| 130 | 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, | ||
| 131 | 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, | ||
| 132 | 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, | ||
| 133 | 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, | ||
| 134 | 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, | ||
| 135 | 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, | ||
| 136 | 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, | ||
| 137 | 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, | ||
| 138 | 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, | ||
| 139 | 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, | ||
| 140 | 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, | ||
| 141 | 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, | ||
| 142 | 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, | ||
| 143 | 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, | ||
| 144 | 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, | ||
| 145 | 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, | ||
| 146 | 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, | ||
| 147 | 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, | ||
| 148 | 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, | ||
| 149 | 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, | ||
| 150 | 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, | ||
| 151 | 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, | ||
| 152 | 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, | ||
| 153 | 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, | ||
| 154 | 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, | ||
| 155 | 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, | ||
| 156 | 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, | ||
| 157 | 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, | ||
| 158 | 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, | ||
| 159 | 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, | ||
| 160 | 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, | ||
| 161 | 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, | ||
| 162 | 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, | ||
| 163 | 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, | ||
| 164 | 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, | ||
| 165 | 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, | ||
| 166 | 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, | ||
| 167 | 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, | ||
| 168 | 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, | ||
| 169 | 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, | ||
| 170 | 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, | ||
| 171 | 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, | ||
| 172 | 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, | ||
| 173 | 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, | ||
| 174 | 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, | ||
| 175 | 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, | ||
| 176 | 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, | ||
| 177 | 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, | ||
| 178 | 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, | ||
| 179 | 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, | ||
| 180 | 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, | ||
| 181 | 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, | ||
| 182 | 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, | ||
| 183 | 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, | ||
| 184 | 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, | ||
| 185 | 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, | ||
| 186 | 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, | ||
| 187 | 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a}, | ||
| 188 | { | ||
| 189 | 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, | ||
| 190 | 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, | ||
| 191 | 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, | ||
| 192 | 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, | ||
| 193 | 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, | ||
| 194 | 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, | ||
| 195 | 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, | ||
| 196 | 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, | ||
| 197 | 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, | ||
| 198 | 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, | ||
| 199 | 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, | ||
| 200 | 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, | ||
| 201 | 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, | ||
| 202 | 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, | ||
| 203 | 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, | ||
| 204 | 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, | ||
| 205 | 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, | ||
| 206 | 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, | ||
| 207 | 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, | ||
| 208 | 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, | ||
| 209 | 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, | ||
| 210 | 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, | ||
| 211 | 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, | ||
| 212 | 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, | ||
| 213 | 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, | ||
| 214 | 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, | ||
| 215 | 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, | ||
| 216 | 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, | ||
| 217 | 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, | ||
| 218 | 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, | ||
| 219 | 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, | ||
| 220 | 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, | ||
| 221 | 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, | ||
| 222 | 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, | ||
| 223 | 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, | ||
| 224 | 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, | ||
| 225 | 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, | ||
| 226 | 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, | ||
| 227 | 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, | ||
| 228 | 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, | ||
| 229 | 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, | ||
| 230 | 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, | ||
| 231 | 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, | ||
| 232 | 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, | ||
| 233 | 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, | ||
| 234 | 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, | ||
| 235 | 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, | ||
| 236 | 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, | ||
| 237 | 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, | ||
| 238 | 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, | ||
| 239 | 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, | ||
| 240 | 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, | ||
| 241 | 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, | ||
| 242 | 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, | ||
| 243 | 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, | ||
| 244 | 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, | ||
| 245 | 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, | ||
| 246 | 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, | ||
| 247 | 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, | ||
| 248 | 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, | ||
| 249 | 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, | ||
| 250 | 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, | ||
| 251 | 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, | ||
| 252 | 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7}, | ||
| 253 | { | ||
| 254 | 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, | ||
| 255 | 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, | ||
| 256 | 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, | ||
| 257 | 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, | ||
| 258 | 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, | ||
| 259 | 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, | ||
| 260 | 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, | ||
| 261 | 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, | ||
| 262 | 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, | ||
| 263 | 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, | ||
| 264 | 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, | ||
| 265 | 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, | ||
| 266 | 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, | ||
| 267 | 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, | ||
| 268 | 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, | ||
| 269 | 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, | ||
| 270 | 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, | ||
| 271 | 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, | ||
| 272 | 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, | ||
| 273 | 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, | ||
| 274 | 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, | ||
| 275 | 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, | ||
| 276 | 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, | ||
| 277 | 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, | ||
| 278 | 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, | ||
| 279 | 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, | ||
| 280 | 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, | ||
| 281 | 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, | ||
| 282 | 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, | ||
| 283 | 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, | ||
| 284 | 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, | ||
| 285 | 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, | ||
| 286 | 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, | ||
| 287 | 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, | ||
| 288 | 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, | ||
| 289 | 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, | ||
| 290 | 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, | ||
| 291 | 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, | ||
| 292 | 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, | ||
| 293 | 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, | ||
| 294 | 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, | ||
| 295 | 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, | ||
| 296 | 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, | ||
| 297 | 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, | ||
| 298 | 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, | ||
| 299 | 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, | ||
| 300 | 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, | ||
| 301 | 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, | ||
| 302 | 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, | ||
| 303 | 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, | ||
| 304 | 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, | ||
| 305 | 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, | ||
| 306 | 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, | ||
| 307 | 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, | ||
| 308 | 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, | ||
| 309 | 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, | ||
| 310 | 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, | ||
| 311 | 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, | ||
| 312 | 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, | ||
| 313 | 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, | ||
| 314 | 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, | ||
| 315 | 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, | ||
| 316 | 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, | ||
| 317 | 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0}, | ||
| 318 | { | ||
| 319 | 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, | ||
| 320 | 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, | ||
| 321 | 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, | ||
| 322 | 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, | ||
| 323 | 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, | ||
| 324 | 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, | ||
| 325 | 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, | ||
| 326 | 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, | ||
| 327 | 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, | ||
| 328 | 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, | ||
| 329 | 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, | ||
| 330 | 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, | ||
| 331 | 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, | ||
| 332 | 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, | ||
| 333 | 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, | ||
| 334 | 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, | ||
| 335 | 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, | ||
| 336 | 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, | ||
| 337 | 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, | ||
| 338 | 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, | ||
| 339 | 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, | ||
| 340 | 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, | ||
| 341 | 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, | ||
| 342 | 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, | ||
| 343 | 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, | ||
| 344 | 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, | ||
| 345 | 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, | ||
| 346 | 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, | ||
| 347 | 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, | ||
| 348 | 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, | ||
| 349 | 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, | ||
| 350 | 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, | ||
| 351 | 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, | ||
| 352 | 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, | ||
| 353 | 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, | ||
| 354 | 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, | ||
| 355 | 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, | ||
| 356 | 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, | ||
| 357 | 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, | ||
| 358 | 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, | ||
| 359 | 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, | ||
| 360 | 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, | ||
| 361 | 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, | ||
| 362 | 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, | ||
| 363 | 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, | ||
| 364 | 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, | ||
| 365 | 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, | ||
| 366 | 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, | ||
| 367 | 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, | ||
| 368 | 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, | ||
| 369 | 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, | ||
| 370 | 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, | ||
| 371 | 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, | ||
| 372 | 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, | ||
| 373 | 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, | ||
| 374 | 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, | ||
| 375 | 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, | ||
| 376 | 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, | ||
| 377 | 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, | ||
| 378 | 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, | ||
| 379 | 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, | ||
| 380 | 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, | ||
| 381 | 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, | ||
| 382 | 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6} | ||
| 383 | }, | ||
| 384 | { | ||
| 385 | 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, | ||
| 386 | 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, | ||
| 387 | 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, | ||
| 388 | 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, | ||
| 389 | 0x9216d5d9, 0x8979fb1b | ||
| 390 | } }; | ||
| 391 | |||
| 392 | *c = initstate; | ||
| 393 | } | ||
| 394 | |||
| 395 | u_int32_t | ||
| 396 | Blowfish_stream2word(const u_int8_t *data, u_int16_t databytes, | ||
| 397 | u_int16_t *current) | ||
| 398 | { | ||
| 399 | u_int8_t i; | ||
| 400 | u_int16_t j; | ||
| 401 | u_int32_t temp; | ||
| 402 | |||
| 403 | temp = 0x00000000; | ||
| 404 | j = *current; | ||
| 405 | |||
| 406 | for (i = 0; i < 4; i++, j++) { | ||
| 407 | if (j >= databytes) | ||
| 408 | j = 0; | ||
| 409 | temp = (temp << 8) | data[j]; | ||
| 410 | } | ||
| 411 | |||
| 412 | *current = j; | ||
| 413 | return temp; | ||
| 414 | } | ||
| 415 | |||
| 416 | void | ||
| 417 | Blowfish_expand0state(blf_ctx *c, const u_int8_t *key, u_int16_t keybytes) | ||
| 418 | { | ||
| 419 | u_int16_t i; | ||
| 420 | u_int16_t j; | ||
| 421 | u_int16_t k; | ||
| 422 | u_int32_t temp; | ||
| 423 | u_int32_t datal; | ||
| 424 | u_int32_t datar; | ||
| 425 | |||
| 426 | j = 0; | ||
| 427 | for (i = 0; i < BLF_N + 2; i++) { | ||
| 428 | /* Extract 4 int8 to 1 int32 from keystream */ | ||
| 429 | temp = Blowfish_stream2word(key, keybytes, &j); | ||
| 430 | c->P[i] = c->P[i] ^ temp; | ||
| 431 | } | ||
| 432 | |||
| 433 | j = 0; | ||
| 434 | datal = 0x00000000; | ||
| 435 | datar = 0x00000000; | ||
| 436 | for (i = 0; i < BLF_N + 2; i += 2) { | ||
| 437 | Blowfish_encipher(c, &datal, &datar); | ||
| 438 | |||
| 439 | c->P[i] = datal; | ||
| 440 | c->P[i + 1] = datar; | ||
| 441 | } | ||
| 442 | |||
| 443 | for (i = 0; i < 4; i++) { | ||
| 444 | for (k = 0; k < 256; k += 2) { | ||
| 445 | Blowfish_encipher(c, &datal, &datar); | ||
| 446 | |||
| 447 | c->S[i][k] = datal; | ||
| 448 | c->S[i][k + 1] = datar; | ||
| 449 | } | ||
| 450 | } | ||
| 451 | } | ||
| 452 | |||
| 453 | |||
| 454 | void | ||
| 455 | Blowfish_expandstate(blf_ctx *c, const u_int8_t *data, u_int16_t databytes, | ||
| 456 | const u_int8_t *key, u_int16_t keybytes) | ||
| 457 | { | ||
| 458 | u_int16_t i; | ||
| 459 | u_int16_t j; | ||
| 460 | u_int16_t k; | ||
| 461 | u_int32_t temp; | ||
| 462 | u_int32_t datal; | ||
| 463 | u_int32_t datar; | ||
| 464 | |||
| 465 | j = 0; | ||
| 466 | for (i = 0; i < BLF_N + 2; i++) { | ||
| 467 | /* Extract 4 int8 to 1 int32 from keystream */ | ||
| 468 | temp = Blowfish_stream2word(key, keybytes, &j); | ||
| 469 | c->P[i] = c->P[i] ^ temp; | ||
| 470 | } | ||
| 471 | |||
| 472 | j = 0; | ||
| 473 | datal = 0x00000000; | ||
| 474 | datar = 0x00000000; | ||
| 475 | for (i = 0; i < BLF_N + 2; i += 2) { | ||
| 476 | datal ^= Blowfish_stream2word(data, databytes, &j); | ||
| 477 | datar ^= Blowfish_stream2word(data, databytes, &j); | ||
| 478 | Blowfish_encipher(c, &datal, &datar); | ||
| 479 | |||
| 480 | c->P[i] = datal; | ||
| 481 | c->P[i + 1] = datar; | ||
| 482 | } | ||
| 483 | |||
| 484 | for (i = 0; i < 4; i++) { | ||
| 485 | for (k = 0; k < 256; k += 2) { | ||
| 486 | datal ^= Blowfish_stream2word(data, databytes, &j); | ||
| 487 | datar ^= Blowfish_stream2word(data, databytes, &j); | ||
| 488 | Blowfish_encipher(c, &datal, &datar); | ||
| 489 | |||
| 490 | c->S[i][k] = datal; | ||
| 491 | c->S[i][k + 1] = datar; | ||
| 492 | } | ||
| 493 | } | ||
| 494 | |||
| 495 | } | ||
| 496 | |||
| 497 | void | ||
| 498 | blf_key(blf_ctx *c, const u_int8_t *k, u_int16_t len) | ||
| 499 | { | ||
| 500 | /* Initialize S-boxes and subkeys with Pi */ | ||
| 501 | Blowfish_initstate(c); | ||
| 502 | |||
| 503 | /* Transform S-boxes and subkeys with key */ | ||
| 504 | Blowfish_expand0state(c, k, len); | ||
| 505 | } | ||
| 506 | |||
| 507 | void | ||
| 508 | blf_enc(blf_ctx *c, u_int32_t *data, u_int16_t blocks) | ||
| 509 | { | ||
| 510 | u_int32_t *d; | ||
| 511 | u_int16_t i; | ||
| 512 | |||
| 513 | d = data; | ||
| 514 | for (i = 0; i < blocks; i++) { | ||
| 515 | Blowfish_encipher(c, d, d + 1); | ||
| 516 | d += 2; | ||
| 517 | } | ||
| 518 | } | ||
| 519 | |||
| 520 | void | ||
| 521 | blf_dec(blf_ctx *c, u_int32_t *data, u_int16_t blocks) | ||
| 522 | { | ||
| 523 | u_int32_t *d; | ||
| 524 | u_int16_t i; | ||
| 525 | |||
| 526 | d = data; | ||
| 527 | for (i = 0; i < blocks; i++) { | ||
| 528 | Blowfish_decipher(c, d, d + 1); | ||
| 529 | d += 2; | ||
| 530 | } | ||
| 531 | } | ||
| 532 | |||
| 533 | void | ||
| 534 | blf_ecb_encrypt(blf_ctx *c, u_int8_t *data, u_int32_t len) | ||
| 535 | { | ||
| 536 | u_int32_t l, r; | ||
| 537 | u_int32_t i; | ||
| 538 | |||
| 539 | for (i = 0; i < len; i += 8) { | ||
| 540 | l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; | ||
| 541 | r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; | ||
| 542 | Blowfish_encipher(c, &l, &r); | ||
| 543 | data[0] = l >> 24 & 0xff; | ||
| 544 | data[1] = l >> 16 & 0xff; | ||
| 545 | data[2] = l >> 8 & 0xff; | ||
| 546 | data[3] = l & 0xff; | ||
| 547 | data[4] = r >> 24 & 0xff; | ||
| 548 | data[5] = r >> 16 & 0xff; | ||
| 549 | data[6] = r >> 8 & 0xff; | ||
| 550 | data[7] = r & 0xff; | ||
| 551 | data += 8; | ||
| 552 | } | ||
| 553 | } | ||
| 554 | |||
| 555 | void | ||
| 556 | blf_ecb_decrypt(blf_ctx *c, u_int8_t *data, u_int32_t len) | ||
| 557 | { | ||
| 558 | u_int32_t l, r; | ||
| 559 | u_int32_t i; | ||
| 560 | |||
| 561 | for (i = 0; i < len; i += 8) { | ||
| 562 | l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; | ||
| 563 | r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; | ||
| 564 | Blowfish_decipher(c, &l, &r); | ||
| 565 | data[0] = l >> 24 & 0xff; | ||
| 566 | data[1] = l >> 16 & 0xff; | ||
| 567 | data[2] = l >> 8 & 0xff; | ||
| 568 | data[3] = l & 0xff; | ||
| 569 | data[4] = r >> 24 & 0xff; | ||
| 570 | data[5] = r >> 16 & 0xff; | ||
| 571 | data[6] = r >> 8 & 0xff; | ||
| 572 | data[7] = r & 0xff; | ||
| 573 | data += 8; | ||
| 574 | } | ||
| 575 | } | ||
| 576 | |||
| 577 | void | ||
| 578 | blf_cbc_encrypt(blf_ctx *c, u_int8_t *iv, u_int8_t *data, u_int32_t len) | ||
| 579 | { | ||
| 580 | u_int32_t l, r; | ||
| 581 | u_int32_t i, j; | ||
| 582 | |||
| 583 | for (i = 0; i < len; i += 8) { | ||
| 584 | for (j = 0; j < 8; j++) | ||
| 585 | data[j] ^= iv[j]; | ||
| 586 | l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; | ||
| 587 | r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; | ||
| 588 | Blowfish_encipher(c, &l, &r); | ||
| 589 | data[0] = l >> 24 & 0xff; | ||
| 590 | data[1] = l >> 16 & 0xff; | ||
| 591 | data[2] = l >> 8 & 0xff; | ||
| 592 | data[3] = l & 0xff; | ||
| 593 | data[4] = r >> 24 & 0xff; | ||
| 594 | data[5] = r >> 16 & 0xff; | ||
| 595 | data[6] = r >> 8 & 0xff; | ||
| 596 | data[7] = r & 0xff; | ||
| 597 | iv = data; | ||
| 598 | data += 8; | ||
| 599 | } | ||
| 600 | } | ||
| 601 | |||
| 602 | void | ||
| 603 | blf_cbc_decrypt(blf_ctx *c, u_int8_t *iva, u_int8_t *data, u_int32_t len) | ||
| 604 | { | ||
| 605 | u_int32_t l, r; | ||
| 606 | u_int8_t *iv; | ||
| 607 | u_int32_t i, j; | ||
| 608 | |||
| 609 | iv = data + len - 16; | ||
| 610 | data = data + len - 8; | ||
| 611 | for (i = len - 8; i >= 8; i -= 8) { | ||
| 612 | l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; | ||
| 613 | r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; | ||
| 614 | Blowfish_decipher(c, &l, &r); | ||
| 615 | data[0] = l >> 24 & 0xff; | ||
| 616 | data[1] = l >> 16 & 0xff; | ||
| 617 | data[2] = l >> 8 & 0xff; | ||
| 618 | data[3] = l & 0xff; | ||
| 619 | data[4] = r >> 24 & 0xff; | ||
| 620 | data[5] = r >> 16 & 0xff; | ||
| 621 | data[6] = r >> 8 & 0xff; | ||
| 622 | data[7] = r & 0xff; | ||
| 623 | for (j = 0; j < 8; j++) | ||
| 624 | data[j] ^= iv[j]; | ||
| 625 | iv -= 8; | ||
| 626 | data -= 8; | ||
| 627 | } | ||
| 628 | l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; | ||
| 629 | r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; | ||
| 630 | Blowfish_decipher(c, &l, &r); | ||
| 631 | data[0] = l >> 24 & 0xff; | ||
| 632 | data[1] = l >> 16 & 0xff; | ||
| 633 | data[2] = l >> 8 & 0xff; | ||
| 634 | data[3] = l & 0xff; | ||
| 635 | data[4] = r >> 24 & 0xff; | ||
| 636 | data[5] = r >> 16 & 0xff; | ||
| 637 | data[6] = r >> 8 & 0xff; | ||
| 638 | data[7] = r & 0xff; | ||
| 639 | for (j = 0; j < 8; j++) | ||
| 640 | data[j] ^= iva[j]; | ||
| 641 | } | ||
| 642 | |||
| 643 | #if 0 | ||
| 644 | void | ||
| 645 | report(u_int32_t data[], u_int16_t len) | ||
| 646 | { | ||
| 647 | u_int16_t i; | ||
| 648 | for (i = 0; i < len; i += 2) | ||
| 649 | printf("Block %0hd: %08lx %08lx.\n", | ||
| 650 | i / 2, data[i], data[i + 1]); | ||
| 651 | } | ||
| 652 | void | ||
| 653 | main(void) | ||
| 654 | { | ||
| 655 | |||
| 656 | blf_ctx c; | ||
| 657 | char key[] = "AAAAA"; | ||
| 658 | char key2[] = "abcdefghijklmnopqrstuvwxyz"; | ||
| 659 | |||
| 660 | u_int32_t data[10]; | ||
| 661 | u_int32_t data2[] = | ||
| 662 | {0x424c4f57l, 0x46495348l}; | ||
| 663 | |||
| 664 | u_int16_t i; | ||
| 665 | |||
| 666 | /* First test */ | ||
| 667 | for (i = 0; i < 10; i++) | ||
| 668 | data[i] = i; | ||
| 669 | |||
| 670 | blf_key(&c, (u_int8_t *) key, 5); | ||
| 671 | blf_enc(&c, data, 5); | ||
| 672 | blf_dec(&c, data, 1); | ||
| 673 | blf_dec(&c, data + 2, 4); | ||
| 674 | printf("Should read as 0 - 9.\n"); | ||
| 675 | report(data, 10); | ||
| 676 | |||
| 677 | /* Second test */ | ||
| 678 | blf_key(&c, (u_int8_t *) key2, strlen(key2)); | ||
| 679 | blf_enc(&c, data2, 1); | ||
| 680 | printf("\nShould read as: 0x324ed0fe 0xf413a203.\n"); | ||
| 681 | report(data2, 2); | ||
| 682 | blf_dec(&c, data2, 1); | ||
| 683 | report(data2, 2); | ||
| 684 | } | ||
| 685 | #endif | ||
diff --git a/src/lib/libc/crypt/chacha_private.h b/src/lib/libc/crypt/chacha_private.h new file mode 100644 index 0000000000..7c3680fa6d --- /dev/null +++ b/src/lib/libc/crypt/chacha_private.h | |||
| @@ -0,0 +1,222 @@ | |||
| 1 | /* | ||
| 2 | chacha-merged.c version 20080118 | ||
| 3 | D. J. Bernstein | ||
| 4 | Public domain. | ||
| 5 | */ | ||
| 6 | |||
| 7 | /* $OpenBSD: chacha_private.h,v 1.2 2013/10/04 07:02:27 djm Exp $ */ | ||
| 8 | |||
| 9 | typedef unsigned char u8; | ||
| 10 | typedef unsigned int u32; | ||
| 11 | |||
| 12 | typedef struct | ||
| 13 | { | ||
| 14 | u32 input[16]; /* could be compressed */ | ||
| 15 | } chacha_ctx; | ||
| 16 | |||
| 17 | #define U8C(v) (v##U) | ||
| 18 | #define U32C(v) (v##U) | ||
| 19 | |||
| 20 | #define U8V(v) ((u8)(v) & U8C(0xFF)) | ||
| 21 | #define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF)) | ||
| 22 | |||
| 23 | #define ROTL32(v, n) \ | ||
| 24 | (U32V((v) << (n)) | ((v) >> (32 - (n)))) | ||
| 25 | |||
| 26 | #define U8TO32_LITTLE(p) \ | ||
| 27 | (((u32)((p)[0]) ) | \ | ||
| 28 | ((u32)((p)[1]) << 8) | \ | ||
| 29 | ((u32)((p)[2]) << 16) | \ | ||
| 30 | ((u32)((p)[3]) << 24)) | ||
| 31 | |||
| 32 | #define U32TO8_LITTLE(p, v) \ | ||
| 33 | do { \ | ||
| 34 | (p)[0] = U8V((v) ); \ | ||
| 35 | (p)[1] = U8V((v) >> 8); \ | ||
| 36 | (p)[2] = U8V((v) >> 16); \ | ||
| 37 | (p)[3] = U8V((v) >> 24); \ | ||
| 38 | } while (0) | ||
| 39 | |||
| 40 | #define ROTATE(v,c) (ROTL32(v,c)) | ||
| 41 | #define XOR(v,w) ((v) ^ (w)) | ||
| 42 | #define PLUS(v,w) (U32V((v) + (w))) | ||
| 43 | #define PLUSONE(v) (PLUS((v),1)) | ||
| 44 | |||
| 45 | #define QUARTERROUND(a,b,c,d) \ | ||
| 46 | a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \ | ||
| 47 | c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \ | ||
| 48 | a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \ | ||
| 49 | c = PLUS(c,d); b = ROTATE(XOR(b,c), 7); | ||
| 50 | |||
| 51 | static const char sigma[16] = "expand 32-byte k"; | ||
| 52 | static const char tau[16] = "expand 16-byte k"; | ||
| 53 | |||
| 54 | static void | ||
| 55 | chacha_keysetup(chacha_ctx *x,const u8 *k,u32 kbits,u32 ivbits) | ||
| 56 | { | ||
| 57 | const char *constants; | ||
| 58 | |||
| 59 | x->input[4] = U8TO32_LITTLE(k + 0); | ||
| 60 | x->input[5] = U8TO32_LITTLE(k + 4); | ||
| 61 | x->input[6] = U8TO32_LITTLE(k + 8); | ||
| 62 | x->input[7] = U8TO32_LITTLE(k + 12); | ||
| 63 | if (kbits == 256) { /* recommended */ | ||
| 64 | k += 16; | ||
| 65 | constants = sigma; | ||
| 66 | } else { /* kbits == 128 */ | ||
| 67 | constants = tau; | ||
| 68 | } | ||
| 69 | x->input[8] = U8TO32_LITTLE(k + 0); | ||
| 70 | x->input[9] = U8TO32_LITTLE(k + 4); | ||
| 71 | x->input[10] = U8TO32_LITTLE(k + 8); | ||
| 72 | x->input[11] = U8TO32_LITTLE(k + 12); | ||
| 73 | x->input[0] = U8TO32_LITTLE(constants + 0); | ||
| 74 | x->input[1] = U8TO32_LITTLE(constants + 4); | ||
| 75 | x->input[2] = U8TO32_LITTLE(constants + 8); | ||
| 76 | x->input[3] = U8TO32_LITTLE(constants + 12); | ||
| 77 | } | ||
| 78 | |||
| 79 | static void | ||
| 80 | chacha_ivsetup(chacha_ctx *x,const u8 *iv) | ||
| 81 | { | ||
| 82 | x->input[12] = 0; | ||
| 83 | x->input[13] = 0; | ||
| 84 | x->input[14] = U8TO32_LITTLE(iv + 0); | ||
| 85 | x->input[15] = U8TO32_LITTLE(iv + 4); | ||
| 86 | } | ||
| 87 | |||
| 88 | static void | ||
| 89 | chacha_encrypt_bytes(chacha_ctx *x,const u8 *m,u8 *c,u32 bytes) | ||
| 90 | { | ||
| 91 | u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; | ||
| 92 | u32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15; | ||
| 93 | u8 *ctarget = NULL; | ||
| 94 | u8 tmp[64]; | ||
| 95 | u_int i; | ||
| 96 | |||
| 97 | if (!bytes) return; | ||
| 98 | |||
| 99 | j0 = x->input[0]; | ||
| 100 | j1 = x->input[1]; | ||
| 101 | j2 = x->input[2]; | ||
| 102 | j3 = x->input[3]; | ||
| 103 | j4 = x->input[4]; | ||
| 104 | j5 = x->input[5]; | ||
| 105 | j6 = x->input[6]; | ||
| 106 | j7 = x->input[7]; | ||
| 107 | j8 = x->input[8]; | ||
| 108 | j9 = x->input[9]; | ||
| 109 | j10 = x->input[10]; | ||
| 110 | j11 = x->input[11]; | ||
| 111 | j12 = x->input[12]; | ||
| 112 | j13 = x->input[13]; | ||
| 113 | j14 = x->input[14]; | ||
| 114 | j15 = x->input[15]; | ||
| 115 | |||
| 116 | for (;;) { | ||
| 117 | if (bytes < 64) { | ||
| 118 | for (i = 0;i < bytes;++i) tmp[i] = m[i]; | ||
| 119 | m = tmp; | ||
| 120 | ctarget = c; | ||
| 121 | c = tmp; | ||
| 122 | } | ||
| 123 | x0 = j0; | ||
| 124 | x1 = j1; | ||
| 125 | x2 = j2; | ||
| 126 | x3 = j3; | ||
| 127 | x4 = j4; | ||
| 128 | x5 = j5; | ||
| 129 | x6 = j6; | ||
| 130 | x7 = j7; | ||
| 131 | x8 = j8; | ||
| 132 | x9 = j9; | ||
| 133 | x10 = j10; | ||
| 134 | x11 = j11; | ||
| 135 | x12 = j12; | ||
| 136 | x13 = j13; | ||
| 137 | x14 = j14; | ||
| 138 | x15 = j15; | ||
| 139 | for (i = 20;i > 0;i -= 2) { | ||
| 140 | QUARTERROUND( x0, x4, x8,x12) | ||
| 141 | QUARTERROUND( x1, x5, x9,x13) | ||
| 142 | QUARTERROUND( x2, x6,x10,x14) | ||
| 143 | QUARTERROUND( x3, x7,x11,x15) | ||
| 144 | QUARTERROUND( x0, x5,x10,x15) | ||
| 145 | QUARTERROUND( x1, x6,x11,x12) | ||
| 146 | QUARTERROUND( x2, x7, x8,x13) | ||
| 147 | QUARTERROUND( x3, x4, x9,x14) | ||
| 148 | } | ||
| 149 | x0 = PLUS(x0,j0); | ||
| 150 | x1 = PLUS(x1,j1); | ||
| 151 | x2 = PLUS(x2,j2); | ||
| 152 | x3 = PLUS(x3,j3); | ||
| 153 | x4 = PLUS(x4,j4); | ||
| 154 | x5 = PLUS(x5,j5); | ||
| 155 | x6 = PLUS(x6,j6); | ||
| 156 | x7 = PLUS(x7,j7); | ||
| 157 | x8 = PLUS(x8,j8); | ||
| 158 | x9 = PLUS(x9,j9); | ||
| 159 | x10 = PLUS(x10,j10); | ||
| 160 | x11 = PLUS(x11,j11); | ||
| 161 | x12 = PLUS(x12,j12); | ||
| 162 | x13 = PLUS(x13,j13); | ||
| 163 | x14 = PLUS(x14,j14); | ||
| 164 | x15 = PLUS(x15,j15); | ||
| 165 | |||
| 166 | #ifndef KEYSTREAM_ONLY | ||
| 167 | x0 = XOR(x0,U8TO32_LITTLE(m + 0)); | ||
| 168 | x1 = XOR(x1,U8TO32_LITTLE(m + 4)); | ||
| 169 | x2 = XOR(x2,U8TO32_LITTLE(m + 8)); | ||
| 170 | x3 = XOR(x3,U8TO32_LITTLE(m + 12)); | ||
| 171 | x4 = XOR(x4,U8TO32_LITTLE(m + 16)); | ||
| 172 | x5 = XOR(x5,U8TO32_LITTLE(m + 20)); | ||
| 173 | x6 = XOR(x6,U8TO32_LITTLE(m + 24)); | ||
| 174 | x7 = XOR(x7,U8TO32_LITTLE(m + 28)); | ||
| 175 | x8 = XOR(x8,U8TO32_LITTLE(m + 32)); | ||
| 176 | x9 = XOR(x9,U8TO32_LITTLE(m + 36)); | ||
| 177 | x10 = XOR(x10,U8TO32_LITTLE(m + 40)); | ||
| 178 | x11 = XOR(x11,U8TO32_LITTLE(m + 44)); | ||
| 179 | x12 = XOR(x12,U8TO32_LITTLE(m + 48)); | ||
| 180 | x13 = XOR(x13,U8TO32_LITTLE(m + 52)); | ||
| 181 | x14 = XOR(x14,U8TO32_LITTLE(m + 56)); | ||
| 182 | x15 = XOR(x15,U8TO32_LITTLE(m + 60)); | ||
| 183 | #endif | ||
| 184 | |||
| 185 | j12 = PLUSONE(j12); | ||
| 186 | if (!j12) { | ||
| 187 | j13 = PLUSONE(j13); | ||
| 188 | /* stopping at 2^70 bytes per nonce is user's responsibility */ | ||
| 189 | } | ||
| 190 | |||
| 191 | U32TO8_LITTLE(c + 0,x0); | ||
| 192 | U32TO8_LITTLE(c + 4,x1); | ||
| 193 | U32TO8_LITTLE(c + 8,x2); | ||
| 194 | U32TO8_LITTLE(c + 12,x3); | ||
| 195 | U32TO8_LITTLE(c + 16,x4); | ||
| 196 | U32TO8_LITTLE(c + 20,x5); | ||
| 197 | U32TO8_LITTLE(c + 24,x6); | ||
| 198 | U32TO8_LITTLE(c + 28,x7); | ||
| 199 | U32TO8_LITTLE(c + 32,x8); | ||
| 200 | U32TO8_LITTLE(c + 36,x9); | ||
| 201 | U32TO8_LITTLE(c + 40,x10); | ||
| 202 | U32TO8_LITTLE(c + 44,x11); | ||
| 203 | U32TO8_LITTLE(c + 48,x12); | ||
| 204 | U32TO8_LITTLE(c + 52,x13); | ||
| 205 | U32TO8_LITTLE(c + 56,x14); | ||
| 206 | U32TO8_LITTLE(c + 60,x15); | ||
| 207 | |||
| 208 | if (bytes <= 64) { | ||
| 209 | if (bytes < 64) { | ||
| 210 | for (i = 0;i < bytes;++i) ctarget[i] = c[i]; | ||
| 211 | } | ||
| 212 | x->input[12] = j12; | ||
| 213 | x->input[13] = j13; | ||
| 214 | return; | ||
| 215 | } | ||
| 216 | bytes -= 64; | ||
| 217 | c += 64; | ||
| 218 | #ifndef KEYSTREAM_ONLY | ||
| 219 | m += 64; | ||
| 220 | #endif | ||
| 221 | } | ||
| 222 | } | ||
diff --git a/src/lib/libc/crypt/crypt.3 b/src/lib/libc/crypt/crypt.3 new file mode 100644 index 0000000000..f4a78781da --- /dev/null +++ b/src/lib/libc/crypt/crypt.3 | |||
| @@ -0,0 +1,318 @@ | |||
| 1 | .\" $OpenBSD: crypt.3,v 1.34 2014/03/19 02:34:45 tedu 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 $Mdocdate: March 19 2014 $ | ||
| 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 | .Nm bcrypt_gensalt , | ||
| 44 | .Nm bcrypt , | ||
| 45 | .Nm md5crypt | ||
| 46 | .Nd password hashing | ||
| 47 | .Sh SYNOPSIS | ||
| 48 | .In stdlib.h | ||
| 49 | .Ft int | ||
| 50 | .Fn setkey "const char *key" | ||
| 51 | .Pp | ||
| 52 | .In unistd.h | ||
| 53 | .Ft char * | ||
| 54 | .Fn crypt "const char *key" "const char *setting" | ||
| 55 | .Ft int | ||
| 56 | .Fn encrypt "char *block" "int flag" | ||
| 57 | .Ft int | ||
| 58 | .Fn des_setkey "const char *key" | ||
| 59 | .Ft int | ||
| 60 | .Fn des_cipher "const char *in" "char *out" "int32_t salt" "int count" | ||
| 61 | .In pwd.h | ||
| 62 | .Ft char * | ||
| 63 | .Fn bcrypt_gensalt "u_int8_t log_rounds" | ||
| 64 | .Ft char * | ||
| 65 | .Fn bcrypt "const char *key" "const char *salt" | ||
| 66 | .Ft char * | ||
| 67 | .Fn md5crypt "const char *key" "const char *salt" | ||
| 68 | .Sh DESCRIPTION | ||
| 69 | The | ||
| 70 | .Fn crypt | ||
| 71 | function performs password hashing based on the | ||
| 72 | .Tn NBS | ||
| 73 | Data Encryption Standard (DES). | ||
| 74 | Additional code has been added to deter key search attempts and to use | ||
| 75 | stronger hashing algorithms. | ||
| 76 | .Pp | ||
| 77 | The first argument to | ||
| 78 | .Fn crypt | ||
| 79 | is a | ||
| 80 | .Dv NUL Ns -terminated | ||
| 81 | string, typically a user's typed password. | ||
| 82 | The second is in one of three forms: | ||
| 83 | if it begins with an underscore | ||
| 84 | .Pq Ql _ | ||
| 85 | then an extended format is used | ||
| 86 | in interpreting both the key and the setting, as outlined below. | ||
| 87 | If it begins | ||
| 88 | with a string character | ||
| 89 | .Pq Ql $ | ||
| 90 | and a number then a different algorithm is used depending on the number. | ||
| 91 | At the moment a | ||
| 92 | .Ql $1 | ||
| 93 | chooses MD5 hashing and a | ||
| 94 | .Ql $2 | ||
| 95 | chooses Blowfish hashing; see below for more information. | ||
| 96 | .Ss Extended crypt | ||
| 97 | The | ||
| 98 | .Ar key | ||
| 99 | is divided into groups of 8 characters (the last group is null-padded) | ||
| 100 | and the low-order 7 bits of each character (56 bits per group) are | ||
| 101 | used to form the DES key as follows: | ||
| 102 | the first group of 56 bits becomes the initial DES key. | ||
| 103 | For each additional group, the XOR of the encryption of the current DES | ||
| 104 | key with itself and the group bits becomes the next DES key. | ||
| 105 | .Pp | ||
| 106 | The setting is a 9-character array consisting of an underscore followed | ||
| 107 | by 4 bytes of iteration count and 4 bytes of salt. | ||
| 108 | These are encoded as printable characters, 6 bits per character, | ||
| 109 | least significant character first. | ||
| 110 | The values 0 to 63 are encoded as | ||
| 111 | .Dq \&./0-9A-Za-z . | ||
| 112 | This allows 24 bits for both | ||
| 113 | .Fa count | ||
| 114 | and | ||
| 115 | .Fa salt . | ||
| 116 | .Ss "MD5" crypt | ||
| 117 | For | ||
| 118 | .Tn MD5 | ||
| 119 | crypt the version number, | ||
| 120 | .Fa salt | ||
| 121 | and the hashed password are separated by the | ||
| 122 | .Ql $ | ||
| 123 | character. | ||
| 124 | The maximum length of a password is limited by | ||
| 125 | the length counter of the MD5 context, which is about | ||
| 126 | 2**64. | ||
| 127 | A valid MD5 password entry looks like this: | ||
| 128 | .Pp | ||
| 129 | .Dq $1$caeiHQwX$hsKqOjrFRRN6K32OWkCBf1 . | ||
| 130 | .Pp | ||
| 131 | The whole MD5 password string is passed as | ||
| 132 | .Fa setting | ||
| 133 | for interpretation. | ||
| 134 | .Ss "Blowfish" crypt | ||
| 135 | The | ||
| 136 | .Tn Blowfish | ||
| 137 | version of crypt has 128 bits of | ||
| 138 | .Fa salt | ||
| 139 | in order to make building dictionaries of common passwords space consuming. | ||
| 140 | The initial state of the | ||
| 141 | .Tn Blowfish | ||
| 142 | cipher is expanded using the | ||
| 143 | .Fa salt | ||
| 144 | and the | ||
| 145 | .Fa password | ||
| 146 | repeating the process a variable number of rounds, which is encoded in | ||
| 147 | the password string. | ||
| 148 | The maximum password length is 72. | ||
| 149 | The final Blowfish password entry is created by encrypting the string | ||
| 150 | .Pp | ||
| 151 | .Dq OrpheanBeholderScryDoubt | ||
| 152 | .Pp | ||
| 153 | with the | ||
| 154 | .Tn Blowfish | ||
| 155 | state 64 times. | ||
| 156 | .Pp | ||
| 157 | The version number, the logarithm of the number of rounds and | ||
| 158 | the concatenation of salt and hashed password are separated by the | ||
| 159 | .Ql $ | ||
| 160 | character. | ||
| 161 | An encoded | ||
| 162 | .Sq 8 | ||
| 163 | would specify 256 rounds. | ||
| 164 | A valid Blowfish password looks like this: | ||
| 165 | .Pp | ||
| 166 | .Dq $2a$12$eIAq8PR8sIUnJ1HaohxX2O9x9Qlm2vK97LJ5dsXdmB.eXF42qjchC . | ||
| 167 | .Pp | ||
| 168 | The whole Blowfish password string is passed as | ||
| 169 | .Fa setting | ||
| 170 | for interpretation. | ||
| 171 | .Ss "Traditional" crypt | ||
| 172 | The first 8 bytes of the key are null-padded, and the low-order 7 bits of | ||
| 173 | each character is used to form the 56-bit | ||
| 174 | .Tn DES | ||
| 175 | key. | ||
| 176 | .Pp | ||
| 177 | The setting is a 2-character array of the ASCII-encoded salt. | ||
| 178 | Thus only 12 bits of | ||
| 179 | .Fa salt | ||
| 180 | are used. | ||
| 181 | .Fa count | ||
| 182 | is set to 25. | ||
| 183 | .Ss DES Algorithm | ||
| 184 | The | ||
| 185 | .Fa salt | ||
| 186 | introduces disorder in the | ||
| 187 | .Tn DES | ||
| 188 | algorithm in one of 16777216 or 4096 possible ways | ||
| 189 | (i.e., with 24 or 12 bits: if bit | ||
| 190 | .Em i | ||
| 191 | of the | ||
| 192 | .Ar salt | ||
| 193 | is set, then bits | ||
| 194 | .Em i | ||
| 195 | and | ||
| 196 | .Em i+24 | ||
| 197 | are swapped in the | ||
| 198 | .Tn DES | ||
| 199 | E-box output). | ||
| 200 | .Pp | ||
| 201 | The DES key is used to encrypt a 64-bit constant using | ||
| 202 | .Ar count | ||
| 203 | iterations of | ||
| 204 | .Tn DES . | ||
| 205 | The value returned is a | ||
| 206 | .Dv NUL Ns -terminated | ||
| 207 | string, 20 or 13 bytes (plus NUL) in length, consisting of the | ||
| 208 | .Ar setting | ||
| 209 | followed by the encoded 64-bit encryption. | ||
| 210 | .Pp | ||
| 211 | The functions | ||
| 212 | .Fn encrypt , | ||
| 213 | .Fn setkey , | ||
| 214 | .Fn des_setkey , | ||
| 215 | and | ||
| 216 | .Fn des_cipher | ||
| 217 | provide access to the | ||
| 218 | .Tn DES | ||
| 219 | algorithm itself. | ||
| 220 | .Fn setkey | ||
| 221 | is passed a 64-byte array of binary values (numeric 0 or 1). | ||
| 222 | A 56-bit key is extracted from this array by dividing the | ||
| 223 | array into groups of 8, and ignoring the last bit in each group. | ||
| 224 | That bit is reserved for a byte parity check by DES, but is ignored | ||
| 225 | by these functions. | ||
| 226 | .Pp | ||
| 227 | The | ||
| 228 | .Fa block | ||
| 229 | argument to | ||
| 230 | .Fn encrypt | ||
| 231 | is also a 64-byte array of binary values. | ||
| 232 | If the value of | ||
| 233 | .Fa flag | ||
| 234 | is 0, | ||
| 235 | .Fa block | ||
| 236 | is encrypted otherwise it is decrypted. | ||
| 237 | The result is returned in the original array | ||
| 238 | .Fa block | ||
| 239 | after using the key specified by | ||
| 240 | .Fn setkey | ||
| 241 | to process it. | ||
| 242 | .Pp | ||
| 243 | The argument to | ||
| 244 | .Fn des_setkey | ||
| 245 | is a character array of length 8. | ||
| 246 | The least significant bit (the parity bit) in each character is ignored, | ||
| 247 | and the remaining bits are concatenated to form a 56-bit key. | ||
| 248 | The function | ||
| 249 | .Fn des_cipher | ||
| 250 | encrypts (or decrypts if | ||
| 251 | .Fa count | ||
| 252 | is negative) the 64-bits stored in the 8 characters at | ||
| 253 | .Fa in | ||
| 254 | using | ||
| 255 | .Xr abs 3 | ||
| 256 | of | ||
| 257 | .Fa count | ||
| 258 | iterations of | ||
| 259 | .Tn DES | ||
| 260 | and stores the 64-bit result in the 8 characters at | ||
| 261 | .Fa out | ||
| 262 | (which may be the same as | ||
| 263 | .Fa in ) . | ||
| 264 | The | ||
| 265 | .Fa salt | ||
| 266 | specifies perturbations to the | ||
| 267 | .Tn DES | ||
| 268 | E-box output as described above. | ||
| 269 | .Pp | ||
| 270 | The | ||
| 271 | .Fn crypt , | ||
| 272 | .Fn setkey , | ||
| 273 | and | ||
| 274 | .Fn des_setkey | ||
| 275 | functions all manipulate the same key space. | ||
| 276 | .Sh RETURN VALUES | ||
| 277 | The function | ||
| 278 | .Fn crypt | ||
| 279 | returns a pointer to the encrypted value on success, and | ||
| 280 | .Dv NULL | ||
| 281 | on failure. | ||
| 282 | The functions | ||
| 283 | .Fn setkey , | ||
| 284 | .Fn encrypt , | ||
| 285 | .Fn des_setkey , | ||
| 286 | and | ||
| 287 | .Fn des_cipher | ||
| 288 | return 0 on success and 1 on failure. | ||
| 289 | .Sh SEE ALSO | ||
| 290 | .Xr encrypt 1 , | ||
| 291 | .Xr login 1 , | ||
| 292 | .Xr passwd 1 , | ||
| 293 | .Xr blowfish 3 , | ||
| 294 | .Xr getpass 3 , | ||
| 295 | .Xr md5 3 , | ||
| 296 | .Xr passwd 5 | ||
| 297 | .Sh HISTORY | ||
| 298 | A rotor-based | ||
| 299 | .Fn crypt | ||
| 300 | function appeared in | ||
| 301 | .At v3 . | ||
| 302 | The current style | ||
| 303 | .Fn crypt | ||
| 304 | first appeared in | ||
| 305 | .At v7 . | ||
| 306 | .Sh AUTHORS | ||
| 307 | .An David Burren Aq Mt davidb@werj.com.au | ||
| 308 | wrote the original DES functions. | ||
| 309 | .Sh BUGS | ||
| 310 | The | ||
| 311 | .Fn crypt | ||
| 312 | function returns a pointer to static data, and subsequent calls to | ||
| 313 | .Fn crypt | ||
| 314 | will modify the same object. | ||
| 315 | .Pp | ||
| 316 | With DES hashing, passwords containing the byte 0x80 use less key entropy | ||
| 317 | than other passwords. | ||
| 318 | This is an implementation bug, not a bug in the DES cipher. | ||
diff --git a/src/lib/libc/crypt/crypt.c b/src/lib/libc/crypt/crypt.c new file mode 100644 index 0000000000..15a784532d --- /dev/null +++ b/src/lib/libc/crypt/crypt.c | |||
| @@ -0,0 +1,696 @@ | |||
| 1 | /* $OpenBSD: crypt.c,v 1.20 2005/08/08 08:05:33 espie Exp $ */ | ||
| 2 | |||
| 3 | /* | ||
| 4 | * FreeSec: libcrypt | ||
| 5 | * | ||
| 6 | * Copyright (c) 1994 David Burren | ||
| 7 | * All rights reserved. | ||
| 8 | * | ||
| 9 | * Redistribution and use in source and binary forms, with or without | ||
| 10 | * modification, are permitted provided that the following conditions | ||
| 11 | * are met: | ||
| 12 | * 1. Redistributions of source code must retain the above copyright | ||
| 13 | * notice, this list of conditions and the following disclaimer. | ||
| 14 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 15 | * notice, this list of conditions and the following disclaimer in the | ||
| 16 | * documentation and/or other materials provided with the distribution. | ||
| 17 | * 4. Neither the name of the author nor the names of other contributors | ||
| 18 | * may be used to endorse or promote products derived from this software | ||
| 19 | * without specific prior written permission. | ||
| 20 | * | ||
| 21 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | ||
| 22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
| 25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 31 | * SUCH DAMAGE. | ||
| 32 | * | ||
| 33 | * | ||
| 34 | * This is an original implementation of the DES and the crypt(3) interfaces | ||
| 35 | * by David Burren <davidb@werj.com.au>. | ||
| 36 | * | ||
| 37 | * An excellent reference on the underlying algorithm (and related | ||
| 38 | * algorithms) is: | ||
| 39 | * | ||
| 40 | * B. Schneier, Applied Cryptography: protocols, algorithms, | ||
| 41 | * and source code in C, John Wiley & Sons, 1994. | ||
| 42 | * | ||
| 43 | * Note that in that book's description of DES the lookups for the initial, | ||
| 44 | * pbox, and final permutations are inverted (this has been brought to the | ||
| 45 | * attention of the author). A list of errata for this book has been | ||
| 46 | * posted to the sci.crypt newsgroup by the author and is available for FTP. | ||
| 47 | */ | ||
| 48 | |||
| 49 | #include <sys/types.h> | ||
| 50 | #include <sys/param.h> | ||
| 51 | #include <pwd.h> | ||
| 52 | #include <unistd.h> | ||
| 53 | #include <string.h> | ||
| 54 | |||
| 55 | #ifdef DEBUG | ||
| 56 | # include <stdio.h> | ||
| 57 | #endif | ||
| 58 | |||
| 59 | static const u_char IP[64] = { | ||
| 60 | 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, | ||
| 61 | 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8, | ||
| 62 | 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3, | ||
| 63 | 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7 | ||
| 64 | }; | ||
| 65 | |||
| 66 | static u_char inv_key_perm[64]; | ||
| 67 | static u_char u_key_perm[56]; | ||
| 68 | static u_char const key_perm[56] = { | ||
| 69 | 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, | ||
| 70 | 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36, | ||
| 71 | 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, | ||
| 72 | 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4 | ||
| 73 | }; | ||
| 74 | |||
| 75 | static const u_char key_shifts[16] = { | ||
| 76 | 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 | ||
| 77 | }; | ||
| 78 | |||
| 79 | static u_char inv_comp_perm[56]; | ||
| 80 | static const u_char comp_perm[48] = { | ||
| 81 | 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, | ||
| 82 | 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, | ||
| 83 | 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48, | ||
| 84 | 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32 | ||
| 85 | }; | ||
| 86 | |||
| 87 | /* | ||
| 88 | * No E box is used, as it's replaced by some ANDs, shifts, and ORs. | ||
| 89 | */ | ||
| 90 | |||
| 91 | static u_char u_sbox[8][64]; | ||
| 92 | static const u_char sbox[8][64] = { | ||
| 93 | { | ||
| 94 | 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, | ||
| 95 | 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, | ||
| 96 | 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, | ||
| 97 | 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 | ||
| 98 | }, | ||
| 99 | { | ||
| 100 | 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, | ||
| 101 | 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, | ||
| 102 | 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, | ||
| 103 | 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 | ||
| 104 | }, | ||
| 105 | { | ||
| 106 | 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, | ||
| 107 | 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, | ||
| 108 | 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, | ||
| 109 | 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 | ||
| 110 | }, | ||
| 111 | { | ||
| 112 | 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, | ||
| 113 | 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, | ||
| 114 | 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, | ||
| 115 | 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 | ||
| 116 | }, | ||
| 117 | { | ||
| 118 | 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, | ||
| 119 | 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, | ||
| 120 | 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, | ||
| 121 | 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 | ||
| 122 | }, | ||
| 123 | { | ||
| 124 | 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, | ||
| 125 | 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, | ||
| 126 | 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, | ||
| 127 | 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 | ||
| 128 | }, | ||
| 129 | { | ||
| 130 | 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, | ||
| 131 | 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, | ||
| 132 | 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, | ||
| 133 | 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 | ||
| 134 | }, | ||
| 135 | { | ||
| 136 | 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, | ||
| 137 | 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, | ||
| 138 | 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, | ||
| 139 | 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 | ||
| 140 | } | ||
| 141 | }; | ||
| 142 | |||
| 143 | static u_char un_pbox[32]; | ||
| 144 | static const u_char pbox[32] = { | ||
| 145 | 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, | ||
| 146 | 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25 | ||
| 147 | }; | ||
| 148 | |||
| 149 | const u_int32_t _des_bits32[32] = | ||
| 150 | { | ||
| 151 | 0x80000000, 0x40000000, 0x20000000, 0x10000000, | ||
| 152 | 0x08000000, 0x04000000, 0x02000000, 0x01000000, | ||
| 153 | 0x00800000, 0x00400000, 0x00200000, 0x00100000, | ||
| 154 | 0x00080000, 0x00040000, 0x00020000, 0x00010000, | ||
| 155 | 0x00008000, 0x00004000, 0x00002000, 0x00001000, | ||
| 156 | 0x00000800, 0x00000400, 0x00000200, 0x00000100, | ||
| 157 | 0x00000080, 0x00000040, 0x00000020, 0x00000010, | ||
| 158 | 0x00000008, 0x00000004, 0x00000002, 0x00000001 | ||
| 159 | }; | ||
| 160 | |||
| 161 | const u_char _des_bits8[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }; | ||
| 162 | |||
| 163 | static u_int32_t saltbits; | ||
| 164 | static int32_t old_salt; | ||
| 165 | static const u_int32_t *bits28, *bits24; | ||
| 166 | static u_char init_perm[64], final_perm[64]; | ||
| 167 | static u_int32_t en_keysl[16], en_keysr[16]; | ||
| 168 | static u_int32_t de_keysl[16], de_keysr[16]; | ||
| 169 | int _des_initialised = 0; | ||
| 170 | static u_char m_sbox[4][4096]; | ||
| 171 | static u_int32_t psbox[4][256]; | ||
| 172 | static u_int32_t ip_maskl[8][256], ip_maskr[8][256]; | ||
| 173 | static u_int32_t fp_maskl[8][256], fp_maskr[8][256]; | ||
| 174 | static u_int32_t key_perm_maskl[8][128], key_perm_maskr[8][128]; | ||
| 175 | static u_int32_t comp_maskl[8][128], comp_maskr[8][128]; | ||
| 176 | static u_int32_t old_rawkey0, old_rawkey1; | ||
| 177 | |||
| 178 | static u_char ascii64[] = | ||
| 179 | "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; | ||
| 180 | /* 0000000000111111111122222222223333333333444444444455555555556666 */ | ||
| 181 | /* 0123456789012345678901234567890123456789012345678901234567890123 */ | ||
| 182 | |||
| 183 | static __inline int | ||
| 184 | ascii_to_bin(char ch) | ||
| 185 | { | ||
| 186 | if (ch > 'z') | ||
| 187 | return(0); | ||
| 188 | if (ch >= 'a') | ||
| 189 | return(ch - 'a' + 38); | ||
| 190 | if (ch > 'Z') | ||
| 191 | return(0); | ||
| 192 | if (ch >= 'A') | ||
| 193 | return(ch - 'A' + 12); | ||
| 194 | if (ch > '9') | ||
| 195 | return(0); | ||
| 196 | if (ch >= '.') | ||
| 197 | return(ch - '.'); | ||
| 198 | return(0); | ||
| 199 | } | ||
| 200 | |||
| 201 | void | ||
| 202 | _des_init(void) | ||
| 203 | { | ||
| 204 | int i, j, b, k, inbit, obit; | ||
| 205 | u_int32_t *p, *il, *ir, *fl, *fr; | ||
| 206 | |||
| 207 | old_rawkey0 = old_rawkey1 = 0; | ||
| 208 | saltbits = 0; | ||
| 209 | old_salt = 0; | ||
| 210 | bits24 = (bits28 = _des_bits32 + 4) + 4; | ||
| 211 | |||
| 212 | /* | ||
| 213 | * Invert the S-boxes, reordering the input bits. | ||
| 214 | */ | ||
| 215 | for (i = 0; i < 8; i++) | ||
| 216 | for (j = 0; j < 64; j++) { | ||
| 217 | b = (j & 0x20) | ((j & 1) << 4) | ((j >> 1) & 0xf); | ||
| 218 | u_sbox[i][j] = sbox[i][b]; | ||
| 219 | } | ||
| 220 | |||
| 221 | /* | ||
| 222 | * Convert the inverted S-boxes into 4 arrays of 8 bits. | ||
| 223 | * Each will handle 12 bits of the S-box input. | ||
| 224 | */ | ||
| 225 | for (b = 0; b < 4; b++) | ||
| 226 | for (i = 0; i < 64; i++) | ||
| 227 | for (j = 0; j < 64; j++) | ||
| 228 | m_sbox[b][(i << 6) | j] = | ||
| 229 | (u_sbox[(b << 1)][i] << 4) | | ||
| 230 | u_sbox[(b << 1) + 1][j]; | ||
| 231 | |||
| 232 | /* | ||
| 233 | * Set up the initial & final permutations into a useful form, and | ||
| 234 | * initialise the inverted key permutation. | ||
| 235 | */ | ||
| 236 | for (i = 0; i < 64; i++) { | ||
| 237 | init_perm[final_perm[i] = IP[i] - 1] = i; | ||
| 238 | inv_key_perm[i] = 255; | ||
| 239 | } | ||
| 240 | |||
| 241 | /* | ||
| 242 | * Invert the key permutation and initialise the inverted key | ||
| 243 | * compression permutation. | ||
| 244 | */ | ||
| 245 | for (i = 0; i < 56; i++) { | ||
| 246 | u_key_perm[i] = key_perm[i] - 1; | ||
| 247 | inv_key_perm[key_perm[i] - 1] = i; | ||
| 248 | inv_comp_perm[i] = 255; | ||
| 249 | } | ||
| 250 | |||
| 251 | /* | ||
| 252 | * Invert the key compression permutation. | ||
| 253 | */ | ||
| 254 | for (i = 0; i < 48; i++) { | ||
| 255 | inv_comp_perm[comp_perm[i] - 1] = i; | ||
| 256 | } | ||
| 257 | |||
| 258 | /* | ||
| 259 | * Set up the OR-mask arrays for the initial and final permutations, | ||
| 260 | * and for the key initial and compression permutations. | ||
| 261 | */ | ||
| 262 | for (k = 0; k < 8; k++) { | ||
| 263 | for (i = 0; i < 256; i++) { | ||
| 264 | *(il = &ip_maskl[k][i]) = 0; | ||
| 265 | *(ir = &ip_maskr[k][i]) = 0; | ||
| 266 | *(fl = &fp_maskl[k][i]) = 0; | ||
| 267 | *(fr = &fp_maskr[k][i]) = 0; | ||
| 268 | for (j = 0; j < 8; j++) { | ||
| 269 | inbit = 8 * k + j; | ||
| 270 | if (i & _des_bits8[j]) { | ||
| 271 | if ((obit = init_perm[inbit]) < 32) | ||
| 272 | *il |= _des_bits32[obit]; | ||
| 273 | else | ||
| 274 | *ir |= _des_bits32[obit-32]; | ||
| 275 | if ((obit = final_perm[inbit]) < 32) | ||
| 276 | *fl |= _des_bits32[obit]; | ||
| 277 | else | ||
| 278 | *fr |= _des_bits32[obit - 32]; | ||
| 279 | } | ||
| 280 | } | ||
| 281 | } | ||
| 282 | for (i = 0; i < 128; i++) { | ||
| 283 | *(il = &key_perm_maskl[k][i]) = 0; | ||
| 284 | *(ir = &key_perm_maskr[k][i]) = 0; | ||
| 285 | for (j = 0; j < 7; j++) { | ||
| 286 | inbit = 8 * k + j; | ||
| 287 | if (i & _des_bits8[j + 1]) { | ||
| 288 | if ((obit = inv_key_perm[inbit]) == 255) | ||
| 289 | continue; | ||
| 290 | if (obit < 28) | ||
| 291 | *il |= bits28[obit]; | ||
| 292 | else | ||
| 293 | *ir |= bits28[obit - 28]; | ||
| 294 | } | ||
| 295 | } | ||
| 296 | *(il = &comp_maskl[k][i]) = 0; | ||
| 297 | *(ir = &comp_maskr[k][i]) = 0; | ||
| 298 | for (j = 0; j < 7; j++) { | ||
| 299 | inbit = 7 * k + j; | ||
| 300 | if (i & _des_bits8[j + 1]) { | ||
| 301 | if ((obit=inv_comp_perm[inbit]) == 255) | ||
| 302 | continue; | ||
| 303 | if (obit < 24) | ||
| 304 | *il |= bits24[obit]; | ||
| 305 | else | ||
| 306 | *ir |= bits24[obit - 24]; | ||
| 307 | } | ||
| 308 | } | ||
| 309 | } | ||
| 310 | } | ||
| 311 | |||
| 312 | /* | ||
| 313 | * Invert the P-box permutation, and convert into OR-masks for | ||
| 314 | * handling the output of the S-box arrays setup above. | ||
| 315 | */ | ||
| 316 | for (i = 0; i < 32; i++) | ||
| 317 | un_pbox[pbox[i] - 1] = i; | ||
| 318 | |||
| 319 | for (b = 0; b < 4; b++) | ||
| 320 | for (i = 0; i < 256; i++) { | ||
| 321 | *(p = &psbox[b][i]) = 0; | ||
| 322 | for (j = 0; j < 8; j++) { | ||
| 323 | if (i & _des_bits8[j]) | ||
| 324 | *p |= _des_bits32[un_pbox[8 * b + j]]; | ||
| 325 | } | ||
| 326 | } | ||
| 327 | |||
| 328 | _des_initialised = 1; | ||
| 329 | } | ||
| 330 | |||
| 331 | void | ||
| 332 | _des_setup_salt(int32_t salt) | ||
| 333 | { | ||
| 334 | u_int32_t obit, saltbit; | ||
| 335 | int i; | ||
| 336 | |||
| 337 | if (salt == old_salt) | ||
| 338 | return; | ||
| 339 | old_salt = salt; | ||
| 340 | |||
| 341 | saltbits = 0; | ||
| 342 | saltbit = 1; | ||
| 343 | obit = 0x800000; | ||
| 344 | for (i = 0; i < 24; i++) { | ||
| 345 | if (salt & saltbit) | ||
| 346 | saltbits |= obit; | ||
| 347 | saltbit <<= 1; | ||
| 348 | obit >>= 1; | ||
| 349 | } | ||
| 350 | } | ||
| 351 | |||
| 352 | int | ||
| 353 | des_setkey(const char *key) | ||
| 354 | { | ||
| 355 | u_int32_t k0, k1, rawkey0, rawkey1; | ||
| 356 | int shifts, round; | ||
| 357 | |||
| 358 | if (!_des_initialised) | ||
| 359 | _des_init(); | ||
| 360 | |||
| 361 | rawkey0 = ntohl(*(u_int32_t *) key); | ||
| 362 | rawkey1 = ntohl(*(u_int32_t *) (key + 4)); | ||
| 363 | |||
| 364 | if ((rawkey0 | rawkey1) | ||
| 365 | && rawkey0 == old_rawkey0 | ||
| 366 | && rawkey1 == old_rawkey1) { | ||
| 367 | /* | ||
| 368 | * Already setup for this key. | ||
| 369 | * This optimisation fails on a zero key (which is weak and | ||
| 370 | * has bad parity anyway) in order to simplify the starting | ||
| 371 | * conditions. | ||
| 372 | */ | ||
| 373 | return(0); | ||
| 374 | } | ||
| 375 | old_rawkey0 = rawkey0; | ||
| 376 | old_rawkey1 = rawkey1; | ||
| 377 | |||
| 378 | /* | ||
| 379 | * Do key permutation and split into two 28-bit subkeys. | ||
| 380 | */ | ||
| 381 | k0 = key_perm_maskl[0][rawkey0 >> 25] | ||
| 382 | | key_perm_maskl[1][(rawkey0 >> 17) & 0x7f] | ||
| 383 | | key_perm_maskl[2][(rawkey0 >> 9) & 0x7f] | ||
| 384 | | key_perm_maskl[3][(rawkey0 >> 1) & 0x7f] | ||
| 385 | | key_perm_maskl[4][rawkey1 >> 25] | ||
| 386 | | key_perm_maskl[5][(rawkey1 >> 17) & 0x7f] | ||
| 387 | | key_perm_maskl[6][(rawkey1 >> 9) & 0x7f] | ||
| 388 | | key_perm_maskl[7][(rawkey1 >> 1) & 0x7f]; | ||
| 389 | k1 = key_perm_maskr[0][rawkey0 >> 25] | ||
| 390 | | key_perm_maskr[1][(rawkey0 >> 17) & 0x7f] | ||
| 391 | | key_perm_maskr[2][(rawkey0 >> 9) & 0x7f] | ||
| 392 | | key_perm_maskr[3][(rawkey0 >> 1) & 0x7f] | ||
| 393 | | key_perm_maskr[4][rawkey1 >> 25] | ||
| 394 | | key_perm_maskr[5][(rawkey1 >> 17) & 0x7f] | ||
| 395 | | key_perm_maskr[6][(rawkey1 >> 9) & 0x7f] | ||
| 396 | | key_perm_maskr[7][(rawkey1 >> 1) & 0x7f]; | ||
| 397 | /* | ||
| 398 | * Rotate subkeys and do compression permutation. | ||
| 399 | */ | ||
| 400 | shifts = 0; | ||
| 401 | for (round = 0; round < 16; round++) { | ||
| 402 | u_int32_t t0, t1; | ||
| 403 | |||
| 404 | shifts += key_shifts[round]; | ||
| 405 | |||
| 406 | t0 = (k0 << shifts) | (k0 >> (28 - shifts)); | ||
| 407 | t1 = (k1 << shifts) | (k1 >> (28 - shifts)); | ||
| 408 | |||
| 409 | de_keysl[15 - round] = | ||
| 410 | en_keysl[round] = comp_maskl[0][(t0 >> 21) & 0x7f] | ||
| 411 | | comp_maskl[1][(t0 >> 14) & 0x7f] | ||
| 412 | | comp_maskl[2][(t0 >> 7) & 0x7f] | ||
| 413 | | comp_maskl[3][t0 & 0x7f] | ||
| 414 | | comp_maskl[4][(t1 >> 21) & 0x7f] | ||
| 415 | | comp_maskl[5][(t1 >> 14) & 0x7f] | ||
| 416 | | comp_maskl[6][(t1 >> 7) & 0x7f] | ||
| 417 | | comp_maskl[7][t1 & 0x7f]; | ||
| 418 | |||
| 419 | de_keysr[15 - round] = | ||
| 420 | en_keysr[round] = comp_maskr[0][(t0 >> 21) & 0x7f] | ||
| 421 | | comp_maskr[1][(t0 >> 14) & 0x7f] | ||
| 422 | | comp_maskr[2][(t0 >> 7) & 0x7f] | ||
| 423 | | comp_maskr[3][t0 & 0x7f] | ||
| 424 | | comp_maskr[4][(t1 >> 21) & 0x7f] | ||
| 425 | | comp_maskr[5][(t1 >> 14) & 0x7f] | ||
| 426 | | comp_maskr[6][(t1 >> 7) & 0x7f] | ||
| 427 | | comp_maskr[7][t1 & 0x7f]; | ||
| 428 | } | ||
| 429 | return(0); | ||
| 430 | } | ||
| 431 | |||
| 432 | int | ||
| 433 | _des_do_des(u_int32_t l_in, u_int32_t r_in, u_int32_t *l_out, u_int32_t *r_out, | ||
| 434 | int count) | ||
| 435 | { | ||
| 436 | /* | ||
| 437 | * l_in, r_in, l_out, and r_out are in pseudo-"big-endian" format. | ||
| 438 | */ | ||
| 439 | u_int32_t l, r, *kl, *kr, *kl1, *kr1; | ||
| 440 | u_int32_t f, r48l, r48r; | ||
| 441 | int round; | ||
| 442 | |||
| 443 | if (count == 0) { | ||
| 444 | return(1); | ||
| 445 | } else if (count > 0) { | ||
| 446 | /* | ||
| 447 | * Encrypting | ||
| 448 | */ | ||
| 449 | kl1 = en_keysl; | ||
| 450 | kr1 = en_keysr; | ||
| 451 | } else { | ||
| 452 | /* | ||
| 453 | * Decrypting | ||
| 454 | */ | ||
| 455 | count = -count; | ||
| 456 | kl1 = de_keysl; | ||
| 457 | kr1 = de_keysr; | ||
| 458 | } | ||
| 459 | |||
| 460 | /* | ||
| 461 | * Do initial permutation (IP). | ||
| 462 | */ | ||
| 463 | l = ip_maskl[0][l_in >> 24] | ||
| 464 | | ip_maskl[1][(l_in >> 16) & 0xff] | ||
| 465 | | ip_maskl[2][(l_in >> 8) & 0xff] | ||
| 466 | | ip_maskl[3][l_in & 0xff] | ||
| 467 | | ip_maskl[4][r_in >> 24] | ||
| 468 | | ip_maskl[5][(r_in >> 16) & 0xff] | ||
| 469 | | ip_maskl[6][(r_in >> 8) & 0xff] | ||
| 470 | | ip_maskl[7][r_in & 0xff]; | ||
| 471 | r = ip_maskr[0][l_in >> 24] | ||
| 472 | | ip_maskr[1][(l_in >> 16) & 0xff] | ||
| 473 | | ip_maskr[2][(l_in >> 8) & 0xff] | ||
| 474 | | ip_maskr[3][l_in & 0xff] | ||
| 475 | | ip_maskr[4][r_in >> 24] | ||
| 476 | | ip_maskr[5][(r_in >> 16) & 0xff] | ||
| 477 | | ip_maskr[6][(r_in >> 8) & 0xff] | ||
| 478 | | ip_maskr[7][r_in & 0xff]; | ||
| 479 | |||
| 480 | while (count--) { | ||
| 481 | /* | ||
| 482 | * Do each round. | ||
| 483 | */ | ||
| 484 | kl = kl1; | ||
| 485 | kr = kr1; | ||
| 486 | round = 16; | ||
| 487 | while (round--) { | ||
| 488 | /* | ||
| 489 | * Expand R to 48 bits (simulate the E-box). | ||
| 490 | */ | ||
| 491 | r48l = ((r & 0x00000001) << 23) | ||
| 492 | | ((r & 0xf8000000) >> 9) | ||
| 493 | | ((r & 0x1f800000) >> 11) | ||
| 494 | | ((r & 0x01f80000) >> 13) | ||
| 495 | | ((r & 0x001f8000) >> 15); | ||
| 496 | |||
| 497 | r48r = ((r & 0x0001f800) << 7) | ||
| 498 | | ((r & 0x00001f80) << 5) | ||
| 499 | | ((r & 0x000001f8) << 3) | ||
| 500 | | ((r & 0x0000001f) << 1) | ||
| 501 | | ((r & 0x80000000) >> 31); | ||
| 502 | /* | ||
| 503 | * Do salting for crypt() and friends, and | ||
| 504 | * XOR with the permuted key. | ||
| 505 | */ | ||
| 506 | f = (r48l ^ r48r) & saltbits; | ||
| 507 | r48l ^= f ^ *kl++; | ||
| 508 | r48r ^= f ^ *kr++; | ||
| 509 | /* | ||
| 510 | * Do sbox lookups (which shrink it back to 32 bits) | ||
| 511 | * and do the pbox permutation at the same time. | ||
| 512 | */ | ||
| 513 | f = psbox[0][m_sbox[0][r48l >> 12]] | ||
| 514 | | psbox[1][m_sbox[1][r48l & 0xfff]] | ||
| 515 | | psbox[2][m_sbox[2][r48r >> 12]] | ||
| 516 | | psbox[3][m_sbox[3][r48r & 0xfff]]; | ||
| 517 | /* | ||
| 518 | * Now that we've permuted things, complete f(). | ||
| 519 | */ | ||
| 520 | f ^= l; | ||
| 521 | l = r; | ||
| 522 | r = f; | ||
| 523 | } | ||
| 524 | r = l; | ||
| 525 | l = f; | ||
| 526 | } | ||
| 527 | /* | ||
| 528 | * Do final permutation (inverse of IP). | ||
| 529 | */ | ||
| 530 | *l_out = fp_maskl[0][l >> 24] | ||
| 531 | | fp_maskl[1][(l >> 16) & 0xff] | ||
| 532 | | fp_maskl[2][(l >> 8) & 0xff] | ||
| 533 | | fp_maskl[3][l & 0xff] | ||
| 534 | | fp_maskl[4][r >> 24] | ||
| 535 | | fp_maskl[5][(r >> 16) & 0xff] | ||
| 536 | | fp_maskl[6][(r >> 8) & 0xff] | ||
| 537 | | fp_maskl[7][r & 0xff]; | ||
| 538 | *r_out = fp_maskr[0][l >> 24] | ||
| 539 | | fp_maskr[1][(l >> 16) & 0xff] | ||
| 540 | | fp_maskr[2][(l >> 8) & 0xff] | ||
| 541 | | fp_maskr[3][l & 0xff] | ||
| 542 | | fp_maskr[4][r >> 24] | ||
| 543 | | fp_maskr[5][(r >> 16) & 0xff] | ||
| 544 | | fp_maskr[6][(r >> 8) & 0xff] | ||
| 545 | | fp_maskr[7][r & 0xff]; | ||
| 546 | return(0); | ||
| 547 | } | ||
| 548 | |||
| 549 | int | ||
| 550 | des_cipher(const char *in, char *out, int32_t salt, int count) | ||
| 551 | { | ||
| 552 | u_int32_t l_out, r_out, rawl, rawr; | ||
| 553 | u_int32_t x[2]; | ||
| 554 | int retval; | ||
| 555 | |||
| 556 | if (!_des_initialised) | ||
| 557 | _des_init(); | ||
| 558 | |||
| 559 | _des_setup_salt(salt); | ||
| 560 | |||
| 561 | memcpy(x, in, sizeof x); | ||
| 562 | rawl = ntohl(x[0]); | ||
| 563 | rawr = ntohl(x[1]); | ||
| 564 | retval = _des_do_des(rawl, rawr, &l_out, &r_out, count); | ||
| 565 | |||
| 566 | x[0] = htonl(l_out); | ||
| 567 | x[1] = htonl(r_out); | ||
| 568 | memcpy(out, x, sizeof x); | ||
| 569 | return(retval); | ||
| 570 | } | ||
| 571 | |||
| 572 | char * | ||
| 573 | crypt(const char *key, const char *setting) | ||
| 574 | { | ||
| 575 | int i; | ||
| 576 | u_int32_t count, salt, l, r0, r1, keybuf[2]; | ||
| 577 | u_char *p, *q; | ||
| 578 | static u_char output[21]; | ||
| 579 | extern char *md5crypt(const char *, const char *); | ||
| 580 | extern char *bcrypt(const char *, const char *); | ||
| 581 | |||
| 582 | if (setting[0] == '$') { | ||
| 583 | switch (setting[1]) { | ||
| 584 | case '1': | ||
| 585 | return (md5crypt(key, setting)); | ||
| 586 | default: | ||
| 587 | return bcrypt(key, setting); | ||
| 588 | } | ||
| 589 | } | ||
| 590 | |||
| 591 | if (!_des_initialised) | ||
| 592 | _des_init(); | ||
| 593 | |||
| 594 | /* | ||
| 595 | * Copy the key, shifting each character up by one bit | ||
| 596 | * and padding with zeros. | ||
| 597 | */ | ||
| 598 | q = (u_char *) keybuf; | ||
| 599 | while ((q - (u_char *) keybuf) < sizeof(keybuf)) { | ||
| 600 | if ((*q++ = *key << 1)) | ||
| 601 | key++; | ||
| 602 | } | ||
| 603 | if (des_setkey((char *) keybuf)) | ||
| 604 | return(NULL); | ||
| 605 | |||
| 606 | if (*setting == _PASSWORD_EFMT1) { | ||
| 607 | /* | ||
| 608 | * "new"-style: | ||
| 609 | * setting - underscore, 4 bytes of count, 4 bytes of salt | ||
| 610 | * key - unlimited characters | ||
| 611 | */ | ||
| 612 | for (i = 1, count = 0; i < 5; i++) | ||
| 613 | count |= ascii_to_bin(setting[i]) << (i - 1) * 6; | ||
| 614 | |||
| 615 | for (i = 5, salt = 0; i < 9; i++) | ||
| 616 | salt |= ascii_to_bin(setting[i]) << (i - 5) * 6; | ||
| 617 | |||
| 618 | while (*key) { | ||
| 619 | /* | ||
| 620 | * Encrypt the key with itself. | ||
| 621 | */ | ||
| 622 | if (des_cipher((char *)keybuf, (char *)keybuf, 0, 1)) | ||
| 623 | return(NULL); | ||
| 624 | /* | ||
| 625 | * And XOR with the next 8 characters of the key. | ||
| 626 | */ | ||
| 627 | q = (u_char *) keybuf; | ||
| 628 | while (((q - (u_char *) keybuf) < sizeof(keybuf)) && | ||
| 629 | *key) | ||
| 630 | *q++ ^= *key++ << 1; | ||
| 631 | |||
| 632 | if (des_setkey((char *) keybuf)) | ||
| 633 | return(NULL); | ||
| 634 | } | ||
| 635 | strlcpy((char *)output, setting, 10); | ||
| 636 | |||
| 637 | /* | ||
| 638 | * Double check that we weren't given a short setting. | ||
| 639 | * If we were, the above code will probably have created | ||
| 640 | * weird values for count and salt, but we don't really care. | ||
| 641 | * Just make sure the output string doesn't have an extra | ||
| 642 | * NUL in it. | ||
| 643 | */ | ||
| 644 | p = output + strlen((const char *)output); | ||
| 645 | } else { | ||
| 646 | /* | ||
| 647 | * "old"-style: | ||
| 648 | * setting - 2 bytes of salt | ||
| 649 | * key - up to 8 characters | ||
| 650 | */ | ||
| 651 | count = 25; | ||
| 652 | |||
| 653 | salt = (ascii_to_bin(setting[1]) << 6) | ||
| 654 | | ascii_to_bin(setting[0]); | ||
| 655 | |||
| 656 | output[0] = setting[0]; | ||
| 657 | /* | ||
| 658 | * If the encrypted password that the salt was extracted from | ||
| 659 | * is only 1 character long, the salt will be corrupted. We | ||
| 660 | * need to ensure that the output string doesn't have an extra | ||
| 661 | * NUL in it! | ||
| 662 | */ | ||
| 663 | output[1] = setting[1] ? setting[1] : output[0]; | ||
| 664 | |||
| 665 | p = output + 2; | ||
| 666 | } | ||
| 667 | _des_setup_salt(salt); | ||
| 668 | |||
| 669 | /* | ||
| 670 | * Do it. | ||
| 671 | */ | ||
| 672 | if (_des_do_des(0, 0, &r0, &r1, count)) | ||
| 673 | return(NULL); | ||
| 674 | /* | ||
| 675 | * Now encode the result... | ||
| 676 | */ | ||
| 677 | l = (r0 >> 8); | ||
| 678 | *p++ = ascii64[(l >> 18) & 0x3f]; | ||
| 679 | *p++ = ascii64[(l >> 12) & 0x3f]; | ||
| 680 | *p++ = ascii64[(l >> 6) & 0x3f]; | ||
| 681 | *p++ = ascii64[l & 0x3f]; | ||
| 682 | |||
| 683 | l = (r0 << 16) | ((r1 >> 16) & 0xffff); | ||
| 684 | *p++ = ascii64[(l >> 18) & 0x3f]; | ||
| 685 | *p++ = ascii64[(l >> 12) & 0x3f]; | ||
| 686 | *p++ = ascii64[(l >> 6) & 0x3f]; | ||
| 687 | *p++ = ascii64[l & 0x3f]; | ||
| 688 | |||
| 689 | l = r1 << 2; | ||
| 690 | *p++ = ascii64[(l >> 12) & 0x3f]; | ||
| 691 | *p++ = ascii64[(l >> 6) & 0x3f]; | ||
| 692 | *p++ = ascii64[l & 0x3f]; | ||
| 693 | *p = 0; | ||
| 694 | |||
| 695 | return((char *)output); | ||
| 696 | } | ||
diff --git a/src/lib/libc/crypt/crypt2.c b/src/lib/libc/crypt/crypt2.c new file mode 100644 index 0000000000..f31818ae2b --- /dev/null +++ b/src/lib/libc/crypt/crypt2.c | |||
| @@ -0,0 +1,107 @@ | |||
| 1 | /* $OpenBSD: crypt2.c,v 1.4 2013/04/17 17:40:35 tedu Exp $ */ | ||
| 2 | |||
| 3 | /* | ||
| 4 | * FreeSec: libcrypt | ||
| 5 | * | ||
| 6 | * Copyright (c) 1994 David Burren | ||
| 7 | * All rights reserved. | ||
| 8 | * | ||
| 9 | * Redistribution and use in source and binary forms, with or without | ||
| 10 | * modification, are permitted provided that the following conditions | ||
| 11 | * are met: | ||
| 12 | * 1. Redistributions of source code must retain the above copyright | ||
| 13 | * notice, this list of conditions and the following disclaimer. | ||
| 14 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 15 | * notice, this list of conditions and the following disclaimer in the | ||
| 16 | * documentation and/or other materials provided with the distribution. | ||
| 17 | * 4. Neither the name of the author nor the names of other contributors | ||
| 18 | * may be used to endorse or promote products derived from this software | ||
| 19 | * without specific prior written permission. | ||
| 20 | * | ||
| 21 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | ||
| 22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
| 25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 31 | * SUCH DAMAGE. | ||
| 32 | * | ||
| 33 | * | ||
| 34 | * This is an original implementation of the DES and the crypt(3) interfaces | ||
| 35 | * by David Burren <davidb@werj.com.au>. | ||
| 36 | * | ||
| 37 | * An excellent reference on the underlying algorithm (and related | ||
| 38 | * algorithms) is: | ||
| 39 | * | ||
| 40 | * B. Schneier, Applied Cryptography: protocols, algorithms, | ||
| 41 | * and source code in C, John Wiley & Sons, 1994. | ||
| 42 | * | ||
| 43 | * Note that in that book's description of DES the lookups for the initial, | ||
| 44 | * pbox, and final permutations are inverted (this has been brought to the | ||
| 45 | * attention of the author). A list of errata for this book has been | ||
| 46 | * posted to the sci.crypt newsgroup by the author and is available for FTP. | ||
| 47 | */ | ||
| 48 | |||
| 49 | #include <sys/types.h> | ||
| 50 | #include <sys/param.h> | ||
| 51 | #include <pwd.h> | ||
| 52 | #include <unistd.h> | ||
| 53 | #include <string.h> | ||
| 54 | |||
| 55 | #ifdef DEBUG | ||
| 56 | # include <stdio.h> | ||
| 57 | #endif | ||
| 58 | |||
| 59 | extern const u_char _des_bits8[8]; | ||
| 60 | extern const u_int32_t _des_bits32[32]; | ||
| 61 | extern int _des_initialised; | ||
| 62 | void _des_init(void); | ||
| 63 | void _des_setup_salt(int32_t salt); | ||
| 64 | int _des_do_des(u_int32_t , u_int32_t , u_int32_t *, u_int32_t *, int); | ||
| 65 | |||
| 66 | int | ||
| 67 | setkey(const char *key) | ||
| 68 | { | ||
| 69 | int i, j; | ||
| 70 | u_int32_t packed_keys[2]; | ||
| 71 | u_char *p; | ||
| 72 | |||
| 73 | p = (u_char *) packed_keys; | ||
| 74 | |||
| 75 | for (i = 0; i < 8; i++) { | ||
| 76 | p[i] = 0; | ||
| 77 | for (j = 0; j < 8; j++) | ||
| 78 | if (*key++ & 1) | ||
| 79 | p[i] |= _des_bits8[j]; | ||
| 80 | } | ||
| 81 | return(des_setkey((char *)p)); | ||
| 82 | } | ||
| 83 | |||
| 84 | int | ||
| 85 | encrypt(char *block, int flag) | ||
| 86 | { | ||
| 87 | u_int32_t io[2]; | ||
| 88 | u_char *p; | ||
| 89 | int i, j, retval; | ||
| 90 | |||
| 91 | if (!_des_initialised) | ||
| 92 | _des_init(); | ||
| 93 | |||
| 94 | _des_setup_salt(0); | ||
| 95 | p = (u_char *)block; | ||
| 96 | for (i = 0; i < 2; i++) { | ||
| 97 | io[i] = 0L; | ||
| 98 | for (j = 0; j < 32; j++) | ||
| 99 | if (*p++ & 1) | ||
| 100 | io[i] |= _des_bits32[j]; | ||
| 101 | } | ||
| 102 | retval = _des_do_des(io[0], io[1], io, io + 1, flag ? -1 : 1); | ||
| 103 | for (i = 0; i < 2; i++) | ||
| 104 | for (j = 0; j < 32; j++) | ||
| 105 | block[(i << 5) | j] = (io[i] & _des_bits32[j]) ? 1 : 0; | ||
| 106 | return(retval); | ||
| 107 | } | ||
diff --git a/src/lib/libc/crypt/md5crypt.c b/src/lib/libc/crypt/md5crypt.c new file mode 100644 index 0000000000..a855835bcc --- /dev/null +++ b/src/lib/libc/crypt/md5crypt.c | |||
| @@ -0,0 +1,160 @@ | |||
| 1 | /* $OpenBSD: md5crypt.c,v 1.17 2014/04/03 15:55:29 beck Exp $ */ | ||
| 2 | |||
| 3 | /* | ||
| 4 | * Copyright (c) 2000 Poul-Henning Kamp <phk@FreeBSD.org> | ||
| 5 | * | ||
| 6 | * Permission to use, copy, modify, and distribute this software for any | ||
| 7 | * purpose with or without fee is hereby granted, provided that the above | ||
| 8 | * copyright notice and this permission notice appear in all copies. | ||
| 9 | * | ||
| 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 17 | */ | ||
| 18 | |||
| 19 | /* | ||
| 20 | * If we meet some day, and you think this stuff is worth it, you | ||
| 21 | * can buy me a beer in return. Poul-Henning Kamp | ||
| 22 | */ | ||
| 23 | |||
| 24 | #include <unistd.h> | ||
| 25 | #include <stdio.h> | ||
| 26 | #include <string.h> | ||
| 27 | #include <md5.h> | ||
| 28 | #include <string.h> | ||
| 29 | |||
| 30 | static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */ | ||
| 31 | "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; | ||
| 32 | |||
| 33 | static void to64(char *, u_int32_t, int); | ||
| 34 | |||
| 35 | static void | ||
| 36 | to64(char *s, u_int32_t v, int n) | ||
| 37 | { | ||
| 38 | while (--n >= 0) { | ||
| 39 | *s++ = itoa64[v&0x3f]; | ||
| 40 | v >>= 6; | ||
| 41 | } | ||
| 42 | } | ||
| 43 | |||
| 44 | /* | ||
| 45 | * UNIX password | ||
| 46 | * | ||
| 47 | * Use MD5 for what it is best at... | ||
| 48 | */ | ||
| 49 | |||
| 50 | char *md5crypt(const char *pw, const char *salt); | ||
| 51 | |||
| 52 | char * | ||
| 53 | md5crypt(const char *pw, const char *salt) | ||
| 54 | { | ||
| 55 | /* | ||
| 56 | * This string is the magic for this algorithm. | ||
| 57 | * Having it this way, we can get better later on. | ||
| 58 | */ | ||
| 59 | static unsigned char *magic = (unsigned char *)"$1$"; | ||
| 60 | |||
| 61 | static char passwd[120], *p; | ||
| 62 | static const unsigned char *sp,*ep; | ||
| 63 | unsigned char final[16]; | ||
| 64 | int sl,pl,i; | ||
| 65 | MD5_CTX ctx,ctx1; | ||
| 66 | u_int32_t l; | ||
| 67 | |||
| 68 | /* Refine the salt first */ | ||
| 69 | sp = (const unsigned char *)salt; | ||
| 70 | |||
| 71 | /* If it starts with the magic string, then skip that */ | ||
| 72 | if(!strncmp((const char *)sp,(const char *)magic,strlen((const char *)magic))) | ||
| 73 | sp += strlen((const char *)magic); | ||
| 74 | |||
| 75 | /* It stops at the first '$', max 8 chars */ | ||
| 76 | for(ep=sp;*ep && *ep != '$' && ep < (sp+8);ep++) | ||
| 77 | continue; | ||
| 78 | |||
| 79 | /* get the length of the true salt */ | ||
| 80 | sl = ep - sp; | ||
| 81 | |||
| 82 | MD5Init(&ctx); | ||
| 83 | |||
| 84 | /* The password first, since that is what is most unknown */ | ||
| 85 | MD5Update(&ctx,(const unsigned char *)pw,strlen(pw)); | ||
| 86 | |||
| 87 | /* Then our magic string */ | ||
| 88 | MD5Update(&ctx,magic,strlen((const char *)magic)); | ||
| 89 | |||
| 90 | /* Then the raw salt */ | ||
| 91 | MD5Update(&ctx,sp,sl); | ||
| 92 | |||
| 93 | /* Then just as many characters of the MD5(pw,salt,pw) */ | ||
| 94 | MD5Init(&ctx1); | ||
| 95 | MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw)); | ||
| 96 | MD5Update(&ctx1,sp,sl); | ||
| 97 | MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw)); | ||
| 98 | MD5Final(final,&ctx1); | ||
| 99 | for(pl = strlen(pw); pl > 0; pl -= 16) | ||
| 100 | MD5Update(&ctx,final,pl>16 ? 16 : pl); | ||
| 101 | |||
| 102 | /* Don't leave anything around in vm they could use. */ | ||
| 103 | memset(final,0,sizeof final); | ||
| 104 | |||
| 105 | /* Then something really weird... */ | ||
| 106 | for (i = strlen(pw); i ; i >>= 1) | ||
| 107 | if(i&1) | ||
| 108 | MD5Update(&ctx, final, 1); | ||
| 109 | else | ||
| 110 | MD5Update(&ctx, (const unsigned char *)pw, 1); | ||
| 111 | |||
| 112 | /* Now make the output string */ | ||
| 113 | snprintf(passwd, sizeof(passwd), "%s%.*s$", (char *)magic, | ||
| 114 | sl, (const char *)sp); | ||
| 115 | |||
| 116 | MD5Final(final,&ctx); | ||
| 117 | |||
| 118 | /* | ||
| 119 | * And now, just to make sure things don't run too fast | ||
| 120 | * On a 60 MHz Pentium this takes 34 msec, so you would | ||
| 121 | * need 30 seconds to build a 1000 entry dictionary... | ||
| 122 | * On a modern machine, with possible GPU optimization, | ||
| 123 | * this will run a lot faster than that. | ||
| 124 | */ | ||
| 125 | for(i=0;i<1000;i++) { | ||
| 126 | MD5Init(&ctx1); | ||
| 127 | if(i & 1) | ||
| 128 | MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw)); | ||
| 129 | else | ||
| 130 | MD5Update(&ctx1,final,16); | ||
| 131 | |||
| 132 | if(i % 3) | ||
| 133 | MD5Update(&ctx1,sp,sl); | ||
| 134 | |||
| 135 | if(i % 7) | ||
| 136 | MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw)); | ||
| 137 | |||
| 138 | if(i & 1) | ||
| 139 | MD5Update(&ctx1,final,16); | ||
| 140 | else | ||
| 141 | MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw)); | ||
| 142 | MD5Final(final,&ctx1); | ||
| 143 | } | ||
| 144 | |||
| 145 | p = passwd + strlen(passwd); | ||
| 146 | |||
| 147 | l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; to64(p,l,4); p += 4; | ||
| 148 | l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; to64(p,l,4); p += 4; | ||
| 149 | l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; to64(p,l,4); p += 4; | ||
| 150 | l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; to64(p,l,4); p += 4; | ||
| 151 | l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; to64(p,l,4); p += 4; | ||
| 152 | l = final[11] ; to64(p,l,2); p += 2; | ||
| 153 | *p = '\0'; | ||
| 154 | |||
| 155 | /* Don't leave anything around in vm they could use. */ | ||
| 156 | memset(final, 0, sizeof final); | ||
| 157 | |||
| 158 | return passwd; | ||
| 159 | } | ||
| 160 | |||
diff --git a/src/lib/libc/include/ctype_private.h b/src/lib/libc/include/ctype_private.h new file mode 100644 index 0000000000..39cc792ea4 --- /dev/null +++ b/src/lib/libc/include/ctype_private.h | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | /* $OpenBSD: ctype_private.h,v 1.1 2005/08/08 05:53:00 espie Exp $ */ | ||
| 2 | /* Written by Marc Espie, public domain */ | ||
| 3 | #define CTYPE_NUM_CHARS 256 | ||
| 4 | extern const char _C_ctype_[]; | ||
| 5 | extern const short _C_toupper_[]; | ||
| 6 | extern const short _C_tolower_[]; | ||
| 7 | |||
diff --git a/src/lib/libc/include/namespace.h b/src/lib/libc/include/namespace.h index 803657e006..4a51f15ddf 100644 --- a/src/lib/libc/include/namespace.h +++ b/src/lib/libc/include/namespace.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $NetBSD: namespace.h,v 1.2 1995/02/27 13:02:12 cgd Exp $ */ | 1 | /* $OpenBSD: namespace.h,v 1.2 1996/08/19 08:28:08 tholo Exp $ */ |
| 2 | 2 | ||
| 3 | #define catclose _catclose | 3 | #define catclose _catclose |
| 4 | #define catgets _catgets | 4 | #define catgets _catgets |
diff --git a/src/lib/libc/include/thread_private.h b/src/lib/libc/include/thread_private.h new file mode 100644 index 0000000000..673fb9c6a6 --- /dev/null +++ b/src/lib/libc/include/thread_private.h | |||
| @@ -0,0 +1,175 @@ | |||
| 1 | /* $OpenBSD: thread_private.h,v 1.25 2011/10/16 06:29:56 guenther Exp $ */ | ||
| 2 | |||
| 3 | /* PUBLIC DOMAIN: No Rights Reserved. Marco S Hyman <marc@snafu.org> */ | ||
| 4 | |||
| 5 | #ifndef _THREAD_PRIVATE_H_ | ||
| 6 | #define _THREAD_PRIVATE_H_ | ||
| 7 | |||
| 8 | /* | ||
| 9 | * This file defines the thread library interface to libc. Thread | ||
| 10 | * libraries must implement the functions described here for proper | ||
| 11 | * inter-operation with libc. libc contains weak versions of the | ||
| 12 | * described functions for operation in a non-threaded environment. | ||
| 13 | */ | ||
| 14 | |||
| 15 | /* | ||
| 16 | * This variable is 0 until a second thread is created. | ||
| 17 | */ | ||
| 18 | extern int __isthreaded; | ||
| 19 | |||
| 20 | /* | ||
| 21 | * Weak symbols are used in libc so that the thread library can | ||
| 22 | * efficiently wrap libc functions. | ||
| 23 | * | ||
| 24 | * Use WEAK_NAME(n) to get a libc-private name for n (_weak_n), | ||
| 25 | * WEAK_ALIAS(n) to generate the weak symbol n pointing to _weak_n, | ||
| 26 | * WEAK_PROTOTYPE(n) to generate a prototype for _weak_n (based on n). | ||
| 27 | */ | ||
| 28 | #define WEAK_NAME(name) __CONCAT(_weak_,name) | ||
| 29 | #define WEAK_ALIAS(name) __weak_alias(name, WEAK_NAME(name)) | ||
| 30 | #ifdef __GNUC__ | ||
| 31 | #define WEAK_PROTOTYPE(name) __typeof__(name) WEAK_NAME(name) | ||
| 32 | #else | ||
| 33 | #define WEAK_PROTOTYPE(name) /* typeof() only in gcc */ | ||
| 34 | #endif | ||
| 35 | |||
| 36 | /* | ||
| 37 | * Ditto for hand-written syscall stubs: | ||
| 38 | * | ||
| 39 | * Use STUB_NAME(n) to get the strong name of the stub: _thread_sys_n | ||
| 40 | * STUB_ALIAS(n) to generate the weak symbol n pointing to _thread_sys_n, | ||
| 41 | * STUB_PROTOTYPE(n) to generate a prototype for _thread_sys_n (based on n). | ||
| 42 | */ | ||
| 43 | #define STUB_NAME(name) __CONCAT(_thread_sys_,name) | ||
| 44 | #define STUB_ALIAS(name) __weak_alias(name, STUB_NAME(name)) | ||
| 45 | #ifdef __GNUC__ | ||
| 46 | #define STUB_PROTOTYPE(name) __typeof__(name) STUB_NAME(name) | ||
| 47 | #else | ||
| 48 | #define STUB_PROTOTYPE(name) /* typeof() only in gcc */ | ||
| 49 | #endif | ||
| 50 | |||
| 51 | /* | ||
| 52 | * helper macro to make unique names in the thread namespace | ||
| 53 | */ | ||
| 54 | #define __THREAD_NAME(name) __CONCAT(_thread_tagname_,name) | ||
| 55 | |||
| 56 | /* | ||
| 57 | * helper functions that exist as (weak) null functions in libc and | ||
| 58 | * (strong) functions in the thread library. These functions: | ||
| 59 | * | ||
| 60 | * _thread_tag_lock: | ||
| 61 | * lock the mutex associated with the given tag. If the given | ||
| 62 | * tag is NULL a tag is first allocated. | ||
| 63 | * | ||
| 64 | * _thread_tag_unlock: | ||
| 65 | * unlock the mutex associated with the given tag. If the given | ||
| 66 | * tag is NULL a tag is first allocated. | ||
| 67 | * | ||
| 68 | * _thread_tag_storage: | ||
| 69 | * return a pointer to per thread instance of data associated | ||
| 70 | * with the given tag. If the given tag is NULL a tag is first | ||
| 71 | * allocated. | ||
| 72 | * | ||
| 73 | * _thread_mutex_lock: | ||
| 74 | * lock the given mutex. If the given mutex is NULL, | ||
| 75 | * rely on rthreads/pthreads implementation to initialize | ||
| 76 | * the mutex before locking. | ||
| 77 | * | ||
| 78 | * _thread_mutex_unlock: | ||
| 79 | * unlock the given mutex. | ||
| 80 | * | ||
| 81 | * _thread_mutex_destroy: | ||
| 82 | * destroy the given mutex. | ||
| 83 | */ | ||
| 84 | void _thread_tag_lock(void **); | ||
| 85 | void _thread_tag_unlock(void **); | ||
| 86 | void *_thread_tag_storage(void **, void *, size_t, void *); | ||
| 87 | void _thread_mutex_lock(void **); | ||
| 88 | void _thread_mutex_unlock(void **); | ||
| 89 | void _thread_mutex_destroy(void **); | ||
| 90 | |||
| 91 | /* | ||
| 92 | * Macros used in libc to access thread mutex, keys, and per thread storage. | ||
| 93 | * _THREAD_PRIVATE_KEY and _THREAD_PRIVATE_MUTEX are different macros for | ||
| 94 | * historical reasons. They do the same thing, define a static variable | ||
| 95 | * keyed by 'name' that identifies a mutex and a key to identify per thread | ||
| 96 | * data. | ||
| 97 | */ | ||
| 98 | #define _THREAD_PRIVATE_KEY(name) \ | ||
| 99 | static void *__THREAD_NAME(name) | ||
| 100 | #define _THREAD_PRIVATE_MUTEX(name) \ | ||
| 101 | static void *__THREAD_NAME(name) | ||
| 102 | #define _THREAD_PRIVATE_MUTEX_LOCK(name) \ | ||
| 103 | _thread_tag_lock(&(__THREAD_NAME(name))) | ||
| 104 | #define _THREAD_PRIVATE_MUTEX_UNLOCK(name) \ | ||
| 105 | _thread_tag_unlock(&(__THREAD_NAME(name))) | ||
| 106 | #define _THREAD_PRIVATE(keyname, storage, error) \ | ||
| 107 | _thread_tag_storage(&(__THREAD_NAME(keyname)), &(storage), \ | ||
| 108 | sizeof (storage), error) | ||
| 109 | |||
| 110 | /* | ||
| 111 | * Macros used in libc to access mutexes. | ||
| 112 | */ | ||
| 113 | #define _MUTEX_LOCK(mutex) \ | ||
| 114 | do { \ | ||
| 115 | if (__isthreaded) \ | ||
| 116 | _thread_mutex_lock(mutex); \ | ||
| 117 | } while (0) | ||
| 118 | #define _MUTEX_UNLOCK(mutex) \ | ||
| 119 | do { \ | ||
| 120 | if (__isthreaded) \ | ||
| 121 | _thread_mutex_unlock(mutex); \ | ||
| 122 | } while (0) | ||
| 123 | #define _MUTEX_DESTROY(mutex) \ | ||
| 124 | do { \ | ||
| 125 | if (__isthreaded) \ | ||
| 126 | _thread_mutex_destroy(mutex); \ | ||
| 127 | } while (0) | ||
| 128 | |||
| 129 | /* | ||
| 130 | * Resolver code is special cased in that it uses global keys. | ||
| 131 | */ | ||
| 132 | extern void *__THREAD_NAME(_res); | ||
| 133 | extern void *__THREAD_NAME(_res_ext); | ||
| 134 | extern void *__THREAD_NAME(serv_mutex); | ||
| 135 | |||
| 136 | /* | ||
| 137 | * malloc lock/unlock prototypes and definitions | ||
| 138 | */ | ||
| 139 | void _thread_malloc_lock(void); | ||
| 140 | void _thread_malloc_unlock(void); | ||
| 141 | |||
| 142 | #define _MALLOC_LOCK() do { \ | ||
| 143 | if (__isthreaded) \ | ||
| 144 | _thread_malloc_lock(); \ | ||
| 145 | } while (0) | ||
| 146 | #define _MALLOC_UNLOCK() do { \ | ||
| 147 | if (__isthreaded) \ | ||
| 148 | _thread_malloc_unlock();\ | ||
| 149 | } while (0) | ||
| 150 | |||
| 151 | void _thread_atexit_lock(void); | ||
| 152 | void _thread_atexit_unlock(void); | ||
| 153 | |||
| 154 | #define _ATEXIT_LOCK() do { \ | ||
| 155 | if (__isthreaded) \ | ||
| 156 | _thread_atexit_lock(); \ | ||
| 157 | } while (0) | ||
| 158 | #define _ATEXIT_UNLOCK() do { \ | ||
| 159 | if (__isthreaded) \ | ||
| 160 | _thread_atexit_unlock();\ | ||
| 161 | } while (0) | ||
| 162 | |||
| 163 | void _thread_arc4_lock(void); | ||
| 164 | void _thread_arc4_unlock(void); | ||
| 165 | |||
| 166 | #define _ARC4_LOCK() do { \ | ||
| 167 | if (__isthreaded) \ | ||
| 168 | _thread_arc4_lock(); \ | ||
| 169 | } while (0) | ||
| 170 | #define _ARC4_UNLOCK() do { \ | ||
| 171 | if (__isthreaded) \ | ||
| 172 | _thread_arc4_unlock();\ | ||
| 173 | } while (0) | ||
| 174 | |||
| 175 | #endif /* _THREAD_PRIVATE_H_ */ | ||
diff --git a/src/lib/libc/net/Makefile.inc b/src/lib/libc/net/Makefile.inc index 2d220067e4..f4153bbfb4 100644 --- a/src/lib/libc/net/Makefile.inc +++ b/src/lib/libc/net/Makefile.inc | |||
| @@ -1,46 +1,98 @@ | |||
| 1 | # $NetBSD: Makefile.inc,v 1.23 1995/03/02 09:09:07 chopps Exp $ | 1 | # $OpenBSD: Makefile.inc,v 1.51 2014/04/07 17:57:56 schwarze Exp $ |
| 2 | # @(#)Makefile.inc 8.2 (Berkeley) 9/5/93 | ||
| 3 | 2 | ||
| 4 | # net sources | 3 | # net sources |
| 5 | .PATH: ${.CURDIR}/arch/${MACHINE_ARCH}/net ${.CURDIR}/net | 4 | .PATH: ${LIBCSRCDIR}/arch/${MACHINE_CPU}/net ${LIBCSRCDIR}/net |
| 6 | 5 | ||
| 7 | SRCS+= gethostnamadr.c getnetbyaddr.c getnetbyname.c getnetent.c \ | 6 | CFLAGS+=-DRESOLVSORT |
| 8 | getproto.c getprotoent.c getprotoname.c getservbyname.c \ | 7 | |
| 9 | getservbyport.c getservent.c herror.c inet_addr.c inet_lnaof.c \ | 8 | SRCS+= base64.c freeaddrinfo.c gai_strerror.c getaddrinfo.c gethostnamadr.c \ |
| 10 | inet_makeaddr.c inet_netof.c inet_network.c inet_ntoa.c \ | 9 | getifaddrs.c getnameinfo.c getnetbyaddr.c getnetbyname.c getnetent.c \ |
| 11 | iso_addr.c linkaddr.c ns_addr.c ns_ntoa.c rcmd.c recv.c res_comp.c \ | 10 | getnetnamadr.c getpeereid.c getproto.c getprotoent.c getprotoname.c \ |
| 12 | res_debug.c res_init.c res_mkquery.c res_query.c res_send.c \ | 11 | getservbyname.c getservbyport.c getservent.c getrrsetbyname.c \ |
| 13 | send.c sethostent.c ethers.c | 12 | herror.c if_indextoname.c if_nameindex.c if_nametoindex.c inet_addr.c \ |
| 13 | inet_lnaof.c inet_makeaddr.c inet_neta.c inet_netof.c inet_network.c \ | ||
| 14 | inet_net_ntop.c inet_net_pton.c inet_ntoa.c inet_ntop.c inet_pton.c \ | ||
| 15 | linkaddr.c rcmd.c ruserok.c rresvport.c recv.c res_comp.c res_data.c \ | ||
| 16 | res_debug.c res_debug_syms.c res_init.c res_mkquery.c res_query.c \ | ||
| 17 | res_random.c res_send.c send.c sethostent.c ethers.c rcmdsh.c | ||
| 18 | |||
| 19 | # IPv6 | ||
| 20 | SRCS+= ip6opt.c rthdr.c vars6.c | ||
| 14 | 21 | ||
| 15 | # machine-dependent net sources | 22 | # machine-dependent net sources |
| 16 | # m-d Makefile.inc must include sources for: | 23 | # m-d Makefile.inc must include sources for: |
| 17 | # htonl() htons() ntohl() ntohs() | 24 | # htonl() htons() ntohl() ntohs() |
| 18 | 25 | ||
| 19 | .include "${.CURDIR}/arch/${MACHINE_ARCH}/net/Makefile.inc" | 26 | .include "${LIBCSRCDIR}/arch/${MACHINE_CPU}/net/Makefile.inc" |
| 20 | 27 | ||
| 21 | MAN+= byteorder.3 gethostbyname.3 getnetent.3 getprotoent.3 getservent.3 \ | 28 | MAN+= byteorder.3 ethers.3 gai_strerror.3 getaddrinfo.3 gethostbyname.3 \ |
| 22 | inet.3 linkaddr.3 ns.3 rcmd.3 resolver.3 ethers.3 | 29 | getifaddrs.3 getnameinfo.3 getnetent.3 getpeereid.3 getprotoent.3 \ |
| 30 | getrrsetbyname.3 getservent.3 if_indextoname.3 inet.3 \ | ||
| 31 | inet_net.3 inet6_option_space.3 inet6_rthdr_space.3 \ | ||
| 32 | inet6_opt_init.3 inet6_rth_space.3 link_addr.3 \ | ||
| 33 | rcmd.3 rcmdsh.3 resolver.3 | ||
| 23 | 34 | ||
| 24 | MLINKS+=byteorder.3 htonl.3 byteorder.3 htons.3 byteorder.3 ntohl.3 \ | 35 | MLINKS+=byteorder.3 htonl.3 byteorder.3 htons.3 byteorder.3 ntohl.3 \ |
| 25 | byteorder.3 ntohs.3 | 36 | byteorder.3 ntohs.3 byteorder.3 htobe16.3 byteorder.3 htobe32.3 \ |
| 37 | byteorder.3 htobe64.3 byteorder.3 betoh16.3 byteorder.3 betoh32.3 \ | ||
| 38 | byteorder.3 betoh64.3 byteorder.3 htole16.3 byteorder.3 htole32.3 \ | ||
| 39 | byteorder.3 htole64.3 byteorder.3 letoh16.3 byteorder.3 letoh32.3 \ | ||
| 40 | byteorder.3 letoh64.3 byteorder.3 swap16.3 byteorder.3 swap32.3 \ | ||
| 41 | byteorder.3 swap64.3 | ||
| 26 | MLINKS+=ethers.3 ether_aton.3 ethers.3 ether_hostton.3 ethers.3 ether_line.3 \ | 42 | MLINKS+=ethers.3 ether_aton.3 ethers.3 ether_hostton.3 ethers.3 ether_line.3 \ |
| 27 | ethers.3 ether_ntoa.3 ethers.3 ether_ntohost.3 | 43 | ethers.3 ether_ntoa.3 ethers.3 ether_ntohost.3 |
| 44 | MLINKS+=getaddrinfo.3 freeaddrinfo.3 | ||
| 28 | MLINKS+=gethostbyname.3 endhostent.3 gethostbyname.3 gethostbyaddr.3 \ | 45 | MLINKS+=gethostbyname.3 endhostent.3 gethostbyname.3 gethostbyaddr.3 \ |
| 29 | gethostbyname.3 sethostent.3 gethostbyname.3 gethostent.3 \ | 46 | gethostbyname.3 sethostent.3 gethostbyname.3 gethostent.3 \ |
| 30 | gethostbyname.3 herror.3 | 47 | gethostbyname.3 herror.3 gethostbyname.3 gethostbyname2.3 \ |
| 48 | gethostbyname.3 hstrerror.3 | ||
| 49 | MLINKS+=getifaddrs.3 freeifaddrs.3 | ||
| 31 | MLINKS+=getnetent.3 endnetent.3 getnetent.3 getnetbyaddr.3 \ | 50 | MLINKS+=getnetent.3 endnetent.3 getnetent.3 getnetbyaddr.3 \ |
| 32 | getnetent.3 getnetbyname.3 getnetent.3 setnetent.3 | 51 | getnetent.3 getnetbyname.3 getnetent.3 setnetent.3 |
| 33 | MLINKS+=getprotoent.3 endprotoent.3 getprotoent.3 getprotobyname.3 \ | 52 | MLINKS+=getprotoent.3 endprotoent.3 getprotoent.3 getprotobyname.3 \ |
| 34 | getprotoent.3 getprotobynumber.3 getprotoent.3 setprotoent.3 | 53 | getprotoent.3 getprotobynumber.3 getprotoent.3 setprotoent.3 \ |
| 54 | getprotoent.3 getprotoent_r.3 getprotoent.3 getprotobyname_r.3 \ | ||
| 55 | getprotoent.3 getprotobynumber_r.3 getprotoent.3 setprotoent_r.3 \ | ||
| 56 | getprotoent.3 endprotoent_r.3 | ||
| 35 | MLINKS+=getservent.3 endservent.3 getservent.3 getservbyname.3 \ | 57 | MLINKS+=getservent.3 endservent.3 getservent.3 getservbyname.3 \ |
| 36 | getservent.3 getservbyport.3 getservent.3 setservent.3 | 58 | getservent.3 getservbyport.3 getservent.3 setservent.3 \ |
| 37 | MLINKS+=inet.3 addr.3 inet.3 inet_addr.3 inet.3 inet_aton.3 \ | 59 | getservent.3 getservent_r.3 getservent.3 getservbyname_r.3 \ |
| 60 | getservent.3 getservbyport_r.3 getservent.3 setservent_r.3 \ | ||
| 61 | getservent.3 endservent_r.3 | ||
| 62 | MLINKS+= if_indextoname.3 if_nametoindex.3 if_indextoname.3 if_nameindex.3 \ | ||
| 63 | if_indextoname.3 if_freenameindex.3 | ||
| 64 | MLINKS+=inet.3 inet_addr.3 inet.3 inet_aton.3 \ | ||
| 38 | inet.3 inet_lnaof.3 inet.3 inet_makeaddr.3 inet.3 inet_netof.3 \ | 65 | inet.3 inet_lnaof.3 inet.3 inet_makeaddr.3 inet.3 inet_netof.3 \ |
| 39 | inet.3 inet_network.3 inet.3 inet_ntoa.3 inet.3 network.3 \ | 66 | inet.3 inet_network.3 inet.3 inet_ntoa.3 \ |
| 40 | inet.3 ntoa.3 | 67 | inet.3 inet_ntop.3 inet.3 inet_pton.3 |
| 41 | MLINKS+=linkaddr.3 linkntoa.3 | 68 | MLINKS+=inet_net.3 inet_net_ntop.3 inet_net.3 inet_net_pton.3 |
| 42 | MLINKS+=ns.3 ns_addr.3 ns.3 ns_ntoa.3 | 69 | MLINKS+=link_addr.3 link_ntoa.3 |
| 43 | MLINKS+=rcmd.3 iruserok.3 rcmd.3 rresvport.3 rcmd.3 ruserok.3 | 70 | MLINKS+=rcmd.3 iruserok.3 rcmd.3 rresvport.3 rcmd.3 ruserok.3 \ |
| 71 | rcmd.3 rresvport_af.3 rcmd.3 rcmd_af.3 rcmd.3 iruserok_sa.3 | ||
| 44 | MLINKS+=resolver.3 dn_comp.3 resolver.3 dn_expand.3 resolver.3 res_init.3 \ | 72 | MLINKS+=resolver.3 dn_comp.3 resolver.3 dn_expand.3 resolver.3 res_init.3 \ |
| 45 | resolver.3 res_mkquery.3 resolver.3 res_send.3 resolver.3 res_query.3 \ | 73 | resolver.3 res_mkquery.3 resolver.3 res_send.3 resolver.3 res_query.3 \ |
| 46 | resolver.3 res_search.3 | 74 | resolver.3 res_search.3 |
| 75 | MLINKS+=getrrsetbyname.3 freerrset.3 | ||
| 76 | MLINKS+=inet6_option_space.3 inet6_option_init.3 \ | ||
| 77 | inet6_option_space.3 inet6_option_append.3 \ | ||
| 78 | inet6_option_space.3 inet6_option_alloc.3 \ | ||
| 79 | inet6_option_space.3 inet6_option_next.3 \ | ||
| 80 | inet6_option_space.3 inet6_option_find.3 | ||
| 81 | MLINKS+=inet6_rthdr_space.3 inet6_rthdr_init.3 \ | ||
| 82 | inet6_rthdr_space.3 inet6_rthdr_add.3 \ | ||
| 83 | inet6_rthdr_space.3 inet6_rthdr_lasthop.3 \ | ||
| 84 | inet6_rthdr_space.3 inet6_rthdr_reverse.3 \ | ||
| 85 | inet6_rthdr_space.3 inet6_rthdr_segments.3 \ | ||
| 86 | inet6_rthdr_space.3 inet6_rthdr_getaddr.3 \ | ||
| 87 | inet6_rthdr_space.3 inet6_rthdr_getflags.3 | ||
| 88 | MLINKS+=inet6_opt_init.3 inet6_opt_append.3 \ | ||
| 89 | inet6_opt_init.3 inet6_opt_finish.3 \ | ||
| 90 | inet6_opt_init.3 inet6_opt_set_val.3 \ | ||
| 91 | inet6_opt_init.3 inet6_opt_next.3 \ | ||
| 92 | inet6_opt_init.3 inet6_opt_find.3 \ | ||
| 93 | inet6_opt_init.3 inet6_opt_get_val.3 | ||
| 94 | MLINKS+=inet6_rth_space.3 inet6_rth_init.3 \ | ||
| 95 | inet6_rth_space.3 inet6_rth_add.3 \ | ||
| 96 | inet6_rth_space.3 inet6_rth_reverse.3 \ | ||
| 97 | inet6_rth_space.3 inet6_rth_segments.3 \ | ||
| 98 | inet6_rth_space.3 inet6_rth_getaddr.3 \ | ||
diff --git a/src/lib/libc/net/base64.c b/src/lib/libc/net/base64.c new file mode 100644 index 0000000000..7c3d1d319f --- /dev/null +++ b/src/lib/libc/net/base64.c | |||
| @@ -0,0 +1,316 @@ | |||
| 1 | /* $OpenBSD: base64.c,v 1.7 2013/12/31 02:32:56 tedu 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 | static const char Base64[] = | ||
| 60 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | ||
| 61 | static const char Pad64 = '='; | ||
| 62 | |||
| 63 | /* (From RFC1521 and draft-ietf-dnssec-secext-03.txt) | ||
| 64 | The following encoding technique is taken from RFC 1521 by Borenstein | ||
| 65 | and Freed. It is reproduced here in a slightly edited form for | ||
| 66 | convenience. | ||
| 67 | |||
| 68 | A 65-character subset of US-ASCII is used, enabling 6 bits to be | ||
| 69 | represented per printable character. (The extra 65th character, "=", | ||
| 70 | is used to signify a special processing function.) | ||
| 71 | |||
| 72 | The encoding process represents 24-bit groups of input bits as output | ||
| 73 | strings of 4 encoded characters. Proceeding from left to right, a | ||
| 74 | 24-bit input group is formed by concatenating 3 8-bit input groups. | ||
| 75 | These 24 bits are then treated as 4 concatenated 6-bit groups, each | ||
| 76 | of which is translated into a single digit in the base64 alphabet. | ||
| 77 | |||
| 78 | Each 6-bit group is used as an index into an array of 64 printable | ||
| 79 | characters. The character referenced by the index is placed in the | ||
| 80 | output string. | ||
| 81 | |||
| 82 | Table 1: The Base64 Alphabet | ||
| 83 | |||
| 84 | Value Encoding Value Encoding Value Encoding Value Encoding | ||
| 85 | 0 A 17 R 34 i 51 z | ||
| 86 | 1 B 18 S 35 j 52 0 | ||
| 87 | 2 C 19 T 36 k 53 1 | ||
| 88 | 3 D 20 U 37 l 54 2 | ||
| 89 | 4 E 21 V 38 m 55 3 | ||
| 90 | 5 F 22 W 39 n 56 4 | ||
| 91 | 6 G 23 X 40 o 57 5 | ||
| 92 | 7 H 24 Y 41 p 58 6 | ||
| 93 | 8 I 25 Z 42 q 59 7 | ||
| 94 | 9 J 26 a 43 r 60 8 | ||
| 95 | 10 K 27 b 44 s 61 9 | ||
| 96 | 11 L 28 c 45 t 62 + | ||
| 97 | 12 M 29 d 46 u 63 / | ||
| 98 | 13 N 30 e 47 v | ||
| 99 | 14 O 31 f 48 w (pad) = | ||
| 100 | 15 P 32 g 49 x | ||
| 101 | 16 Q 33 h 50 y | ||
| 102 | |||
| 103 | Special processing is performed if fewer than 24 bits are available | ||
| 104 | at the end of the data being encoded. A full encoding quantum is | ||
| 105 | always completed at the end of a quantity. When fewer than 24 input | ||
| 106 | bits are available in an input group, zero bits are added (on the | ||
| 107 | right) to form an integral number of 6-bit groups. Padding at the | ||
| 108 | end of the data is performed using the '=' character. | ||
| 109 | |||
| 110 | Since all base64 input is an integral number of octets, only the | ||
| 111 | ------------------------------------------------- | ||
| 112 | following cases can arise: | ||
| 113 | |||
| 114 | (1) the final quantum of encoding input is an integral | ||
| 115 | multiple of 24 bits; here, the final unit of encoded | ||
| 116 | output will be an integral multiple of 4 characters | ||
| 117 | with no "=" padding, | ||
| 118 | (2) the final quantum of encoding input is exactly 8 bits; | ||
| 119 | here, the final unit of encoded output will be two | ||
| 120 | characters followed by two "=" padding characters, or | ||
| 121 | (3) the final quantum of encoding input is exactly 16 bits; | ||
| 122 | here, the final unit of encoded output will be three | ||
| 123 | characters followed by one "=" padding character. | ||
| 124 | */ | ||
| 125 | |||
| 126 | int | ||
| 127 | b64_ntop(src, srclength, target, targsize) | ||
| 128 | u_char const *src; | ||
| 129 | size_t srclength; | ||
| 130 | char *target; | ||
| 131 | size_t targsize; | ||
| 132 | { | ||
| 133 | size_t datalength = 0; | ||
| 134 | u_char input[3]; | ||
| 135 | u_char output[4]; | ||
| 136 | int i; | ||
| 137 | |||
| 138 | while (2 < srclength) { | ||
| 139 | input[0] = *src++; | ||
| 140 | input[1] = *src++; | ||
| 141 | input[2] = *src++; | ||
| 142 | srclength -= 3; | ||
| 143 | |||
| 144 | output[0] = input[0] >> 2; | ||
| 145 | output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); | ||
| 146 | output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); | ||
| 147 | output[3] = input[2] & 0x3f; | ||
| 148 | |||
| 149 | if (datalength + 4 > targsize) | ||
| 150 | return (-1); | ||
| 151 | target[datalength++] = Base64[output[0]]; | ||
| 152 | target[datalength++] = Base64[output[1]]; | ||
| 153 | target[datalength++] = Base64[output[2]]; | ||
| 154 | target[datalength++] = Base64[output[3]]; | ||
| 155 | } | ||
| 156 | |||
| 157 | /* Now we worry about padding. */ | ||
| 158 | if (0 != srclength) { | ||
| 159 | /* Get what's left. */ | ||
| 160 | input[0] = input[1] = input[2] = '\0'; | ||
| 161 | for (i = 0; i < srclength; i++) | ||
| 162 | input[i] = *src++; | ||
| 163 | |||
| 164 | output[0] = input[0] >> 2; | ||
| 165 | output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); | ||
| 166 | output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); | ||
| 167 | |||
| 168 | if (datalength + 4 > targsize) | ||
| 169 | return (-1); | ||
| 170 | target[datalength++] = Base64[output[0]]; | ||
| 171 | target[datalength++] = Base64[output[1]]; | ||
| 172 | if (srclength == 1) | ||
| 173 | target[datalength++] = Pad64; | ||
| 174 | else | ||
| 175 | target[datalength++] = Base64[output[2]]; | ||
| 176 | target[datalength++] = Pad64; | ||
| 177 | } | ||
| 178 | if (datalength >= targsize) | ||
| 179 | return (-1); | ||
| 180 | target[datalength] = '\0'; /* Returned value doesn't count \0. */ | ||
| 181 | return (datalength); | ||
| 182 | } | ||
| 183 | |||
| 184 | /* skips all whitespace anywhere. | ||
| 185 | converts characters, four at a time, starting at (or after) | ||
| 186 | src from base - 64 numbers into three 8 bit bytes in the target area. | ||
| 187 | it returns the number of data bytes stored at the target, or -1 on error. | ||
| 188 | */ | ||
| 189 | |||
| 190 | int | ||
| 191 | b64_pton(src, target, targsize) | ||
| 192 | char const *src; | ||
| 193 | u_char *target; | ||
| 194 | size_t targsize; | ||
| 195 | { | ||
| 196 | int tarindex, state, ch; | ||
| 197 | u_char nextbyte; | ||
| 198 | char *pos; | ||
| 199 | |||
| 200 | state = 0; | ||
| 201 | tarindex = 0; | ||
| 202 | |||
| 203 | while ((ch = (unsigned char)*src++) != '\0') { | ||
| 204 | if (isspace(ch)) /* Skip whitespace anywhere. */ | ||
| 205 | continue; | ||
| 206 | |||
| 207 | if (ch == Pad64) | ||
| 208 | break; | ||
| 209 | |||
| 210 | pos = strchr(Base64, ch); | ||
| 211 | if (pos == 0) /* A non-base64 character. */ | ||
| 212 | return (-1); | ||
| 213 | |||
| 214 | switch (state) { | ||
| 215 | case 0: | ||
| 216 | if (target) { | ||
| 217 | if (tarindex >= targsize) | ||
| 218 | return (-1); | ||
| 219 | target[tarindex] = (pos - Base64) << 2; | ||
| 220 | } | ||
| 221 | state = 1; | ||
| 222 | break; | ||
| 223 | case 1: | ||
| 224 | if (target) { | ||
| 225 | if (tarindex >= targsize) | ||
| 226 | return (-1); | ||
| 227 | target[tarindex] |= (pos - Base64) >> 4; | ||
| 228 | nextbyte = ((pos - Base64) & 0x0f) << 4; | ||
| 229 | if (tarindex + 1 < targsize) | ||
| 230 | target[tarindex+1] = nextbyte; | ||
| 231 | else if (nextbyte) | ||
| 232 | return (-1); | ||
| 233 | } | ||
| 234 | tarindex++; | ||
| 235 | state = 2; | ||
| 236 | break; | ||
| 237 | case 2: | ||
| 238 | if (target) { | ||
| 239 | if (tarindex >= targsize) | ||
| 240 | return (-1); | ||
| 241 | target[tarindex] |= (pos - Base64) >> 2; | ||
| 242 | nextbyte = ((pos - Base64) & 0x03) << 6; | ||
| 243 | if (tarindex + 1 < targsize) | ||
| 244 | target[tarindex+1] = nextbyte; | ||
| 245 | else if (nextbyte) | ||
| 246 | return (-1); | ||
| 247 | } | ||
| 248 | tarindex++; | ||
| 249 | state = 3; | ||
| 250 | break; | ||
| 251 | case 3: | ||
| 252 | if (target) { | ||
| 253 | if (tarindex >= targsize) | ||
| 254 | return (-1); | ||
| 255 | target[tarindex] |= (pos - Base64); | ||
| 256 | } | ||
| 257 | tarindex++; | ||
| 258 | state = 0; | ||
| 259 | break; | ||
| 260 | } | ||
| 261 | } | ||
| 262 | |||
| 263 | /* | ||
| 264 | * We are done decoding Base-64 chars. Let's see if we ended | ||
| 265 | * on a byte boundary, and/or with erroneous trailing characters. | ||
| 266 | */ | ||
| 267 | |||
| 268 | if (ch == Pad64) { /* We got a pad char. */ | ||
| 269 | ch = (unsigned char)*src++; /* Skip it, get next. */ | ||
| 270 | switch (state) { | ||
| 271 | case 0: /* Invalid = in first position */ | ||
| 272 | case 1: /* Invalid = in second position */ | ||
| 273 | return (-1); | ||
| 274 | |||
| 275 | case 2: /* Valid, means one byte of info */ | ||
| 276 | /* Skip any number of spaces. */ | ||
| 277 | for (; ch != '\0'; ch = (unsigned char)*src++) | ||
| 278 | if (!isspace(ch)) | ||
| 279 | break; | ||
| 280 | /* Make sure there is another trailing = sign. */ | ||
| 281 | if (ch != Pad64) | ||
| 282 | return (-1); | ||
| 283 | ch = (unsigned char)*src++; /* Skip the = */ | ||
| 284 | /* Fall through to "single trailing =" case. */ | ||
| 285 | /* FALLTHROUGH */ | ||
| 286 | |||
| 287 | case 3: /* Valid, means two bytes of info */ | ||
| 288 | /* | ||
| 289 | * We know this char is an =. Is there anything but | ||
| 290 | * whitespace after it? | ||
| 291 | */ | ||
| 292 | for (; ch != '\0'; ch = (unsigned char)*src++) | ||
| 293 | if (!isspace(ch)) | ||
| 294 | return (-1); | ||
| 295 | |||
| 296 | /* | ||
| 297 | * Now make sure for cases 2 and 3 that the "extra" | ||
| 298 | * bits that slopped past the last full byte were | ||
| 299 | * zeros. If we don't check them, they become a | ||
| 300 | * subliminal channel. | ||
| 301 | */ | ||
| 302 | if (target && tarindex < targsize && | ||
| 303 | target[tarindex] != 0) | ||
| 304 | return (-1); | ||
| 305 | } | ||
| 306 | } else { | ||
| 307 | /* | ||
| 308 | * We ended by seeing the end of the string. Make sure we | ||
| 309 | * have no partial bytes lying around. | ||
| 310 | */ | ||
| 311 | if (state != 0) | ||
| 312 | return (-1); | ||
| 313 | } | ||
| 314 | |||
| 315 | return (tarindex); | ||
| 316 | } | ||
diff --git a/src/lib/libc/net/byteorder.3 b/src/lib/libc/net/byteorder.3 index 701a69f688..53f9fd071d 100644 --- a/src/lib/libc/net/byteorder.3 +++ b/src/lib/libc/net/byteorder.3 | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | .\" $NetBSD: byteorder.3,v 1.3 1995/02/25 06:20:27 cgd Exp $ | 1 | .\" $OpenBSD: byteorder.3,v 1.18 2013/06/05 03:39:22 tedu Exp $ |
| 2 | .\" | 2 | .\" |
| 3 | .\" Copyright (c) 1983, 1991, 1993 | 3 | .\" Copyright (c) 1983, 1991, 1993 |
| 4 | .\" The Regents of the University of California. All rights reserved. | 4 | .\" The Regents of the University of California. All rights reserved. |
| @@ -11,11 +11,7 @@ | |||
| 11 | .\" 2. Redistributions in binary form must reproduce the above copyright | 11 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 12 | .\" notice, this list of conditions and the following disclaimer in the | 12 | .\" notice, this list of conditions and the following disclaimer in the |
| 13 | .\" documentation and/or other materials provided with the distribution. | 13 | .\" documentation and/or other materials provided with the distribution. |
| 14 | .\" 3. All advertising materials mentioning features or use of this software | 14 | .\" 3. Neither the name of the University nor the names of its contributors |
| 15 | .\" must display the following acknowledgement: | ||
| 16 | .\" This product includes software developed by the University of | ||
| 17 | .\" California, Berkeley and its contributors. | ||
| 18 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 19 | .\" may be used to endorse or promote products derived from this software | 15 | .\" may be used to endorse or promote products derived from this software |
| 20 | .\" without specific prior written permission. | 16 | .\" without specific prior written permission. |
| 21 | .\" | 17 | .\" |
| @@ -31,48 +27,180 @@ | |||
| 31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 27 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 32 | .\" SUCH DAMAGE. | 28 | .\" SUCH DAMAGE. |
| 33 | .\" | 29 | .\" |
| 34 | .\" @(#)byteorder.3 8.1 (Berkeley) 6/4/93 | 30 | .Dd $Mdocdate: June 5 2013 $ |
| 35 | .\" | ||
| 36 | .Dd June 4, 1993 | ||
| 37 | .Dt BYTEORDER 3 | 31 | .Dt BYTEORDER 3 |
| 38 | .Os BSD 4.2 | 32 | .Os |
| 39 | .Sh NAME | 33 | .Sh NAME |
| 40 | .Nm htonl , | 34 | .Nm htonl , |
| 41 | .Nm htons , | 35 | .Nm htons , |
| 42 | .Nm ntohl , | 36 | .Nm ntohl , |
| 43 | .Nm ntohs | 37 | .Nm ntohs , |
| 44 | .Nd convert values between host and network byte order | 38 | .Nm htobe64 , |
| 39 | .Nm htobe32 , | ||
| 40 | .Nm htobe16 , | ||
| 41 | .Nm betoh64 , | ||
| 42 | .Nm betoh32 , | ||
| 43 | .Nm betoh16 , | ||
| 44 | .Nm htole64 , | ||
| 45 | .Nm htole32 , | ||
| 46 | .Nm htole16 , | ||
| 47 | .Nm letoh64 , | ||
| 48 | .Nm letoh32 , | ||
| 49 | .Nm letoh16 , | ||
| 50 | .Nm swap64 , | ||
| 51 | .Nm swap32 , | ||
| 52 | .Nm swap16 | ||
| 53 | .Nd convert values between different byte orderings | ||
| 45 | .Sh SYNOPSIS | 54 | .Sh SYNOPSIS |
| 46 | .Fd #include <sys/param.h> | 55 | .In sys/types.h |
| 47 | .Ft u_long | 56 | .Ft u_int32_t |
| 48 | .Fn htonl "u_long hostlong" | 57 | .Fn htonl "u_int32_t host32" |
| 49 | .Ft u_short | 58 | .Ft u_int16_t |
| 50 | .Fn htons "u_short hostshort" | 59 | .Fn htons "u_int16_t host16" |
| 51 | .Ft u_long | 60 | .Ft u_int32_t |
| 52 | .Fn ntohl "u_long netlong" | 61 | .Fn ntohl "u_int32_t net32" |
| 53 | .Ft u_short | 62 | .Ft u_int16_t |
| 54 | .Fn ntohs "u_short netshort" | 63 | .Fn ntohs "u_int16_t net16" |
| 64 | .Ft u_int64_t | ||
| 65 | .Fn htobe64 "u_int64_t host64" | ||
| 66 | .Ft u_int32_t | ||
| 67 | .Fn htobe32 "u_int32_t host32" | ||
| 68 | .Ft u_int16_t | ||
| 69 | .Fn htobe16 "u_int16_t host16" | ||
| 70 | .Ft u_int64_t | ||
| 71 | .Fn betoh64 "u_int64_t big64" | ||
| 72 | .Ft u_int32_t | ||
| 73 | .Fn betoh32 "u_int32_t big32" | ||
| 74 | .Ft u_int16_t | ||
| 75 | .Fn betoh16 "u_int16_t big16" | ||
| 76 | .Ft u_int64_t | ||
| 77 | .Fn htole64 "u_int64_t host64" | ||
| 78 | .Ft u_int32_t | ||
| 79 | .Fn htole32 "u_int32_t host32" | ||
| 80 | .Ft u_int16_t | ||
| 81 | .Fn htole16 "u_int16_t host16" | ||
| 82 | .Ft u_int64_t | ||
| 83 | .Fn letoh64 "u_int64_t little64" | ||
| 84 | .Ft u_int32_t | ||
| 85 | .Fn letoh32 "u_int32_t little32" | ||
| 86 | .Ft u_int16_t | ||
| 87 | .Fn letoh16 "u_int16_t little16" | ||
| 88 | .Ft u_int64_t | ||
| 89 | .Fn swap64 "u_int64_t val64" | ||
| 90 | .Ft u_int32_t | ||
| 91 | .Fn swap32 "u_int32_t val32" | ||
| 92 | .Ft u_int16_t | ||
| 93 | .Fn swap16 "u_int16_t val16" | ||
| 55 | .Sh DESCRIPTION | 94 | .Sh DESCRIPTION |
| 56 | These routines convert 16 and 32 bit quantities between network | 95 | These routines convert 16, 32 and 64-bit quantities between different |
| 96 | byte orderings. | ||
| 97 | The | ||
| 98 | .Dq swap | ||
| 99 | functions reverse the byte ordering of | ||
| 100 | the given quantity; the others convert either from/to the native | ||
| 101 | byte order used by the host to/from either little- or big-endian (a.k.a | ||
| 102 | network) order. | ||
| 103 | .Pp | ||
| 104 | Apart from the swap functions, the names can be described by this form: | ||
| 105 | {src-order}to{dst-order}{size}. | ||
| 106 | Both {src-order} and {dst-order} can take the following forms: | ||
| 107 | .Pp | ||
| 108 | .Bl -tag -width "be " -offset indent -compact | ||
| 109 | .It h | ||
| 110 | Host order. | ||
| 111 | .It n | ||
| 112 | Network order (big-endian). | ||
| 113 | .It be | ||
| 114 | Big-endian (most significant byte first). | ||
| 115 | .It le | ||
| 116 | Little-endian (least significant byte first). | ||
| 117 | .El | ||
| 118 | .Pp | ||
| 119 | One of the specified orderings must be | ||
| 120 | .Sq h . | ||
| 121 | {size} will take these forms: | ||
| 122 | .Pp | ||
| 123 | .Bl -tag -width "32 " -offset indent -compact | ||
| 124 | .It l | ||
| 125 | Long (32-bit, used in conjunction with forms involving | ||
| 126 | .Sq n ) . | ||
| 127 | .It s | ||
| 128 | Short (16-bit, used in conjunction with forms involving | ||
| 129 | .Sq n ) . | ||
| 130 | .It 16 | ||
| 131 | 16-bit. | ||
| 132 | .It 32 | ||
| 133 | 32-bit. | ||
| 134 | .It 64 | ||
| 135 | 64-bit. | ||
| 136 | .El | ||
| 137 | .Pp | ||
| 138 | The swap functions are of the form: swap{size}. | ||
| 139 | .Pp | ||
| 140 | Names involving | ||
| 141 | .Sq n | ||
| 142 | convert quantities between network | ||
| 57 | byte order and host byte order. | 143 | byte order and host byte order. |
| 144 | The last letter | ||
| 145 | .Pf ( Sq s | ||
| 146 | or | ||
| 147 | .Sq l ) | ||
| 148 | is a mnemonic | ||
| 149 | for the traditional names for such quantities, | ||
| 150 | .Li short | ||
| 151 | and | ||
| 152 | .Li long , | ||
| 153 | respectively. | ||
| 154 | Today, the C concept of | ||
| 155 | .Li short | ||
| 156 | and | ||
| 157 | .Li long | ||
| 158 | integers need not coincide with this traditional misunderstanding. | ||
| 58 | On machines which have a byte order which is the same as the network | 159 | On machines which have a byte order which is the same as the network |
| 59 | order, routines are defined as null macros. | 160 | order, routines are defined as null macros. |
| 60 | .Pp | 161 | .Pp |
| 61 | These routines are most often used in conjunction with Internet | 162 | The functions involving either |
| 62 | addresses and ports as returned by | 163 | .Dq be , |
| 164 | .Dq le , | ||
| 165 | or | ||
| 166 | .Dq swap | ||
| 167 | use the numbers | ||
| 168 | 16, 32, or 64 for specifying the bitwidth of the quantities they operate on. | ||
| 169 | Currently all supported architectures are either big- or little-endian | ||
| 170 | so either the | ||
| 171 | .Dq be | ||
| 172 | or | ||
| 173 | .Dq le | ||
| 174 | variants are implemented as null macros. | ||
| 175 | .Pp | ||
| 176 | The routines mentioned above which have either {src-order} or {dst-order} | ||
| 177 | set to | ||
| 178 | .Sq n | ||
| 179 | are most often used in | ||
| 180 | conjunction with Internet addresses and ports as returned by | ||
| 63 | .Xr gethostbyname 3 | 181 | .Xr gethostbyname 3 |
| 64 | and | 182 | and |
| 65 | .Xr getservent 3 . | 183 | .Xr getservent 3 . |
| 66 | .Sh SEE ALSO | 184 | .Sh SEE ALSO |
| 67 | .Xr gethostbyname 3 , | 185 | .Xr gethostbyname 3 , |
| 68 | .Xr getservent 3 | 186 | .Xr getservent 3 |
| 187 | .Sh STANDARDS | ||
| 188 | The | ||
| 189 | .Fn htonl , | ||
| 190 | .Fn htons , | ||
| 191 | .Fn ntohl , | ||
| 192 | and | ||
| 193 | .Fn ntohs | ||
| 194 | functions conform to | ||
| 195 | .St -p1003.1 . | ||
| 196 | The other functions are extensions that should not be used when portability | ||
| 197 | is required. | ||
| 69 | .Sh HISTORY | 198 | .Sh HISTORY |
| 70 | The | 199 | The |
| 71 | .Nm byteorder | 200 | .Nm byteorder |
| 72 | functions appeared in | 201 | functions appeared in |
| 73 | .Bx 4.2 . | 202 | .Bx 4.2 . |
| 74 | .Sh BUGS | 203 | .Sh BUGS |
| 75 | On the | 204 | On the vax, alpha, amd64, i386, and some mips and arm architectures, |
| 76 | .Tn VAX | 205 | bytes are handled backwards from most everyone else in the world. |
| 77 | bytes are handled backwards from most everyone else in | 206 | This is not expected to be fixed in the near future. |
| 78 | the world. This is not expected to be fixed in the near future. | ||
diff --git a/src/lib/libc/net/ethers.3 b/src/lib/libc/net/ethers.3 index 81e6c65935..c254a120a7 100644 --- a/src/lib/libc/net/ethers.3 +++ b/src/lib/libc/net/ethers.3 | |||
| @@ -1,65 +1,87 @@ | |||
| 1 | .\" $OpenBSD: ethers.3,v 1.23 2014/03/18 03:58:49 lteo Exp $ | ||
| 1 | .\" | 2 | .\" |
| 2 | .\" Written by roland@frob.com. Public domain. | 3 | .\" Written by roland@frob.com. Public domain. |
| 3 | .\" | 4 | .\" |
| 4 | .Dd December 16, 1993 | 5 | .Dd $Mdocdate: March 18 2014 $ |
| 5 | .Dt ETHERS 3 | 6 | .Dt ETHERS 3 |
| 6 | .Os NetBSD | 7 | .Os |
| 7 | .Sh NAME | 8 | .Sh NAME |
| 9 | .Nm ether_aton , | ||
| 8 | .Nm ether_ntoa , | 10 | .Nm ether_ntoa , |
| 9 | .Nm ether_addr , | ||
| 10 | .Nm ether_ntohost , | 11 | .Nm ether_ntohost , |
| 11 | .Nm ether_hostton , | 12 | .Nm ether_hostton , |
| 12 | .Nm ether_line , | 13 | .Nm ether_line |
| 13 | .Nd get ethers entry | 14 | .Nd get ethers entry |
| 14 | .Sh SYNOPSIS | 15 | .Sh SYNOPSIS |
| 15 | .Fd #include <netinet/if_ether.h> | 16 | .In sys/types.h |
| 17 | .In sys/socket.h | ||
| 18 | .In net/if.h | ||
| 19 | .In netinet/in.h | ||
| 20 | .In netinet/if_ether.h | ||
| 16 | .Ft char * | 21 | .Ft char * |
| 17 | .Fn ether_ntoa "struct ether_addr *e" | 22 | .Fn ether_ntoa "struct ether_addr *e" |
| 18 | .Ft struct ether_addr * | 23 | .Ft struct ether_addr * |
| 19 | .Fn ether_aton "char *s" | 24 | .Fn ether_aton "const char *s" |
| 25 | .Ft int | ||
| 20 | .Fn ether_ntohost "char *hostname" "struct ether_addr *e" | 26 | .Fn ether_ntohost "char *hostname" "struct ether_addr *e" |
| 21 | .Fn ether_hostton "char *hostname" "struct ether_addr *e" | 27 | .Ft int |
| 22 | .Fn ether_line "char *l" "struct ether_addr *e" "char *hostname" | 28 | .Fn ether_hostton "const char *hostname" "struct ether_addr *e" |
| 29 | .Ft int | ||
| 30 | .Fn ether_line "const char *l" "struct ether_addr *e" "char *hostname" | ||
| 23 | .Sh DESCRIPTION | 31 | .Sh DESCRIPTION |
| 24 | Ethernet addresses are represented by the | 32 | Ethernet addresses are represented by the |
| 25 | following structure: | 33 | following structure: |
| 26 | .Bd -literal -offset indent | 34 | .Bd -literal -offset indent |
| 27 | struct ether_addr { | 35 | struct ether_addr { |
| 28 | u_char ether_addr_octet[6]; | 36 | u_int8_t ether_addr_octet[ETHER_ADDR_LEN]; |
| 29 | }; | 37 | }; |
| 30 | .Ed | 38 | .Ed |
| 31 | .Pp | 39 | .Pp |
| 32 | The | 40 | The |
| 33 | .Fn ether_ntoa | 41 | .Fn ether_ntoa |
| 34 | function converts this structure into an ASCII string of the form | 42 | function converts this structure into an |
| 35 | ``xx:xx:xx:xx:xx:xx'', consisting of 6 hexadecimal numbers separated | 43 | .Tn ASCII |
| 36 | by colons. It returns a pointer to a static buffer that is reused for | 44 | string of the form |
| 37 | each call. | 45 | .Dq xx:xx:xx:xx:xx:xx , |
| 46 | consisting of 6 hexadecimal numbers separated | ||
| 47 | by colons. | ||
| 48 | It returns a pointer to a static buffer that is reused for each call. | ||
| 38 | The | 49 | The |
| 39 | .Fn ether_aton | 50 | .Fn ether_aton |
| 40 | converts an ASCII string of the same form and to a structure | 51 | converts an |
| 41 | containing the 6 octets of the address. It returns a pointer to a | 52 | .Tn ASCII |
| 42 | static structure that is reused for each call. | 53 | string of the same form and to a structure |
| 54 | containing the 6 octets of the address. | ||
| 55 | It returns a pointer to a static structure that is reused for each call. | ||
| 56 | .Fn ether_aton | ||
| 57 | will return NULL if the string does not represent a valid address. | ||
| 43 | .Pp | 58 | .Pp |
| 44 | The | 59 | The |
| 45 | .Fn ether_ntohost | 60 | .Fn ether_ntohost |
| 46 | and | 61 | and |
| 47 | .Fn ether_hostton | 62 | .Fn ether_hostton |
| 48 | functions interrogate the data base mapping host names to Ethernet | 63 | functions interrogate the database mapping host names to Ethernet |
| 49 | addresses, | 64 | addresses, |
| 50 | .Pa /etc/ethers . | 65 | .Pa /etc/ethers . |
| 51 | The | 66 | The |
| 52 | .Fn ether_ntohost | 67 | .Fn ether_ntohost |
| 53 | function looks up the given Ethernet address and writes the associated | 68 | function looks up the given Ethernet address and writes the associated |
| 54 | host name into the character buffer passed. | 69 | host name into the character buffer passed. |
| 70 | This buffer should be | ||
| 71 | .Dv MAXHOSTNAMELEN | ||
| 72 | characters in size. | ||
| 55 | The | 73 | The |
| 56 | .Fn ether_hostton | 74 | .Fn ether_hostton |
| 57 | function looks up the given host name and writes the associated | 75 | function looks up the given host name and writes the associated |
| 58 | Ethernet address into the structure passed. Both functions return | 76 | Ethernet address into the structure passed. |
| 59 | zero if they find the requested host name or address, and -1 if not. | 77 | Both functions return |
| 78 | zero if they find the requested host name or address, and \-1 if not. | ||
| 79 | .Pp | ||
| 60 | Each call reads | 80 | Each call reads |
| 61 | .Pa /etc/ethers | 81 | .Pa /etc/ethers |
| 62 | from the beginning; if a + appears alone on a line in the file, then | 82 | from the beginning; if a |
| 83 | .Ql + | ||
| 84 | appears alone on a line in the file, then | ||
| 63 | .Fn ether_hostton | 85 | .Fn ether_hostton |
| 64 | will consult the | 86 | will consult the |
| 65 | .Pa ethers.byname | 87 | .Pa ethers.byname |
| @@ -73,9 +95,13 @@ The | |||
| 73 | .Fn ether_line | 95 | .Fn ether_line |
| 74 | function parses a line from the | 96 | function parses a line from the |
| 75 | .Pa /etc/ethers | 97 | .Pa /etc/ethers |
| 76 | file and fills in the passed ``struct ether_addr'' and character | 98 | file and fills in the passed |
| 77 | buffer with the Ethernet address and host name on the line. It | 99 | .Li struct ether_addr |
| 78 | returns zero if the line was successfully parsed and -1 if not. | 100 | and character buffer with the Ethernet address and host name on the line. |
| 101 | It returns zero if the line was successfully parsed and \-1 if not. | ||
| 102 | The character buffer should be | ||
| 103 | .Dv MAXHOSTNAMELEN | ||
| 104 | characters in size. | ||
| 79 | .Sh FILES | 105 | .Sh FILES |
| 80 | .Bl -tag -width /etc/ethers -compact | 106 | .Bl -tag -width /etc/ethers -compact |
| 81 | .It Pa /etc/ethers | 107 | .It Pa /etc/ethers |
| @@ -91,12 +117,8 @@ The | |||
| 91 | and | 117 | and |
| 92 | .Fn ether_line | 118 | .Fn ether_line |
| 93 | functions were adopted from SunOS and appeared in | 119 | functions were adopted from SunOS and appeared in |
| 94 | NetBSD 0.9b. | 120 | .Nx 0.9b . |
| 95 | .Sh BUGS | 121 | .Sh BUGS |
| 96 | The data space used by these functions is static; if future use | 122 | The data space used by these functions is static; if future use |
| 97 | requires the data, it should be copied before any subsequent calls to | 123 | requires the data, it should be copied before any subsequent calls to |
| 98 | these functions overwrite it. There is no way to restrict how many | 124 | these functions overwrite it. |
| 99 | character will be written into the host name buffer passed. A very | ||
| 100 | long line in | ||
| 101 | .Pa /etc/ethers | ||
| 102 | could overflow your buffer. | ||
diff --git a/src/lib/libc/net/ethers.c b/src/lib/libc/net/ethers.c index 0f32b9b71b..af31bb8e60 100644 --- a/src/lib/libc/net/ethers.c +++ b/src/lib/libc/net/ethers.c | |||
| @@ -1,10 +1,25 @@ | |||
| 1 | /* $NetBSD: ethers.c,v 1.5 1995/02/25 06:20:28 cgd Exp $ */ | 1 | /* $OpenBSD: ethers.c,v 1.21 2013/11/24 23:51:28 deraadt Exp $ */ |
| 2 | 2 | ||
| 3 | /* | 3 | /* |
| 4 | * ethers(3N) a la Sun. | 4 | * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> |
| 5 | * | ||
| 6 | * Permission to use, copy, modify, and distribute this software for any | ||
| 7 | * purpose with or without fee is hereby granted, provided that the above | ||
| 8 | * copyright notice and this permission notice appear in all copies. | ||
| 5 | * | 9 | * |
| 6 | * Written by Roland McGrath <roland@frob.com> 10/14/93. | 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
| 7 | * Public domain. | 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
| 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 17 | */ | ||
| 18 | |||
| 19 | /* | ||
| 20 | * ethers(3) a la Sun. | ||
| 21 | * Originally Written by Roland McGrath <roland@frob.com> 10/14/93. | ||
| 22 | * Substantially modified by Todd C. Miller <Todd.Miller@courtesan.com> | ||
| 8 | */ | 23 | */ |
| 9 | 24 | ||
| 10 | #include <sys/types.h> | 25 | #include <sys/types.h> |
| @@ -18,57 +33,79 @@ | |||
| 18 | #include <stdio.h> | 33 | #include <stdio.h> |
| 19 | #include <stdlib.h> | 34 | #include <stdlib.h> |
| 20 | #include <string.h> | 35 | #include <string.h> |
| 36 | #include <ctype.h> | ||
| 37 | #ifdef YP | ||
| 38 | #include <rpcsvc/ypclnt.h> | ||
| 39 | #endif | ||
| 21 | 40 | ||
| 22 | #ifndef _PATH_ETHERS | 41 | #ifndef _PATH_ETHERS |
| 23 | #define _PATH_ETHERS "/etc/ethers" | 42 | #define _PATH_ETHERS "/etc/ethers" |
| 24 | #endif | 43 | #endif |
| 25 | 44 | ||
| 45 | static char * _ether_aton(const char *, struct ether_addr *); | ||
| 46 | |||
| 26 | char * | 47 | char * |
| 27 | ether_ntoa(e) | 48 | ether_ntoa(struct ether_addr *e) |
| 28 | struct ether_addr *e; | ||
| 29 | { | 49 | { |
| 30 | static char a[] = "xx:xx:xx:xx:xx:xx"; | 50 | static char a[] = "xx:xx:xx:xx:xx:xx"; |
| 31 | 51 | ||
| 32 | sprintf(a, "%02x:%02x:%02x:%02x:%02x:%02x", | 52 | (void)snprintf(a, sizeof a, "%02x:%02x:%02x:%02x:%02x:%02x", |
| 33 | e->ether_addr_octet[0], e->ether_addr_octet[1], | 53 | e->ether_addr_octet[0], e->ether_addr_octet[1], |
| 34 | e->ether_addr_octet[2], e->ether_addr_octet[3], | 54 | e->ether_addr_octet[2], e->ether_addr_octet[3], |
| 35 | e->ether_addr_octet[4], e->ether_addr_octet[5]); | 55 | e->ether_addr_octet[4], e->ether_addr_octet[5]); |
| 36 | return a; | 56 | |
| 57 | return (a); | ||
| 58 | } | ||
| 59 | |||
| 60 | static char * | ||
| 61 | _ether_aton(const char *s, struct ether_addr *e) | ||
| 62 | { | ||
| 63 | int i; | ||
| 64 | long l; | ||
| 65 | char *pp; | ||
| 66 | |||
| 67 | while (isspace((unsigned char)*s)) | ||
| 68 | s++; | ||
| 69 | |||
| 70 | /* expect 6 hex octets separated by ':' or space/NUL if last octet */ | ||
| 71 | for (i = 0; i < 6; i++) { | ||
| 72 | l = strtol(s, &pp, 16); | ||
| 73 | if (pp == s || l > 0xFF || l < 0) | ||
| 74 | return (NULL); | ||
| 75 | if (!(*pp == ':' || | ||
| 76 | (i == 5 && (isspace((unsigned char)*pp) || | ||
| 77 | *pp == '\0')))) | ||
| 78 | return (NULL); | ||
| 79 | e->ether_addr_octet[i] = (u_char)l; | ||
| 80 | s = pp + 1; | ||
| 81 | } | ||
| 82 | |||
| 83 | /* return character after the octets ala strtol(3) */ | ||
| 84 | return (pp); | ||
| 37 | } | 85 | } |
| 38 | 86 | ||
| 39 | struct ether_addr * | 87 | struct ether_addr * |
| 40 | ether_aton(s) | 88 | ether_aton(const char *s) |
| 41 | char *s; | ||
| 42 | { | 89 | { |
| 43 | static struct ether_addr n; | 90 | static struct ether_addr n; |
| 44 | u_int i[6]; | 91 | |
| 45 | 92 | return (_ether_aton(s, &n) ? &n : NULL); | |
| 46 | if (sscanf(s, " %x:%x:%x:%x:%x:%x ", &i[0], &i[1], | ||
| 47 | &i[2], &i[3], &i[4], &i[5]) == 6) { | ||
| 48 | n.ether_addr_octet[0] = (u_char)i[0]; | ||
| 49 | n.ether_addr_octet[1] = (u_char)i[1]; | ||
| 50 | n.ether_addr_octet[2] = (u_char)i[2]; | ||
| 51 | n.ether_addr_octet[3] = (u_char)i[3]; | ||
| 52 | n.ether_addr_octet[4] = (u_char)i[4]; | ||
| 53 | n.ether_addr_octet[5] = (u_char)i[5]; | ||
| 54 | return &n; | ||
| 55 | } | ||
| 56 | return NULL; | ||
| 57 | } | 93 | } |
| 58 | 94 | ||
| 59 | ether_ntohost(hostname, e) | 95 | int |
| 60 | char *hostname; | 96 | ether_ntohost(char *hostname, struct ether_addr *e) |
| 61 | struct ether_addr *e; | ||
| 62 | { | 97 | { |
| 63 | FILE *f; | 98 | FILE *f; |
| 64 | char buf[BUFSIZ]; | 99 | char buf[BUFSIZ+1], *p; |
| 100 | size_t len; | ||
| 65 | struct ether_addr try; | 101 | struct ether_addr try; |
| 66 | |||
| 67 | #ifdef YP | 102 | #ifdef YP |
| 68 | char trybuf[sizeof "xx:xx:xx:xx:xx:xx"]; | 103 | char trybuf[sizeof("xx:xx:xx:xx:xx:xx")]; |
| 69 | int trylen; | 104 | int trylen; |
| 105 | #endif | ||
| 70 | 106 | ||
| 71 | sprintf(trybuf, "%x:%x:%x:%x:%x:%x", | 107 | #ifdef YP |
| 108 | snprintf(trybuf, sizeof trybuf, "%x:%x:%x:%x:%x:%x", | ||
| 72 | e->ether_addr_octet[0], e->ether_addr_octet[1], | 109 | e->ether_addr_octet[0], e->ether_addr_octet[1], |
| 73 | e->ether_addr_octet[2], e->ether_addr_octet[3], | 110 | e->ether_addr_octet[2], e->ether_addr_octet[3], |
| 74 | e->ether_addr_octet[4], e->ether_addr_octet[5]); | 111 | e->ether_addr_octet[4], e->ether_addr_octet[5]); |
| @@ -76,12 +113,19 @@ ether_ntohost(hostname, e) | |||
| 76 | #endif | 113 | #endif |
| 77 | 114 | ||
| 78 | f = fopen(_PATH_ETHERS, "r"); | 115 | f = fopen(_PATH_ETHERS, "r"); |
| 79 | if (f==NULL) | 116 | if (f == NULL) |
| 80 | return -1; | 117 | return (-1); |
| 81 | while (fgets(buf, sizeof buf, f)) { | 118 | while ((p = fgetln(f, &len)) != NULL) { |
| 119 | if (p[len-1] == '\n') | ||
| 120 | len--; | ||
| 121 | if (len > sizeof(buf) - 2) | ||
| 122 | continue; | ||
| 123 | (void)memcpy(buf, p, len); | ||
| 124 | buf[len] = '\n'; /* code assumes newlines later on */ | ||
| 125 | buf[len+1] = '\0'; | ||
| 82 | #ifdef YP | 126 | #ifdef YP |
| 83 | /* A + in the file means try YP now. */ | 127 | /* A + in the file means try YP now. */ |
| 84 | if (!strncmp(buf, "+\n", sizeof buf)) { | 128 | if (!strncmp(buf, "+\n", sizeof(buf))) { |
| 85 | char *ypbuf, *ypdom; | 129 | char *ypbuf, *ypdom; |
| 86 | int ypbuflen; | 130 | int ypbuflen; |
| 87 | 131 | ||
| @@ -93,42 +137,49 @@ ether_ntohost(hostname, e) | |||
| 93 | if (ether_line(ypbuf, &try, hostname) == 0) { | 137 | if (ether_line(ypbuf, &try, hostname) == 0) { |
| 94 | free(ypbuf); | 138 | free(ypbuf); |
| 95 | (void)fclose(f); | 139 | (void)fclose(f); |
| 96 | return 0; | 140 | return (0); |
| 97 | } | 141 | } |
| 98 | free(ypbuf); | 142 | free(ypbuf); |
| 99 | continue; | 143 | continue; |
| 100 | } | 144 | } |
| 101 | #endif | 145 | #endif |
| 102 | if (ether_line(buf, &try, hostname) == 0 && | 146 | if (ether_line(buf, &try, hostname) == 0 && |
| 103 | bcmp((char *)&try, (char *)e, sizeof try) == 0) { | 147 | memcmp((void *)&try, (void *)e, sizeof(try)) == 0) { |
| 104 | (void)fclose(f); | 148 | (void)fclose(f); |
| 105 | return 0; | 149 | return (0); |
| 106 | } | 150 | } |
| 107 | } | 151 | } |
| 108 | (void)fclose(f); | 152 | (void)fclose(f); |
| 109 | errno = ENOENT; | 153 | errno = ENOENT; |
| 110 | return -1; | 154 | return (-1); |
| 111 | } | 155 | } |
| 112 | 156 | ||
| 113 | ether_hostton(hostname, e) | 157 | int |
| 114 | char *hostname; | 158 | ether_hostton(const char *hostname, struct ether_addr *e) |
| 115 | struct ether_addr *e; | ||
| 116 | { | 159 | { |
| 117 | FILE *f; | 160 | FILE *f; |
| 118 | char buf[BUFSIZ]; | 161 | char buf[BUFSIZ+1], *p; |
| 119 | char try[MAXHOSTNAMELEN]; | 162 | char try[MAXHOSTNAMELEN]; |
| 163 | size_t len; | ||
| 120 | #ifdef YP | 164 | #ifdef YP |
| 121 | int hostlen = strlen(hostname); | 165 | int hostlen = strlen(hostname); |
| 122 | #endif | 166 | #endif |
| 123 | 167 | ||
| 124 | f = fopen(_PATH_ETHERS, "r"); | 168 | f = fopen(_PATH_ETHERS, "r"); |
| 125 | if (f==NULL) | 169 | if (f==NULL) |
| 126 | return -1; | 170 | return (-1); |
| 127 | 171 | ||
| 128 | while (fgets(buf, sizeof buf, f)) { | 172 | while ((p = fgetln(f, &len)) != NULL) { |
| 173 | if (p[len-1] == '\n') | ||
| 174 | len--; | ||
| 175 | if (len > sizeof(buf) - 2) | ||
| 176 | continue; | ||
| 177 | memcpy(buf, p, len); | ||
| 178 | buf[len] = '\n'; /* code assumes newlines later on */ | ||
| 179 | buf[len+1] = '\0'; | ||
| 129 | #ifdef YP | 180 | #ifdef YP |
| 130 | /* A + in the file means try YP now. */ | 181 | /* A + in the file means try YP now. */ |
| 131 | if (!strncmp(buf, "+\n", sizeof buf)) { | 182 | if (!strncmp(buf, "+\n", sizeof(buf))) { |
| 132 | char *ypbuf, *ypdom; | 183 | char *ypbuf, *ypdom; |
| 133 | int ypbuflen; | 184 | int ypbuflen; |
| 134 | 185 | ||
| @@ -140,7 +191,7 @@ ether_hostton(hostname, e) | |||
| 140 | if (ether_line(ypbuf, e, try) == 0) { | 191 | if (ether_line(ypbuf, e, try) == 0) { |
| 141 | free(ypbuf); | 192 | free(ypbuf); |
| 142 | (void)fclose(f); | 193 | (void)fclose(f); |
| 143 | return 0; | 194 | return (0); |
| 144 | } | 195 | } |
| 145 | free(ypbuf); | 196 | free(ypbuf); |
| 146 | continue; | 197 | continue; |
| @@ -148,31 +199,36 @@ ether_hostton(hostname, e) | |||
| 148 | #endif | 199 | #endif |
| 149 | if (ether_line(buf, e, try) == 0 && strcmp(hostname, try) == 0) { | 200 | if (ether_line(buf, e, try) == 0 && strcmp(hostname, try) == 0) { |
| 150 | (void)fclose(f); | 201 | (void)fclose(f); |
| 151 | return 0; | 202 | return (0); |
| 152 | } | 203 | } |
| 153 | } | 204 | } |
| 154 | (void)fclose(f); | 205 | (void)fclose(f); |
| 155 | errno = ENOENT; | 206 | errno = ENOENT; |
| 156 | return -1; | 207 | return (-1); |
| 157 | } | 208 | } |
| 158 | 209 | ||
| 159 | ether_line(l, e, hostname) | 210 | int |
| 160 | char *l; | 211 | ether_line(const char *line, struct ether_addr *e, char *hostname) |
| 161 | struct ether_addr *e; | ||
| 162 | char *hostname; | ||
| 163 | { | 212 | { |
| 164 | u_int i[6]; | 213 | char *p; |
| 165 | 214 | size_t n; | |
| 166 | if (sscanf(l, " %x:%x:%x:%x:%x:%x %s\n", &i[0], &i[1], | 215 | |
| 167 | &i[2], &i[3], &i[4], &i[5], hostname) == 7) { | 216 | /* Parse "xx:xx:xx:xx:xx:xx" */ |
| 168 | e->ether_addr_octet[0] = (u_char)i[0]; | 217 | if ((p = _ether_aton(line, e)) == NULL || (*p != ' ' && *p != '\t')) |
| 169 | e->ether_addr_octet[1] = (u_char)i[1]; | 218 | goto bad; |
| 170 | e->ether_addr_octet[2] = (u_char)i[2]; | 219 | |
| 171 | e->ether_addr_octet[3] = (u_char)i[3]; | 220 | /* Now get the hostname */ |
| 172 | e->ether_addr_octet[4] = (u_char)i[4]; | 221 | while (isspace((unsigned char)*p)) |
| 173 | e->ether_addr_octet[5] = (u_char)i[5]; | 222 | p++; |
| 174 | return 0; | 223 | if (*p == '\0') |
| 175 | } | 224 | goto bad; |
| 225 | n = strcspn(p, " \t\n"); | ||
| 226 | if (n >= MAXHOSTNAMELEN) | ||
| 227 | goto bad; | ||
| 228 | strlcpy(hostname, p, n + 1); | ||
| 229 | return (0); | ||
| 230 | |||
| 231 | bad: | ||
| 176 | errno = EINVAL; | 232 | errno = EINVAL; |
| 177 | return -1; | 233 | return (-1); |
| 178 | } | 234 | } |
diff --git a/src/lib/libc/stdlib/calloc.c b/src/lib/libc/net/freeaddrinfo.c index 3353fab052..58702d0b18 100644 --- a/src/lib/libc/stdlib/calloc.c +++ b/src/lib/libc/net/freeaddrinfo.c | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | /*- | 1 | /* $OpenBSD: freeaddrinfo.c,v 1.6 2005/03/25 13:24:11 otto Exp $ */ |
| 2 | * Copyright (c) 1990 The Regents of the University of California. | 2 | |
| 3 | * All rights reserved. | 3 | /* |
| 4 | * Copyright (c) 1996, 1997, 1998, 1999, Craig Metz, All rights reserved. | ||
| 4 | * | 5 | * |
| 5 | * Redistribution and use in source and binary forms, with or without | 6 | * Redistribution and use in source and binary forms, with or without |
| 6 | * modification, are permitted provided that the following conditions | 7 | * modification, are permitted provided that the following conditions |
| @@ -12,9 +13,9 @@ | |||
| 12 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. All advertising materials mentioning features or use of this software |
| 14 | * must display the following acknowledgement: | 15 | * must display the following acknowledgement: |
| 15 | * This product includes software developed by the University of | 16 | * This product includes software developed by Craig Metz and |
| 16 | * California, Berkeley and its contributors. | 17 | * by other contributors. |
| 17 | * 4. Neither the name of the University nor the names of its contributors | 18 | * 4. Neither the name of the author nor the names of contributors |
| 18 | * may be used to endorse or promote products derived from this software | 19 | * may be used to endorse or promote products derived from this software |
| 19 | * without specific prior written permission. | 20 | * without specific prior written permission. |
| 20 | * | 21 | * |
| @@ -31,23 +32,19 @@ | |||
| 31 | * SUCH DAMAGE. | 32 | * SUCH DAMAGE. |
| 32 | */ | 33 | */ |
| 33 | 34 | ||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 35 | /*static char *sccsid = "from: @(#)calloc.c 5.6 (Berkeley) 2/23/91";*/ | ||
| 36 | static char *rcsid = "$Id: calloc.c,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $"; | ||
| 37 | #endif /* LIBC_SCCS and not lint */ | ||
| 38 | |||
| 39 | #include <stdlib.h> | 35 | #include <stdlib.h> |
| 40 | #include <string.h> | 36 | #include <netdb.h> |
| 41 | 37 | ||
| 42 | void * | 38 | void |
| 43 | calloc(num, size) | 39 | freeaddrinfo(struct addrinfo *ai) |
| 44 | size_t num; | ||
| 45 | register size_t size; | ||
| 46 | { | 40 | { |
| 47 | register void *p; | 41 | struct addrinfo *p; |
| 48 | 42 | ||
| 49 | size *= num; | 43 | do { |
| 50 | if (p = malloc(size)) | 44 | p = ai; |
| 51 | memset(p, '\0', size); | 45 | ai = ai->ai_next; |
| 52 | return(p); | 46 | if (p->ai_canonname) |
| 47 | free(p->ai_canonname); | ||
| 48 | free((void *)p); | ||
| 49 | } while (ai); | ||
| 53 | } | 50 | } |
diff --git a/src/lib/libc/net/gai_strerror.3 b/src/lib/libc/net/gai_strerror.3 new file mode 100644 index 0000000000..e0373eb91e --- /dev/null +++ b/src/lib/libc/net/gai_strerror.3 | |||
| @@ -0,0 +1,95 @@ | |||
| 1 | .\" $OpenBSD: gai_strerror.3,v 1.9 2014/01/21 03:15:45 schwarze Exp $ | ||
| 2 | .\" $KAME: gai_strerror.3,v 1.1 2005/01/05 03:04:47 itojun Exp $ | ||
| 3 | .\" | ||
| 4 | .\" Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") | ||
| 5 | .\" Copyright (C) 2000, 2001 Internet Software Consortium. | ||
| 6 | .\" | ||
| 7 | .\" Permission to use, copy, modify, and distribute this software for any | ||
| 8 | .\" purpose with or without fee is hereby granted, provided that the above | ||
| 9 | .\" copyright notice and this permission notice appear in all copies. | ||
| 10 | .\" | ||
| 11 | .\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH | ||
| 12 | .\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY | ||
| 13 | .\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, | ||
| 14 | .\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM | ||
| 15 | .\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE | ||
| 16 | .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | ||
| 17 | .\" PERFORMANCE OF THIS SOFTWARE. | ||
| 18 | .\" | ||
| 19 | .Dd $Mdocdate: January 21 2014 $ | ||
| 20 | .Dt GAI_STRERROR 3 | ||
| 21 | .Os | ||
| 22 | .Sh NAME | ||
| 23 | .Nm gai_strerror | ||
| 24 | .Nd get error message string from EAI_xxx error code | ||
| 25 | .Sh SYNOPSIS | ||
| 26 | .In sys/types.h | ||
| 27 | .In sys/socket.h | ||
| 28 | .In netdb.h | ||
| 29 | .Ft "const char *" | ||
| 30 | .Fn gai_strerror "int ecode" | ||
| 31 | .Sh DESCRIPTION | ||
| 32 | The | ||
| 33 | .Fn gai_strerror | ||
| 34 | function returns an error message string corresponding to the error code | ||
| 35 | returned by | ||
| 36 | .Xr getaddrinfo 3 | ||
| 37 | or | ||
| 38 | .Xr getnameinfo 3 . | ||
| 39 | .Pp | ||
| 40 | The following error codes and their meaning are defined in | ||
| 41 | .In netdb.h : | ||
| 42 | .Pp | ||
| 43 | .Bl -tag -width "EAI_ADDRFAMILYXX" -offset indent -compact | ||
| 44 | .It Dv EAI_ADDRFAMILY | ||
| 45 | address family for | ||
| 46 | .Fa hostname | ||
| 47 | not supported | ||
| 48 | .It Dv EAI_AGAIN | ||
| 49 | temporary failure in name resolution | ||
| 50 | .It Dv EAI_BADFLAGS | ||
| 51 | invalid value for | ||
| 52 | .Fa ai_flags | ||
| 53 | .It Dv EAI_BADHINTS | ||
| 54 | invalid value for | ||
| 55 | .Fa hints | ||
| 56 | .It Dv EAI_FAIL | ||
| 57 | non-recoverable failure in name resolution | ||
| 58 | .It Dv EAI_FAMILY | ||
| 59 | .Fa ai_family | ||
| 60 | not supported. | ||
| 61 | .It Dv EAI_MEMORY | ||
| 62 | memory allocation failure | ||
| 63 | .It Dv EAI_NODATA | ||
| 64 | no address associated with | ||
| 65 | .Fa hostname | ||
| 66 | .It Dv EAI_NONAME | ||
| 67 | .Fa hostname | ||
| 68 | or | ||
| 69 | .Fa servname | ||
| 70 | not provided, or not known | ||
| 71 | .It Dv EAI_OVERFLOW | ||
| 72 | argument buffer overflow | ||
| 73 | .It Dv EAI_PROTOCOL | ||
| 74 | resolved protocol is unknown | ||
| 75 | .It Dv EAI_SERVICE | ||
| 76 | .Fa servname | ||
| 77 | not supported for | ||
| 78 | .Fa ai_socktype | ||
| 79 | .It Dv EAI_SOCKTYPE | ||
| 80 | .Fa ai_socktype | ||
| 81 | not supported | ||
| 82 | .It Dv EAI_SYSTEM | ||
| 83 | system error returned in | ||
| 84 | .Va errno | ||
| 85 | .El | ||
| 86 | .Sh RETURN VALUES | ||
| 87 | .Fn gai_strerror | ||
| 88 | returns a pointer to the error message string corresponding to | ||
| 89 | .Fa ecode . | ||
| 90 | If | ||
| 91 | .Fa ecode | ||
| 92 | is out of range, an implementation-specific error message string is returned. | ||
| 93 | .Sh SEE ALSO | ||
| 94 | .Xr getaddrinfo 3 , | ||
| 95 | .Xr getnameinfo 3 | ||
diff --git a/src/lib/libc/net/gai_strerror.c b/src/lib/libc/net/gai_strerror.c new file mode 100644 index 0000000000..f4126413f8 --- /dev/null +++ b/src/lib/libc/net/gai_strerror.c | |||
| @@ -0,0 +1,78 @@ | |||
| 1 | /* $OpenBSD: gai_strerror.c,v 1.7 2009/06/02 16:47:50 jasper Exp $ */ | ||
| 2 | |||
| 3 | /* | ||
| 4 | * Copyright (c) 1997-1999, Craig Metz, All rights reserved. | ||
| 5 | * | ||
| 6 | * Redistribution and use in source and binary forms, with or without | ||
| 7 | * modification, are permitted provided that the following conditions | ||
| 8 | * are met: | ||
| 9 | * 1. Redistributions of source code must retain the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer. | ||
| 11 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 12 | * notice, this list of conditions and the following disclaimer in the | ||
| 13 | * documentation and/or other materials provided with the distribution. | ||
| 14 | * 3. All advertising materials mentioning features or use of this software | ||
| 15 | * must display the following acknowledgement: | ||
| 16 | * This product includes software developed by Craig Metz and | ||
| 17 | * by other contributors. | ||
| 18 | * 4. Neither the name of the author nor the names of contributors | ||
| 19 | * may be used to endorse or promote products derived from this software | ||
| 20 | * without specific prior written permission. | ||
| 21 | * | ||
| 22 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
| 23 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 24 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 25 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
| 26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 32 | * SUCH DAMAGE. | ||
| 33 | */ | ||
| 34 | |||
| 35 | /* gai_strerror() v1.38 */ | ||
| 36 | |||
| 37 | #include <sys/types.h> | ||
| 38 | #include <netdb.h> | ||
| 39 | #include <errno.h> | ||
| 40 | |||
| 41 | const char * | ||
| 42 | gai_strerror(int errnum) | ||
| 43 | { | ||
| 44 | switch (errnum) { | ||
| 45 | case 0: | ||
| 46 | return "no error"; | ||
| 47 | case EAI_BADFLAGS: | ||
| 48 | return "invalid value for ai_flags"; | ||
| 49 | case EAI_NONAME: | ||
| 50 | return "name or service is not known"; | ||
| 51 | case EAI_AGAIN: | ||
| 52 | return "temporary failure in name resolution"; | ||
| 53 | case EAI_FAIL: | ||
| 54 | return "non-recoverable failure in name resolution"; | ||
| 55 | case EAI_NODATA: | ||
| 56 | return "no address associated with name"; | ||
| 57 | case EAI_FAMILY: | ||
| 58 | return "ai_family not supported"; | ||
| 59 | case EAI_SOCKTYPE: | ||
| 60 | return "ai_socktype not supported"; | ||
| 61 | case EAI_SERVICE: | ||
| 62 | return "service not supported for ai_socktype"; | ||
| 63 | case EAI_ADDRFAMILY: | ||
| 64 | return "address family for name not supported"; | ||
| 65 | case EAI_MEMORY: | ||
| 66 | return "memory allocation failure"; | ||
| 67 | case EAI_SYSTEM: | ||
| 68 | return "system error"; | ||
| 69 | case EAI_BADHINTS: | ||
| 70 | return "invalid value for hints"; | ||
| 71 | case EAI_PROTOCOL: | ||
| 72 | return "resolved protocol is unknown"; | ||
| 73 | case EAI_OVERFLOW: | ||
| 74 | return "argument buffer overflow"; | ||
| 75 | default: | ||
| 76 | return "unknown/invalid error"; | ||
| 77 | } | ||
| 78 | } | ||
diff --git a/src/lib/libc/net/getaddrinfo.3 b/src/lib/libc/net/getaddrinfo.3 new file mode 100644 index 0000000000..db4417ab35 --- /dev/null +++ b/src/lib/libc/net/getaddrinfo.3 | |||
| @@ -0,0 +1,465 @@ | |||
| 1 | .\" $OpenBSD: getaddrinfo.3,v 1.54 2014/01/21 03:15:45 schwarze Exp $ | ||
| 2 | .\" $KAME: getaddrinfo.3,v 1.36 2005/01/05 03:23:05 itojun Exp $ | ||
| 3 | .\" | ||
| 4 | .\" Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") | ||
| 5 | .\" Copyright (C) 2000, 2001 Internet Software Consortium. | ||
| 6 | .\" | ||
| 7 | .\" Permission to use, copy, modify, and distribute this software for any | ||
| 8 | .\" purpose with or without fee is hereby granted, provided that the above | ||
| 9 | .\" copyright notice and this permission notice appear in all copies. | ||
| 10 | .\" | ||
| 11 | .\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH | ||
| 12 | .\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY | ||
| 13 | .\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, | ||
| 14 | .\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM | ||
| 15 | .\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE | ||
| 16 | .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | ||
| 17 | .\" PERFORMANCE OF THIS SOFTWARE. | ||
| 18 | .\" | ||
| 19 | .Dd $Mdocdate: January 21 2014 $ | ||
| 20 | .Dt GETADDRINFO 3 | ||
| 21 | .Os | ||
| 22 | .Sh NAME | ||
| 23 | .Nm getaddrinfo , | ||
| 24 | .Nm freeaddrinfo | ||
| 25 | .Nd host and service name to socket address structure | ||
| 26 | .Sh SYNOPSIS | ||
| 27 | .In sys/types.h | ||
| 28 | .In sys/socket.h | ||
| 29 | .In netdb.h | ||
| 30 | .Ft int | ||
| 31 | .Fn getaddrinfo "const char *hostname" "const char *servname" \ | ||
| 32 | "const struct addrinfo *hints" "struct addrinfo **res" | ||
| 33 | .Ft void | ||
| 34 | .Fn freeaddrinfo "struct addrinfo *ai" | ||
| 35 | .Sh DESCRIPTION | ||
| 36 | The | ||
| 37 | .Fn getaddrinfo | ||
| 38 | function is used to get a list of | ||
| 39 | .Tn IP | ||
| 40 | addresses and port numbers for host | ||
| 41 | .Fa hostname | ||
| 42 | and service | ||
| 43 | .Fa servname . | ||
| 44 | It is a replacement for and provides more flexibility than the | ||
| 45 | .Xr gethostbyname 3 | ||
| 46 | and | ||
| 47 | .Xr getservbyname 3 | ||
| 48 | functions. | ||
| 49 | .Pp | ||
| 50 | The | ||
| 51 | .Fa hostname | ||
| 52 | and | ||
| 53 | .Fa servname | ||
| 54 | arguments are either pointers to NUL-terminated strings or the null pointer. | ||
| 55 | An acceptable value for | ||
| 56 | .Fa hostname | ||
| 57 | is either a valid host name or a numeric host address string consisting | ||
| 58 | of a dotted decimal IPv4 address or an IPv6 address. | ||
| 59 | The | ||
| 60 | .Fa servname | ||
| 61 | is either a decimal port number or a service name listed in | ||
| 62 | .Xr services 5 . | ||
| 63 | At least one of | ||
| 64 | .Fa hostname | ||
| 65 | and | ||
| 66 | .Fa servname | ||
| 67 | must be non-null. | ||
| 68 | .Pp | ||
| 69 | .Fa hints | ||
| 70 | is an optional pointer to a | ||
| 71 | .Li struct addrinfo , | ||
| 72 | as defined by | ||
| 73 | .In netdb.h : | ||
| 74 | .Bd -literal | ||
| 75 | struct addrinfo { | ||
| 76 | int ai_flags; /* input flags */ | ||
| 77 | int ai_family; /* protocol family for socket */ | ||
| 78 | int ai_socktype; /* socket type */ | ||
| 79 | int ai_protocol; /* protocol for socket */ | ||
| 80 | socklen_t ai_addrlen; /* length of socket-address */ | ||
| 81 | struct sockaddr *ai_addr; /* socket-address for socket */ | ||
| 82 | char *ai_canonname; /* canonical name for service location */ | ||
| 83 | struct addrinfo *ai_next; /* pointer to next in list */ | ||
| 84 | }; | ||
| 85 | .Ed | ||
| 86 | .Pp | ||
| 87 | This structure can be used to provide hints concerning the type of socket | ||
| 88 | that the caller supports or wishes to use. | ||
| 89 | The caller can supply the following structure elements in | ||
| 90 | .Fa hints : | ||
| 91 | .Bl -tag -width "ai_socktypeXX" | ||
| 92 | .It Fa ai_family | ||
| 93 | The protocol family that should be used. | ||
| 94 | When | ||
| 95 | .Fa ai_family | ||
| 96 | is set to | ||
| 97 | .Dv PF_UNSPEC , | ||
| 98 | it means the caller will accept any protocol family supported by the | ||
| 99 | operating system. | ||
| 100 | .It Fa ai_socktype | ||
| 101 | Denotes the type of socket that is wanted: | ||
| 102 | .Dv SOCK_STREAM , | ||
| 103 | .Dv SOCK_DGRAM , | ||
| 104 | or | ||
| 105 | .Dv SOCK_RAW . | ||
| 106 | When | ||
| 107 | .Fa ai_socktype | ||
| 108 | is zero the caller will accept any socket type. | ||
| 109 | .It Fa ai_protocol | ||
| 110 | Indicates which transport protocol is desired, | ||
| 111 | .Dv IPPROTO_UDP | ||
| 112 | or | ||
| 113 | .Dv IPPROTO_TCP . | ||
| 114 | If | ||
| 115 | .Fa ai_protocol | ||
| 116 | is zero the caller will accept any protocol. | ||
| 117 | .It Fa ai_flags | ||
| 118 | .Fa ai_flags | ||
| 119 | is formed by | ||
| 120 | .Tn OR Ns 'ing | ||
| 121 | the following values: | ||
| 122 | .Bl -tag -width "AI_CANONNAMEXX" | ||
| 123 | .It Dv AI_CANONNAME | ||
| 124 | If the | ||
| 125 | .Dv AI_CANONNAME | ||
| 126 | bit is set, a successful call to | ||
| 127 | .Fn getaddrinfo | ||
| 128 | will return a NUL-terminated string containing the canonical name | ||
| 129 | of the specified host name in the | ||
| 130 | .Fa ai_canonname | ||
| 131 | element of the first | ||
| 132 | .Li addrinfo | ||
| 133 | structure returned. | ||
| 134 | .It Dv AI_FQDN | ||
| 135 | If the | ||
| 136 | .Dv AI_FQDN | ||
| 137 | bit is set, a successful call to | ||
| 138 | .Fn getaddrinfo | ||
| 139 | will return a NUL-terminated string containing the fully qualified domain name | ||
| 140 | of the specified host name in the | ||
| 141 | .Fa ai_canonname | ||
| 142 | element of the first | ||
| 143 | .Li addrinfo | ||
| 144 | structure returned. | ||
| 145 | .Pp | ||
| 146 | This is different from the | ||
| 147 | .Dv AI_CANONNAME | ||
| 148 | bit flag that returns the canonical name registered in DNS, | ||
| 149 | which may be different from the fully qualified domain name | ||
| 150 | that the host name resolved to. | ||
| 151 | Only one of the | ||
| 152 | .Dv AI_FQDN | ||
| 153 | and | ||
| 154 | .Dv AI_CANONNAME | ||
| 155 | bits can be set. | ||
| 156 | .It Dv AI_NUMERICHOST | ||
| 157 | If the | ||
| 158 | .Dv AI_NUMERICHOST | ||
| 159 | bit is set, it indicates that | ||
| 160 | .Fa hostname | ||
| 161 | should be treated as a numeric string defining an IPv4 or IPv6 address | ||
| 162 | and no name resolution should be attempted. | ||
| 163 | .It Dv AI_NUMERICSERV | ||
| 164 | If the | ||
| 165 | .Dv AI_NUMERICSERV | ||
| 166 | bit is set, it indicates that | ||
| 167 | .Fa servname | ||
| 168 | should be treated as a numeric port string | ||
| 169 | and no service name resolution should be attempted. | ||
| 170 | .It Dv AI_PASSIVE | ||
| 171 | If the | ||
| 172 | .Dv AI_PASSIVE | ||
| 173 | bit is set it indicates that the returned socket address structure | ||
| 174 | is intended for use in a call to | ||
| 175 | .Xr bind 2 . | ||
| 176 | In this case, if the | ||
| 177 | .Fa hostname | ||
| 178 | argument is the null pointer, then the IP address portion of the | ||
| 179 | socket address structure will be set to | ||
| 180 | .Dv INADDR_ANY | ||
| 181 | for an IPv4 address or | ||
| 182 | .Dv IN6ADDR_ANY_INIT | ||
| 183 | for an IPv6 address. | ||
| 184 | .Pp | ||
| 185 | If the | ||
| 186 | .Dv AI_PASSIVE | ||
| 187 | bit is not set, the returned socket address structure will be ready | ||
| 188 | for use in a call to | ||
| 189 | .Xr connect 2 | ||
| 190 | for a connection-oriented protocol or | ||
| 191 | .Xr connect 2 , | ||
| 192 | .Xr sendto 2 , | ||
| 193 | or | ||
| 194 | .Xr sendmsg 2 | ||
| 195 | if a connectionless protocol was chosen. | ||
| 196 | The | ||
| 197 | .Tn IP | ||
| 198 | address portion of the socket address structure will be set to the | ||
| 199 | loopback address if | ||
| 200 | .Fa hostname | ||
| 201 | is the null pointer and | ||
| 202 | .Dv AI_PASSIVE | ||
| 203 | is not set. | ||
| 204 | .El | ||
| 205 | .El | ||
| 206 | .Pp | ||
| 207 | All other elements of the | ||
| 208 | .Li addrinfo | ||
| 209 | structure passed via | ||
| 210 | .Fa hints | ||
| 211 | must be zero or the null pointer. | ||
| 212 | .Pp | ||
| 213 | If | ||
| 214 | .Fa hints | ||
| 215 | is the null pointer, | ||
| 216 | .Fn getaddrinfo | ||
| 217 | behaves as if the caller provided a | ||
| 218 | .Li struct addrinfo | ||
| 219 | with | ||
| 220 | .Fa ai_family | ||
| 221 | set to | ||
| 222 | .Dv PF_UNSPEC | ||
| 223 | and all other elements set to zero or | ||
| 224 | .Dv NULL . | ||
| 225 | .Pp | ||
| 226 | After a successful call to | ||
| 227 | .Fn getaddrinfo , | ||
| 228 | .Fa *res | ||
| 229 | is a pointer to a linked list of one or more | ||
| 230 | .Li addrinfo | ||
| 231 | structures. | ||
| 232 | The list can be traversed by following the | ||
| 233 | .Fa ai_next | ||
| 234 | pointer in each | ||
| 235 | .Li addrinfo | ||
| 236 | structure until a null pointer is encountered. | ||
| 237 | The three members | ||
| 238 | .Fa ai_family , | ||
| 239 | .Fa ai_socktype , | ||
| 240 | and | ||
| 241 | .Fa ai_protocol | ||
| 242 | in each returned | ||
| 243 | .Li addrinfo | ||
| 244 | structure are suitable for a call to | ||
| 245 | .Xr socket 2 . | ||
| 246 | For each | ||
| 247 | .Li addrinfo | ||
| 248 | structure in the list, the | ||
| 249 | .Fa ai_addr | ||
| 250 | member points to a filled-in socket address structure of length | ||
| 251 | .Fa ai_addrlen . | ||
| 252 | .Pp | ||
| 253 | This implementation of | ||
| 254 | .Fn getaddrinfo | ||
| 255 | allows numeric IPv6 address notation with scope identifier, | ||
| 256 | as documented in RFC 4007. | ||
| 257 | By appending the percent character and scope identifier to addresses, | ||
| 258 | one can fill the | ||
| 259 | .Li sin6_scope_id | ||
| 260 | field for addresses. | ||
| 261 | This would make management of scoped addresses easier | ||
| 262 | and allows cut-and-paste input of scoped addresses. | ||
| 263 | .Pp | ||
| 264 | At this moment the code supports only link-local addresses with the format. | ||
| 265 | The scope identifier is hardcoded to the name of the hardware interface | ||
| 266 | associated | ||
| 267 | with the link | ||
| 268 | .Po | ||
| 269 | such as | ||
| 270 | .Li ne0 | ||
| 271 | .Pc . | ||
| 272 | An example is | ||
| 273 | .Dq Li fe80::1%ne0 , | ||
| 274 | which means | ||
| 275 | .Do | ||
| 276 | .Li fe80::1 | ||
| 277 | on the link associated with the | ||
| 278 | .Li ne0 | ||
| 279 | interface | ||
| 280 | .Dc . | ||
| 281 | .Pp | ||
| 282 | The current implementation assumes a one-to-one relationship between | ||
| 283 | the interface and link, which is not necessarily true from the specification. | ||
| 284 | .Pp | ||
| 285 | All of the information returned by | ||
| 286 | .Fn getaddrinfo | ||
| 287 | is dynamically allocated: the | ||
| 288 | .Li addrinfo | ||
| 289 | structures themselves as well as the socket address structures and | ||
| 290 | the canonical host name strings included in the | ||
| 291 | .Li addrinfo | ||
| 292 | structures. | ||
| 293 | .Pp | ||
| 294 | Memory allocated for the dynamically allocated structures created by | ||
| 295 | a successful call to | ||
| 296 | .Fn getaddrinfo | ||
| 297 | is released by the | ||
| 298 | .Fn freeaddrinfo | ||
| 299 | function. | ||
| 300 | The | ||
| 301 | .Fa ai | ||
| 302 | pointer should be an | ||
| 303 | .Li addrinfo | ||
| 304 | structure created by a call to | ||
| 305 | .Fn getaddrinfo . | ||
| 306 | .Sh RETURN VALUES | ||
| 307 | .Fn getaddrinfo | ||
| 308 | returns zero on success or one of the error codes listed in | ||
| 309 | .Xr gai_strerror 3 | ||
| 310 | if an error occurs. | ||
| 311 | If an error occurs, no memory is allocated by | ||
| 312 | .Fn getaddrinfo , | ||
| 313 | therefore it is not necessary to release the | ||
| 314 | .Li addrinfo | ||
| 315 | structure(s). | ||
| 316 | .Sh EXAMPLES | ||
| 317 | The following code tries to connect to | ||
| 318 | .Dq Li www.kame.net | ||
| 319 | service | ||
| 320 | .Dq Li www | ||
| 321 | via a stream socket. | ||
| 322 | It loops through all the addresses available, regardless of address family. | ||
| 323 | If the destination resolves to an IPv4 address, it will use an | ||
| 324 | .Dv AF_INET | ||
| 325 | socket. | ||
| 326 | Similarly, if it resolves to IPv6, an | ||
| 327 | .Dv AF_INET6 | ||
| 328 | socket is used. | ||
| 329 | Observe that there is no hardcoded reference to a particular address family. | ||
| 330 | The code works even if | ||
| 331 | .Fn getaddrinfo | ||
| 332 | returns addresses that are not IPv4/v6. | ||
| 333 | .Bd -literal -offset indent | ||
| 334 | struct addrinfo hints, *res, *res0; | ||
| 335 | int error; | ||
| 336 | int save_errno; | ||
| 337 | int s; | ||
| 338 | const char *cause = NULL; | ||
| 339 | |||
| 340 | memset(&hints, 0, sizeof(hints)); | ||
| 341 | hints.ai_family = PF_UNSPEC; | ||
| 342 | hints.ai_socktype = SOCK_STREAM; | ||
| 343 | error = getaddrinfo("www.kame.net", "www", &hints, &res0); | ||
| 344 | if (error) | ||
| 345 | errx(1, "%s", gai_strerror(error)); | ||
| 346 | s = -1; | ||
| 347 | for (res = res0; res; res = res->ai_next) { | ||
| 348 | s = socket(res->ai_family, res->ai_socktype, | ||
| 349 | res->ai_protocol); | ||
| 350 | if (s == -1) { | ||
| 351 | cause = "socket"; | ||
| 352 | continue; | ||
| 353 | } | ||
| 354 | |||
| 355 | if (connect(s, res->ai_addr, res->ai_addrlen) == -1) { | ||
| 356 | cause = "connect"; | ||
| 357 | save_errno = errno; | ||
| 358 | close(s); | ||
| 359 | errno = save_errno; | ||
| 360 | s = -1; | ||
| 361 | continue; | ||
| 362 | } | ||
| 363 | |||
| 364 | break; /* okay we got one */ | ||
| 365 | } | ||
| 366 | if (s == -1) | ||
| 367 | err(1, "%s", cause); | ||
| 368 | freeaddrinfo(res0); | ||
| 369 | .Ed | ||
| 370 | .Pp | ||
| 371 | The following example tries to open a wildcard listening socket onto service | ||
| 372 | .Dq Li www , | ||
| 373 | for all the address families available. | ||
| 374 | .Bd -literal -offset indent | ||
| 375 | struct addrinfo hints, *res, *res0; | ||
| 376 | int error; | ||
| 377 | int save_errno; | ||
| 378 | int s[MAXSOCK]; | ||
| 379 | int nsock; | ||
| 380 | const char *cause = NULL; | ||
| 381 | |||
| 382 | memset(&hints, 0, sizeof(hints)); | ||
| 383 | hints.ai_family = PF_UNSPEC; | ||
| 384 | hints.ai_socktype = SOCK_STREAM; | ||
| 385 | hints.ai_flags = AI_PASSIVE; | ||
| 386 | error = getaddrinfo(NULL, "www", &hints, &res0); | ||
| 387 | if (error) | ||
| 388 | errx(1, "%s", gai_strerror(error)); | ||
| 389 | nsock = 0; | ||
| 390 | for (res = res0; res && nsock < MAXSOCK; res = res->ai_next) { | ||
| 391 | s[nsock] = socket(res->ai_family, res->ai_socktype, | ||
| 392 | res->ai_protocol); | ||
| 393 | if (s[nsock] == -1) { | ||
| 394 | cause = "socket"; | ||
| 395 | continue; | ||
| 396 | } | ||
| 397 | |||
| 398 | if (bind(s[nsock], res->ai_addr, res->ai_addrlen) == -1) { | ||
| 399 | cause = "bind"; | ||
| 400 | save_errno = errno; | ||
| 401 | close(s[nsock]); | ||
| 402 | errno = save_errno; | ||
| 403 | continue; | ||
| 404 | } | ||
| 405 | (void) listen(s[nsock], 5); | ||
| 406 | |||
| 407 | nsock++; | ||
| 408 | } | ||
| 409 | if (nsock == 0) | ||
| 410 | err(1, "%s", cause); | ||
| 411 | freeaddrinfo(res0); | ||
| 412 | .Ed | ||
| 413 | .Sh SEE ALSO | ||
| 414 | .Xr bind 2 , | ||
| 415 | .Xr connect 2 , | ||
| 416 | .Xr send 2 , | ||
| 417 | .Xr socket 2 , | ||
| 418 | .Xr gai_strerror 3 , | ||
| 419 | .Xr gethostbyname 3 , | ||
| 420 | .Xr getnameinfo 3 , | ||
| 421 | .Xr getservbyname 3 , | ||
| 422 | .Xr resolver 3 , | ||
| 423 | .Xr hosts 5 , | ||
| 424 | .Xr resolv.conf 5 , | ||
| 425 | .Xr services 5 , | ||
| 426 | .Xr hostname 7 , | ||
| 427 | .Xr named 8 | ||
| 428 | .Rs | ||
| 429 | .%A Craig Metz | ||
| 430 | .%B Proceedings of the Freenix Track: 2000 USENIX Annual Technical Conference | ||
| 431 | .%D June 2000 | ||
| 432 | .%T Protocol Independence Using the Sockets API | ||
| 433 | .Re | ||
| 434 | .Sh STANDARDS | ||
| 435 | The | ||
| 436 | .Fn getaddrinfo | ||
| 437 | function is defined by the | ||
| 438 | .St -p1003.1g-2000 | ||
| 439 | draft specification and documented in RFC 3493. | ||
| 440 | .Pp | ||
| 441 | The | ||
| 442 | .Dv AI_FQDN | ||
| 443 | flag bit first appeared in Windows 7. | ||
| 444 | .Pp | ||
| 445 | .Rs | ||
| 446 | .%A R. Gilligan | ||
| 447 | .%A S. Thomson | ||
| 448 | .%A J. Bound | ||
| 449 | .%A J. McCann | ||
| 450 | .%A W. Stevens | ||
| 451 | .%D February 2003 | ||
| 452 | .%R RFC 3493 | ||
| 453 | .%T Basic Socket Interface Extensions for IPv6 | ||
| 454 | .Re | ||
| 455 | .Pp | ||
| 456 | .Rs | ||
| 457 | .%A S. Deering | ||
| 458 | .%A B. Haberman | ||
| 459 | .%A T. Jinmei | ||
| 460 | .%A E. Nordmark | ||
| 461 | .%A B. Zill | ||
| 462 | .%D March 2005 | ||
| 463 | .%R RFC 4007 | ||
| 464 | .%T IPv6 Scoped Address Architecture | ||
| 465 | .Re | ||
diff --git a/src/lib/libc/net/gethostbyname.3 b/src/lib/libc/net/gethostbyname.3 index bac0368296..206750a2c3 100644 --- a/src/lib/libc/net/gethostbyname.3 +++ b/src/lib/libc/net/gethostbyname.3 | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | .\" $NetBSD: gethostbyname.3,v 1.6 1995/02/25 06:20:28 cgd Exp $ | 1 | .\" $OpenBSD: gethostbyname.3,v 1.26 2013/06/05 03:39:23 tedu Exp $ |
| 2 | .\" | 2 | .\" |
| 3 | .\" Copyright (c) 1983, 1987, 1991, 1993 | 3 | .\" Copyright (c) 1983, 1987, 1991, 1993 |
| 4 | .\" The Regents of the University of California. All rights reserved. | 4 | .\" The Regents of the University of California. All rights reserved. |
| @@ -11,11 +11,7 @@ | |||
| 11 | .\" 2. Redistributions in binary form must reproduce the above copyright | 11 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 12 | .\" notice, this list of conditions and the following disclaimer in the | 12 | .\" notice, this list of conditions and the following disclaimer in the |
| 13 | .\" documentation and/or other materials provided with the distribution. | 13 | .\" documentation and/or other materials provided with the distribution. |
| 14 | .\" 3. All advertising materials mentioning features or use of this software | 14 | .\" 3. Neither the name of the University nor the names of its contributors |
| 15 | .\" must display the following acknowledgement: | ||
| 16 | .\" This product includes software developed by the University of | ||
| 17 | .\" California, Berkeley and its contributors. | ||
| 18 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 19 | .\" may be used to endorse or promote products derived from this software | 15 | .\" may be used to endorse or promote products derived from this software |
| 20 | .\" without specific prior written permission. | 16 | .\" without specific prior written permission. |
| 21 | .\" | 17 | .\" |
| @@ -31,58 +27,66 @@ | |||
| 31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 27 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 32 | .\" SUCH DAMAGE. | 28 | .\" SUCH DAMAGE. |
| 33 | .\" | 29 | .\" |
| 34 | .\" @(#)gethostbyname.3 8.2 (Berkeley) 4/19/94 | 30 | .Dd $Mdocdate: June 5 2013 $ |
| 35 | .\" | ||
| 36 | .Dd April 19, 1994 | ||
| 37 | .Dt GETHOSTBYNAME 3 | 31 | .Dt GETHOSTBYNAME 3 |
| 38 | .Os BSD 4.2 | 32 | .Os |
| 39 | .Sh NAME | 33 | .Sh NAME |
| 40 | .Nm gethostbyname , | 34 | .Nm gethostbyname , |
| 35 | .Nm gethostbyname2 , | ||
| 41 | .Nm gethostbyaddr , | 36 | .Nm gethostbyaddr , |
| 42 | .Nm gethostent , | 37 | .Nm gethostent , |
| 43 | .Nm sethostent , | 38 | .Nm sethostent , |
| 44 | .Nm endhostent , | 39 | .Nm endhostent , |
| 40 | .Nm hstrerror , | ||
| 45 | .Nm herror | 41 | .Nm herror |
| 46 | .Nd get network host entry | 42 | .Nd get network host entry |
| 47 | .Sh SYNOPSIS | 43 | .Sh SYNOPSIS |
| 48 | .Fd #include <netdb.h> | 44 | .In netdb.h |
| 49 | .Fd extern int h_errno; | 45 | .Vt extern int h_errno ; |
| 50 | .Ft struct hostent * | 46 | .Ft struct hostent * |
| 51 | .Fn gethostbyname "const char *name" | 47 | .Fn gethostbyname "const char *name" |
| 52 | .Ft struct hostent * | 48 | .Ft struct hostent * |
| 53 | .Fn gethostbyaddr "const char *addr" "int len" "int type" | 49 | .Fn gethostbyname2 "const char *name" "int af" |
| 50 | .Ft struct hostent * | ||
| 51 | .Fn gethostbyaddr "const void *addr" "socklen_t len" "int af" | ||
| 54 | .Ft struct hostent * | 52 | .Ft struct hostent * |
| 55 | .Fn gethostent void | 53 | .Fn gethostent void |
| 54 | .Ft void | ||
| 56 | .Fn sethostent "int stayopen" | 55 | .Fn sethostent "int stayopen" |
| 56 | .Ft void | ||
| 57 | .Fn endhostent void | 57 | .Fn endhostent void |
| 58 | .Fn herror "char *string" | 58 | .Ft void |
| 59 | .Fn herror "const char *string" | ||
| 60 | .Ft const char * | ||
| 61 | .Fn hstrerror "int err" | ||
| 59 | .Sh DESCRIPTION | 62 | .Sh DESCRIPTION |
| 60 | The | 63 | The |
| 61 | .Fn gethostbyname | 64 | .Fn gethostbyname , |
| 65 | .Fn gethostbyname2 , | ||
| 62 | and | 66 | and |
| 63 | .Fn gethostbyaddr | 67 | .Fn gethostbyaddr |
| 64 | functions | 68 | functions each return a pointer to an object with the following structure |
| 65 | each return a pointer to an object with the | 69 | describing an Internet host referenced by name or by address, respectively. |
| 66 | following structure describing an internet host | 70 | This structure contains either information obtained from the name server (i.e., |
| 67 | referenced by name or by address, respectively. | 71 | .Xr resolver 3 |
| 68 | This structure contains either the information obtained from the name server, | 72 | and |
| 69 | .Xr named 8 , | 73 | .Xr named 8 ) , |
| 70 | broken-out fields from a line in | 74 | broken-out fields from a line in |
| 71 | .Pa /etc/hosts , | 75 | .Pa /etc/hosts , |
| 72 | or database entries supplied by the | 76 | or database entries supplied by the |
| 73 | .Xr yp 8 | 77 | .Xr yp 8 |
| 74 | system . | 78 | system. |
| 75 | If the local name server is not running these routines do a lookup in | 79 | .Xr resolv.conf 5 |
| 76 | .Pa /etc/hosts . | 80 | describes how the particular database is chosen. |
| 77 | .Bd -literal | 81 | .Bd -literal -offset indent |
| 78 | struct hostent { | 82 | struct hostent { |
| 79 | char *h_name; /* official name of host */ | 83 | char *h_name; /* official name of host */ |
| 80 | char **h_aliases; /* alias list */ | 84 | char **h_aliases; /* alias list */ |
| 81 | int h_addrtype; /* host address type */ | 85 | int h_addrtype; /* host address type */ |
| 82 | int h_length; /* length of address */ | 86 | int h_length; /* length of address */ |
| 83 | char **h_addr_list; /* list of addresses from name server */ | 87 | char **h_addr_list; /* list of returned addresses */ |
| 84 | }; | 88 | }; |
| 85 | #define h_addr h_addr_list[0] /* address, for backward compatibility */ | 89 | #define h_addr h_addr_list[0] /* address, for backward compat */ |
| 86 | .Ed | 90 | .Ed |
| 87 | .Pp | 91 | .Pp |
| 88 | The members of this structure are: | 92 | The members of this structure are: |
| @@ -90,36 +94,50 @@ The members of this structure are: | |||
| 90 | .It Fa h_name | 94 | .It Fa h_name |
| 91 | Official name of the host. | 95 | Official name of the host. |
| 92 | .It Fa h_aliases | 96 | .It Fa h_aliases |
| 93 | A zero terminated array of alternate names for the host. | 97 | A null-terminated array of alternate names for the host. |
| 94 | .It Fa h_addrtype | 98 | .It Fa h_addrtype |
| 95 | The type of address being returned; currently always | 99 | The type of address being returned. |
| 96 | .Dv AF_INET . | ||
| 97 | .It Fa h_length | 100 | .It Fa h_length |
| 98 | The length, in bytes, of the address. | 101 | The length, in bytes, of the address. |
| 99 | .It Fa h_addr_list | 102 | .It Fa h_addr_list |
| 100 | A zero terminated array of network addresses for the host. | 103 | A null-terminated array of network addresses for the host. |
| 101 | Host addresses are returned in network byte order. | 104 | Host addresses are returned in network byte order. |
| 102 | .It Fa h_addr | 105 | .It Fa h_addr |
| 103 | The first address in | 106 | The first address in |
| 104 | .Fa h_addr_list ; | 107 | .Fa h_addr_list ; |
| 105 | this is for backward compatibility. | 108 | this is for backward compatibility. |
| 109 | .El | ||
| 106 | .Pp | 110 | .Pp |
| 107 | When using the nameserver, | 111 | The function |
| 108 | .Fn gethostbyname | 112 | .Fn gethostbyname |
| 109 | will search for the named host in the current domain and its parents | 113 | will search for the named host in the current domain and its parents |
| 110 | unless the name ends in a dot. | 114 | using the search lookup semantics detailed in |
| 111 | If the name contains no dot, and if the environment variable | 115 | .Xr resolv.conf 5 |
| 112 | .Dq Ev HOSTALIASES | 116 | and |
| 113 | contains the name of an alias file, the alias file will first be searched | 117 | .Xr hostname 7 . |
| 114 | for an alias matching the input name. | 118 | .Pp |
| 115 | See | 119 | .Fn gethostbyname2 |
| 116 | .Xr hostname 7 | 120 | is an advanced form of |
| 117 | for the domain search procedure and the alias file format. | 121 | .Fn gethostbyname |
| 122 | which allows lookups in address families other than | ||
| 123 | .Dv AF_INET . | ||
| 124 | Currently, the only supported address family besides | ||
| 125 | .Dv AF_INET | ||
| 126 | is | ||
| 127 | .Dv AF_INET6 . | ||
| 128 | .Pp | ||
| 129 | The | ||
| 130 | .Fn gethostbyaddr | ||
| 131 | function will search for the specified address of length | ||
| 132 | .Fa len | ||
| 133 | in the address family | ||
| 134 | .Fa af . | ||
| 135 | The only address family currently supported is | ||
| 136 | .Dv AF_INET . | ||
| 118 | .Pp | 137 | .Pp |
| 119 | The | 138 | The |
| 120 | .Fn sethostent | 139 | .Fn sethostent |
| 121 | function | 140 | function may be used to request the use of a connected |
| 122 | may be used to request the use of a connected | ||
| 123 | .Tn TCP | 141 | .Tn TCP |
| 124 | socket for queries. | 142 | socket for queries. |
| 125 | If the | 143 | If the |
| @@ -127,7 +145,7 @@ If the | |||
| 127 | flag is non-zero, | 145 | flag is non-zero, |
| 128 | this sets the option to send all queries to the name server using | 146 | this sets the option to send all queries to the name server using |
| 129 | .Tn TCP | 147 | .Tn TCP |
| 130 | and to retain the connection after each call to | 148 | and to retain the connection after each call to |
| 131 | .Fn gethostbyname | 149 | .Fn gethostbyname |
| 132 | or | 150 | or |
| 133 | .Fn gethostbyaddr . | 151 | .Fn gethostbyaddr . |
| @@ -137,17 +155,46 @@ datagrams. | |||
| 137 | .Pp | 155 | .Pp |
| 138 | The | 156 | The |
| 139 | .Fn endhostent | 157 | .Fn endhostent |
| 140 | function | 158 | function closes the |
| 141 | closes the | ||
| 142 | .Tn TCP | 159 | .Tn TCP |
| 143 | connection. | 160 | connection. |
| 161 | .Pp | ||
| 162 | The | ||
| 163 | .Fn herror | ||
| 164 | function prints an error message describing the failure. | ||
| 165 | If its argument | ||
| 166 | .Fa string | ||
| 167 | is non-null, | ||
| 168 | it is prepended to the message string and separated from it by a colon | ||
| 169 | .Pq Ql \&: | ||
| 170 | and a space. | ||
| 171 | The error message is printed with a trailing newline. | ||
| 172 | The contents of the error message is the same as that returned by | ||
| 173 | .Fn hstrerror | ||
| 174 | with argument | ||
| 175 | .Fa h_errno . | ||
| 176 | .Sh ENVIRONMENT | ||
| 177 | .Bl -tag -width HOSTALIASES | ||
| 178 | .It HOSTALIASES | ||
| 179 | A file containing local host aliases. | ||
| 180 | See | ||
| 181 | .Xr hostname 7 | ||
| 182 | for more information. | ||
| 183 | .It RES_OPTIONS | ||
| 184 | A list of options to override the resolver's internal defaults. | ||
| 185 | See | ||
| 186 | .Xr resolver 3 | ||
| 187 | for more information. | ||
| 188 | .El | ||
| 144 | .Sh FILES | 189 | .Sh FILES |
| 145 | .Bl -tag -width /etc/hosts -compact | 190 | .Bl -tag -width /etc/resolv.conf -compact |
| 146 | .It Pa /etc/hosts | 191 | .It Pa /etc/hosts |
| 192 | .It Pa /etc/resolv.conf | ||
| 147 | .El | 193 | .El |
| 148 | .Sh DIAGNOSTICS | 194 | .Sh DIAGNOSTICS |
| 149 | Error return status from | 195 | Error return status from |
| 150 | .Fn gethostbyname | 196 | .Fn gethostbyname , |
| 197 | .Fn gethostbyname2 , | ||
| 151 | and | 198 | and |
| 152 | .Fn gethostbyaddr | 199 | .Fn gethostbyaddr |
| 153 | is indicated by return of a null pointer. | 200 | is indicated by return of a null pointer. |
| @@ -155,15 +202,6 @@ The external integer | |||
| 155 | .Va h_errno | 202 | .Va h_errno |
| 156 | may then be checked to see whether this is a temporary failure | 203 | may then be checked to see whether this is a temporary failure |
| 157 | or an invalid or unknown host. | 204 | or an invalid or unknown host. |
| 158 | The routine | ||
| 159 | .Fn herror | ||
| 160 | can be used to print an error message describing the failure. | ||
| 161 | If its argument | ||
| 162 | .Fa string | ||
| 163 | is | ||
| 164 | .Pf non Dv -NULL , | ||
| 165 | it is printed, followed by a colon and a space. | ||
| 166 | The error message is printed with a trailing newline. | ||
| 167 | .Pp | 205 | .Pp |
| 168 | The variable | 206 | The variable |
| 169 | .Va h_errno | 207 | .Va h_errno |
| @@ -180,75 +218,80 @@ A retry at some later time may succeed. | |||
| 180 | Some unexpected server failure was encountered. | 218 | Some unexpected server failure was encountered. |
| 181 | This is a non-recoverable error. | 219 | This is a non-recoverable error. |
| 182 | .It Dv NO_DATA | 220 | .It Dv NO_DATA |
| 183 | The requested name is valid but does not have an IP address; | 221 | The requested name is valid but does not have an IP address; |
| 184 | this is not a temporary error. | 222 | this is not a temporary error. |
| 185 | This means that the name is known to the name server but there is no address | 223 | This means that the name is known to the name server but there is no address |
| 186 | associated with this name. | 224 | associated with this name. |
| 187 | Another type of request to the name server using this domain name | 225 | Another type of request to the name server using this domain name |
| 188 | will result in an answer; | 226 | will result in an answer; |
| 189 | for example, a mail-forwarder may be registered for this domain. | 227 | for example, a mail-forwarder may be registered for this domain. |
| 228 | .It Dv NETDB_INTERNAL | ||
| 229 | An internal error occurred. | ||
| 230 | This may occur when an address family other than | ||
| 231 | .Dv AF_INET | ||
| 232 | or | ||
| 233 | .Dv AF_INET6 | ||
| 234 | is specified or when a resource is unable to be allocated. | ||
| 235 | .It Dv NETDB_SUCCESS | ||
| 236 | The function completed successfully. | ||
| 190 | .El | 237 | .El |
| 191 | .Sh SEE ALSO | 238 | .Sh SEE ALSO |
| 239 | .Xr getaddrinfo 3 , | ||
| 240 | .Xr getnameinfo 3 , | ||
| 192 | .Xr resolver 3 , | 241 | .Xr resolver 3 , |
| 193 | .Xr hosts 5 , | 242 | .Xr hosts 5 , |
| 243 | .Xr resolv.conf 5 , | ||
| 194 | .Xr hostname 7 , | 244 | .Xr hostname 7 , |
| 195 | .Xr named 8 | 245 | .Xr named 8 |
| 196 | .Sh CAVEAT | 246 | .Sh HISTORY |
| 197 | The | 247 | The |
| 198 | .Fn gethostent | 248 | .Fn herror |
| 199 | function | 249 | function appeared in |
| 200 | is defined, and | 250 | .Bx 4.3 . |
| 201 | .Fn sethostent | 251 | The |
| 252 | .Fn endhostent , | ||
| 253 | .Fn gethostbyaddr , | ||
| 254 | .Fn gethostbyname , | ||
| 255 | .Fn gethostent , | ||
| 202 | and | 256 | and |
| 203 | .Fn endhostent | 257 | .Fn sethostent |
| 204 | are redefined, | 258 | functions appeared in |
| 205 | when | 259 | .Bx 4.2 . |
| 206 | .Xr libc 3 | 260 | .Sh CAVEATS |
| 207 | is built to use only the routines to lookup in | 261 | If the search routines in |
| 262 | .Xr resolv.conf 5 | ||
| 263 | decide to read the | ||
| 208 | .Pa /etc/hosts | 264 | .Pa /etc/hosts |
| 209 | and not the name server. | 265 | file, |
| 210 | .Pp | ||
| 211 | The | ||
| 212 | .Fn gethostent | 266 | .Fn gethostent |
| 213 | function | 267 | and other functions will |
| 214 | reads the next line of | 268 | read the next line of the file, |
| 215 | .Pa /etc/hosts , | 269 | re-opening the file if necessary. |
| 216 | opening the file if necessary. | ||
| 217 | .Pp | 270 | .Pp |
| 218 | The | 271 | The |
| 219 | .Fn sethostent | 272 | .Fn sethostent |
| 220 | function | 273 | function opens and/or rewinds the file |
| 221 | opens and/or rewinds the file | ||
| 222 | .Pa /etc/hosts . | 274 | .Pa /etc/hosts . |
| 223 | If the | 275 | If the |
| 224 | .Fa stayopen | 276 | .Fa stayopen |
| 225 | argument is non-zero, | 277 | argument is non-zero, the file will not be closed after each call to |
| 226 | the file will not be closed after each call to | 278 | .Fn gethostbyname , |
| 227 | .Fn gethostbyname | 279 | .Fn gethostbyname2 , |
| 228 | or | 280 | or |
| 229 | .Fn gethostbyaddr . | 281 | .Fn gethostbyaddr . |
| 230 | .Pp | 282 | .Pp |
| 231 | The | 283 | The |
| 232 | .Fn endhostent | 284 | .Fn endhostent |
| 233 | function | 285 | function closes the file. |
| 234 | closes the file. | ||
| 235 | .Sh HISTORY | ||
| 236 | The | ||
| 237 | .Fn herror | ||
| 238 | function appeared in | ||
| 239 | .Bx 4.3 . | ||
| 240 | The | ||
| 241 | .Fn endhostent , | ||
| 242 | .Fn gethostbyaddr , | ||
| 243 | .Fn gethostbyname , | ||
| 244 | .Fn gethostent , | ||
| 245 | and | ||
| 246 | .Fn sethostent | ||
| 247 | functions appeared in | ||
| 248 | .Bx 4.2 . | ||
| 249 | .Sh BUGS | 286 | .Sh BUGS |
| 250 | These functions use static data storage; | 287 | These functions use static data storage; |
| 251 | if the data is needed for future use, it should be | 288 | if the data is needed for future use, it should be |
| 252 | copied before any subsequent calls overwrite it. | 289 | copied before any subsequent calls overwrite it. |
| 290 | .Pp | ||
| 253 | Only the Internet | 291 | Only the Internet |
| 254 | address format is currently understood. | 292 | address formats are currently understood. |
| 293 | .Pp | ||
| 294 | YP does not support any address families other than | ||
| 295 | .Dv AF_INET | ||
| 296 | and uses | ||
| 297 | the traditional database format. | ||
diff --git a/src/lib/libc/net/gethostnamadr.c b/src/lib/libc/net/gethostnamadr.c deleted file mode 100644 index ec3f14a900..0000000000 --- a/src/lib/libc/net/gethostnamadr.c +++ /dev/null | |||
| @@ -1,654 +0,0 @@ | |||
| 1 | /* $NetBSD: gethostnamadr.c,v 1.13 1995/05/21 16:21:14 mycroft Exp $ */ | ||
| 2 | |||
| 3 | /*- | ||
| 4 | * Copyright (c) 1985, 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 | * Portions Copyright (c) 1993 by Digital Equipment Corporation. | ||
| 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, and that | ||
| 40 | * the name of Digital Equipment Corporation not be used in advertising or | ||
| 41 | * publicity pertaining to distribution of the document or software without | ||
| 42 | * specific, written prior permission. | ||
| 43 | * | ||
| 44 | * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL | ||
| 45 | * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES | ||
| 46 | * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT | ||
| 47 | * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | ||
| 48 | * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR | ||
| 49 | * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS | ||
| 50 | * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | ||
| 51 | * SOFTWARE. | ||
| 52 | * - | ||
| 53 | * --Copyright-- | ||
| 54 | */ | ||
| 55 | |||
| 56 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 57 | #if 0 | ||
| 58 | static char sccsid[] = "@(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93"; | ||
| 59 | static char rcsid[] = "$Id: gethnamaddr.c,v 4.9.1.1 1993/05/02 22:43:03 vixie Rel "; | ||
| 60 | #else | ||
| 61 | static char rcsid[] = "$NetBSD: gethostnamadr.c,v 1.13 1995/05/21 16:21:14 mycroft Exp $"; | ||
| 62 | #endif | ||
| 63 | #endif /* LIBC_SCCS and not lint */ | ||
| 64 | |||
| 65 | #include <sys/param.h> | ||
| 66 | #include <sys/socket.h> | ||
| 67 | #include <netinet/in.h> | ||
| 68 | #include <arpa/inet.h> | ||
| 69 | #include <arpa/nameser.h> | ||
| 70 | #include <netdb.h> | ||
| 71 | #include <resolv.h> | ||
| 72 | #include <stdio.h> | ||
| 73 | #include <ctype.h> | ||
| 74 | #include <errno.h> | ||
| 75 | #include <string.h> | ||
| 76 | #ifdef YP | ||
| 77 | #include <rpc/rpc.h> | ||
| 78 | #include <rpcsvc/yp_prot.h> | ||
| 79 | #include <rpcsvc/ypclnt.h> | ||
| 80 | #endif | ||
| 81 | |||
| 82 | #define MAXALIASES 35 | ||
| 83 | #define MAXADDRS 35 | ||
| 84 | |||
| 85 | static char *h_addr_ptrs[MAXADDRS + 1]; | ||
| 86 | |||
| 87 | #ifdef YP | ||
| 88 | static char *__ypdomain; | ||
| 89 | #endif | ||
| 90 | |||
| 91 | static struct hostent host; | ||
| 92 | static char *host_aliases[MAXALIASES]; | ||
| 93 | static char hostbuf[BUFSIZ+1]; | ||
| 94 | static struct in_addr host_addr; | ||
| 95 | static FILE *hostf = NULL; | ||
| 96 | static int stayopen = 0; | ||
| 97 | |||
| 98 | #if PACKETSZ > 1024 | ||
| 99 | #define MAXPACKET PACKETSZ | ||
| 100 | #else | ||
| 101 | #define MAXPACKET 1024 | ||
| 102 | #endif | ||
| 103 | |||
| 104 | typedef union { | ||
| 105 | HEADER hdr; | ||
| 106 | u_char buf[MAXPACKET]; | ||
| 107 | } querybuf; | ||
| 108 | |||
| 109 | typedef union { | ||
| 110 | int32_t al; | ||
| 111 | char ac; | ||
| 112 | } align; | ||
| 113 | |||
| 114 | static int qcomp __P((struct in_addr **, struct in_addr **)); | ||
| 115 | static struct hostent *getanswer __P((querybuf *, int, int)); | ||
| 116 | |||
| 117 | extern int h_errno; | ||
| 118 | |||
| 119 | static struct hostent * | ||
| 120 | getanswer(answer, anslen, iquery) | ||
| 121 | querybuf *answer; | ||
| 122 | int anslen; | ||
| 123 | int iquery; | ||
| 124 | { | ||
| 125 | register HEADER *hp; | ||
| 126 | register u_char *cp; | ||
| 127 | register int n; | ||
| 128 | u_char *eom; | ||
| 129 | char *bp, **ap; | ||
| 130 | int type, class, buflen, ancount, qdcount; | ||
| 131 | int haveanswer, getclass = C_ANY; | ||
| 132 | char **hap; | ||
| 133 | |||
| 134 | eom = answer->buf + anslen; | ||
| 135 | /* | ||
| 136 | * find first satisfactory answer | ||
| 137 | */ | ||
| 138 | hp = &answer->hdr; | ||
| 139 | ancount = ntohs(hp->ancount); | ||
| 140 | qdcount = ntohs(hp->qdcount); | ||
| 141 | bp = hostbuf; | ||
| 142 | buflen = sizeof(hostbuf); | ||
| 143 | cp = answer->buf + sizeof(HEADER); | ||
| 144 | if (qdcount) { | ||
| 145 | if (iquery) { | ||
| 146 | if ((n = dn_expand((u_char *)answer->buf, | ||
| 147 | (u_char *)eom, (u_char *)cp, (u_char *)bp, | ||
| 148 | buflen)) < 0) { | ||
| 149 | h_errno = NO_RECOVERY; | ||
| 150 | return ((struct hostent *) NULL); | ||
| 151 | } | ||
| 152 | cp += n + QFIXEDSZ; | ||
| 153 | host.h_name = bp; | ||
| 154 | n = strlen(bp) + 1; | ||
| 155 | bp += n; | ||
| 156 | buflen -= n; | ||
| 157 | } else | ||
| 158 | cp += __dn_skipname(cp, eom) + QFIXEDSZ; | ||
| 159 | while (--qdcount > 0) | ||
| 160 | cp += __dn_skipname(cp, eom) + QFIXEDSZ; | ||
| 161 | } else if (iquery) { | ||
| 162 | if (hp->aa) | ||
| 163 | h_errno = HOST_NOT_FOUND; | ||
| 164 | else | ||
| 165 | h_errno = TRY_AGAIN; | ||
| 166 | return ((struct hostent *) NULL); | ||
| 167 | } | ||
| 168 | ap = host_aliases; | ||
| 169 | *ap = NULL; | ||
| 170 | host.h_aliases = host_aliases; | ||
| 171 | hap = h_addr_ptrs; | ||
| 172 | *hap = NULL; | ||
| 173 | host.h_addr_list = h_addr_ptrs; | ||
| 174 | haveanswer = 0; | ||
| 175 | while (--ancount >= 0 && cp < eom) { | ||
| 176 | if ((n = dn_expand((u_char *)answer->buf, (u_char *)eom, | ||
| 177 | (u_char *)cp, (u_char *)bp, buflen)) < 0) | ||
| 178 | break; | ||
| 179 | cp += n; | ||
| 180 | type = _getshort(cp); | ||
| 181 | cp += sizeof(u_int16_t); | ||
| 182 | class = _getshort(cp); | ||
| 183 | cp += sizeof(u_int16_t) + sizeof(u_int32_t); | ||
| 184 | n = _getshort(cp); | ||
| 185 | cp += sizeof(u_int16_t); | ||
| 186 | if (type == T_CNAME) { | ||
| 187 | cp += n; | ||
| 188 | if (ap >= &host_aliases[MAXALIASES-1]) | ||
| 189 | continue; | ||
| 190 | *ap++ = bp; | ||
| 191 | n = strlen(bp) + 1; | ||
| 192 | bp += n; | ||
| 193 | buflen -= n; | ||
| 194 | continue; | ||
| 195 | } | ||
| 196 | if (iquery && type == T_PTR) { | ||
| 197 | if ((n = dn_expand((u_char *)answer->buf, | ||
| 198 | (u_char *)eom, (u_char *)cp, (u_char *)bp, | ||
| 199 | buflen)) < 0) | ||
| 200 | break; | ||
| 201 | cp += n; | ||
| 202 | host.h_name = bp; | ||
| 203 | return(&host); | ||
| 204 | } | ||
| 205 | if (iquery || type != T_A) { | ||
| 206 | #ifdef DEBUG | ||
| 207 | if (_res.options & RES_DEBUG) | ||
| 208 | printf("unexpected answer type %d, size %d\n", | ||
| 209 | type, n); | ||
| 210 | #endif | ||
| 211 | cp += n; | ||
| 212 | continue; | ||
| 213 | } | ||
| 214 | if (haveanswer) { | ||
| 215 | if (n != host.h_length) { | ||
| 216 | cp += n; | ||
| 217 | continue; | ||
| 218 | } | ||
| 219 | if (class != getclass) { | ||
| 220 | cp += n; | ||
| 221 | continue; | ||
| 222 | } | ||
| 223 | } else { | ||
| 224 | host.h_length = n; | ||
| 225 | getclass = class; | ||
| 226 | host.h_addrtype = (class == C_IN) ? AF_INET : AF_UNSPEC; | ||
| 227 | if (!iquery) { | ||
| 228 | host.h_name = bp; | ||
| 229 | bp += strlen(bp) + 1; | ||
| 230 | } | ||
| 231 | } | ||
| 232 | |||
| 233 | bp += sizeof(align) - ((u_long)bp % sizeof(align)); | ||
| 234 | |||
| 235 | if (bp + n >= &hostbuf[sizeof(hostbuf)]) { | ||
| 236 | #ifdef DEBUG | ||
| 237 | if (_res.options & RES_DEBUG) | ||
| 238 | printf("size (%d) too big\n", n); | ||
| 239 | #endif | ||
| 240 | break; | ||
| 241 | } | ||
| 242 | bcopy(cp, *hap++ = bp, n); | ||
| 243 | bp +=n; | ||
| 244 | cp += n; | ||
| 245 | haveanswer++; | ||
| 246 | } | ||
| 247 | if (haveanswer) { | ||
| 248 | *ap = NULL; | ||
| 249 | *hap = NULL; | ||
| 250 | if (_res.nsort) { | ||
| 251 | qsort(host.h_addr_list, haveanswer, | ||
| 252 | sizeof(struct in_addr), | ||
| 253 | (int (*)__P((const void *, const void *)))qcomp); | ||
| 254 | } | ||
| 255 | return (&host); | ||
| 256 | } else { | ||
| 257 | h_errno = TRY_AGAIN; | ||
| 258 | return ((struct hostent *) NULL); | ||
| 259 | } | ||
| 260 | } | ||
| 261 | |||
| 262 | struct hostent * | ||
| 263 | gethostbyname(name) | ||
| 264 | const char *name; | ||
| 265 | { | ||
| 266 | querybuf buf; | ||
| 267 | register const char *cp; | ||
| 268 | int n, i; | ||
| 269 | extern struct hostent *_gethtbyname(), *_yp_gethtbyname(); | ||
| 270 | register struct hostent *hp; | ||
| 271 | char lookups[MAXDNSLUS]; | ||
| 272 | |||
| 273 | /* | ||
| 274 | * disallow names consisting only of digits/dots, unless | ||
| 275 | * they end in a dot. | ||
| 276 | */ | ||
| 277 | if (isdigit(name[0])) | ||
| 278 | for (cp = name;; ++cp) { | ||
| 279 | if (!*cp) { | ||
| 280 | if (*--cp == '.') | ||
| 281 | break; | ||
| 282 | /* | ||
| 283 | * All-numeric, no dot at the end. | ||
| 284 | * Fake up a hostent as if we'd actually | ||
| 285 | * done a lookup. | ||
| 286 | */ | ||
| 287 | if (!inet_aton(name, &host_addr)) { | ||
| 288 | h_errno = HOST_NOT_FOUND; | ||
| 289 | return((struct hostent *) NULL); | ||
| 290 | } | ||
| 291 | host.h_name = (char *)name; | ||
| 292 | host.h_aliases = host_aliases; | ||
| 293 | host_aliases[0] = NULL; | ||
| 294 | host.h_addrtype = AF_INET; | ||
| 295 | host.h_length = sizeof(u_int32_t); | ||
| 296 | h_addr_ptrs[0] = (char *)&host_addr; | ||
| 297 | h_addr_ptrs[1] = NULL; | ||
| 298 | host.h_addr_list = h_addr_ptrs; | ||
| 299 | return (&host); | ||
| 300 | } | ||
| 301 | if (!isdigit(*cp) && *cp != '.') | ||
| 302 | break; | ||
| 303 | } | ||
| 304 | |||
| 305 | if ((_res.options & RES_INIT) == 0 && res_init() == -1) | ||
| 306 | return (_gethtbyname(name)); | ||
| 307 | |||
| 308 | bcopy(_res.lookups, lookups, sizeof lookups); | ||
| 309 | if (lookups[0] == '\0') | ||
| 310 | strncpy(lookups, "bf", sizeof lookups); | ||
| 311 | |||
| 312 | hp = (struct hostent *)NULL; | ||
| 313 | for (i = 0; i < MAXDNSLUS && hp == NULL && lookups[i]; i++) { | ||
| 314 | switch (lookups[i]) { | ||
| 315 | #ifdef YP | ||
| 316 | case 'y': | ||
| 317 | hp = _yp_gethtbyname(name); | ||
| 318 | break; | ||
| 319 | #endif | ||
| 320 | case 'b': | ||
| 321 | if ((n = res_search(name, C_IN, T_A, buf.buf, | ||
| 322 | sizeof(buf))) < 0) { | ||
| 323 | #ifdef DEBUG | ||
| 324 | if (_res.options & RES_DEBUG) | ||
| 325 | printf("res_search failed\n"); | ||
| 326 | #endif | ||
| 327 | break; | ||
| 328 | } | ||
| 329 | hp = getanswer(&buf, n, 0); | ||
| 330 | break; | ||
| 331 | case 'f': | ||
| 332 | hp = _gethtbyname(name); | ||
| 333 | break; | ||
| 334 | } | ||
| 335 | } | ||
| 336 | return (hp); | ||
| 337 | } | ||
| 338 | |||
| 339 | struct hostent * | ||
| 340 | gethostbyaddr(addr, len, type) | ||
| 341 | const char *addr; | ||
| 342 | int len, type; | ||
| 343 | { | ||
| 344 | int n, i; | ||
| 345 | querybuf buf; | ||
| 346 | register struct hostent *hp; | ||
| 347 | char qbuf[MAXDNAME]; | ||
| 348 | extern struct hostent *_gethtbyaddr(), *_yp_gethtbyaddr(); | ||
| 349 | char lookups[MAXDNSLUS]; | ||
| 350 | |||
| 351 | if (type != AF_INET) | ||
| 352 | return ((struct hostent *) NULL); | ||
| 353 | (void)sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa", | ||
| 354 | ((unsigned)addr[3] & 0xff), | ||
| 355 | ((unsigned)addr[2] & 0xff), | ||
| 356 | ((unsigned)addr[1] & 0xff), | ||
| 357 | ((unsigned)addr[0] & 0xff)); | ||
| 358 | |||
| 359 | if ((_res.options & RES_INIT) == 0 && res_init() == -1) | ||
| 360 | return (_gethtbyaddr(addr, len, type)); | ||
| 361 | |||
| 362 | bcopy(_res.lookups, lookups, sizeof lookups); | ||
| 363 | if (lookups[0] == '\0') | ||
| 364 | strncpy(lookups, "bf", sizeof lookups); | ||
| 365 | |||
| 366 | hp = (struct hostent *)NULL; | ||
| 367 | for (i = 0; i < MAXDNSLUS && hp == NULL && lookups[i]; i++) { | ||
| 368 | switch (lookups[i]) { | ||
| 369 | #ifdef YP | ||
| 370 | case 'y': | ||
| 371 | hp = _yp_gethtbyaddr(addr, len, type); | ||
| 372 | break; | ||
| 373 | #endif | ||
| 374 | case 'b': | ||
| 375 | n = res_query(qbuf, C_IN, T_PTR, (char *)&buf, sizeof(buf)); | ||
| 376 | if (n < 0) { | ||
| 377 | #ifdef DEBUG | ||
| 378 | if (_res.options & RES_DEBUG) | ||
| 379 | printf("res_query failed\n"); | ||
| 380 | #endif | ||
| 381 | break; | ||
| 382 | } | ||
| 383 | hp = getanswer(&buf, n, 1); | ||
| 384 | if (hp == NULL) | ||
| 385 | break; | ||
| 386 | hp->h_addrtype = type; | ||
| 387 | hp->h_length = len; | ||
| 388 | h_addr_ptrs[0] = (char *)&host_addr; | ||
| 389 | h_addr_ptrs[1] = (char *)0; | ||
| 390 | host_addr = *(struct in_addr *)addr; | ||
| 391 | break; | ||
| 392 | case 'f': | ||
| 393 | hp = _gethtbyaddr(addr, len, type); | ||
| 394 | break; | ||
| 395 | } | ||
| 396 | } | ||
| 397 | return (hp); | ||
| 398 | } | ||
| 399 | |||
| 400 | void | ||
| 401 | _sethtent(f) | ||
| 402 | int f; | ||
| 403 | { | ||
| 404 | if (hostf == NULL) | ||
| 405 | hostf = fopen(_PATH_HOSTS, "r" ); | ||
| 406 | else | ||
| 407 | rewind(hostf); | ||
| 408 | stayopen = f; | ||
| 409 | } | ||
| 410 | |||
| 411 | void | ||
| 412 | _endhtent() | ||
| 413 | { | ||
| 414 | if (hostf && !stayopen) { | ||
| 415 | (void) fclose(hostf); | ||
| 416 | hostf = NULL; | ||
| 417 | } | ||
| 418 | } | ||
| 419 | |||
| 420 | struct hostent * | ||
| 421 | _gethtent() | ||
| 422 | { | ||
| 423 | char *p; | ||
| 424 | register char *cp, **q; | ||
| 425 | |||
| 426 | if (hostf == NULL && (hostf = fopen(_PATH_HOSTS, "r" )) == NULL) | ||
| 427 | return (NULL); | ||
| 428 | again: | ||
| 429 | if ((p = fgets(hostbuf, BUFSIZ, hostf)) == NULL) | ||
| 430 | return (NULL); | ||
| 431 | if (*p == '#') | ||
| 432 | goto again; | ||
| 433 | cp = strpbrk(p, "#\n"); | ||
| 434 | if (cp == NULL) | ||
| 435 | goto again; | ||
| 436 | *cp = '\0'; | ||
| 437 | cp = strpbrk(p, " \t"); | ||
| 438 | if (cp == NULL) | ||
| 439 | goto again; | ||
| 440 | *cp++ = '\0'; | ||
| 441 | /* THIS STUFF IS INTERNET SPECIFIC */ | ||
| 442 | h_addr_ptrs[0] = (char *)&host_addr; | ||
| 443 | h_addr_ptrs[1] = NULL; | ||
| 444 | (void) inet_aton(p, &host_addr); | ||
| 445 | host.h_addr_list = h_addr_ptrs; | ||
| 446 | host.h_length = sizeof(u_int32_t); | ||
| 447 | host.h_addrtype = AF_INET; | ||
| 448 | while (*cp == ' ' || *cp == '\t') | ||
| 449 | cp++; | ||
| 450 | host.h_name = cp; | ||
| 451 | q = host.h_aliases = host_aliases; | ||
| 452 | cp = strpbrk(cp, " \t"); | ||
| 453 | if (cp != NULL) | ||
| 454 | *cp++ = '\0'; | ||
| 455 | while (cp && *cp) { | ||
| 456 | if (*cp == ' ' || *cp == '\t') { | ||
| 457 | cp++; | ||
| 458 | continue; | ||
| 459 | } | ||
| 460 | if (q < &host_aliases[MAXALIASES - 1]) | ||
| 461 | *q++ = cp; | ||
| 462 | cp = strpbrk(cp, " \t"); | ||
| 463 | if (cp != NULL) | ||
| 464 | *cp++ = '\0'; | ||
| 465 | } | ||
| 466 | *q = NULL; | ||
| 467 | return (&host); | ||
| 468 | } | ||
| 469 | |||
| 470 | struct hostent * | ||
| 471 | _gethtbyname(name) | ||
| 472 | char *name; | ||
| 473 | { | ||
| 474 | register struct hostent *p; | ||
| 475 | register char **cp; | ||
| 476 | |||
| 477 | _sethtent(0); | ||
| 478 | while (p = _gethtent()) { | ||
| 479 | if (strcasecmp(p->h_name, name) == 0) | ||
| 480 | break; | ||
| 481 | for (cp = p->h_aliases; *cp != 0; cp++) | ||
| 482 | if (strcasecmp(*cp, name) == 0) | ||
| 483 | goto found; | ||
| 484 | } | ||
| 485 | found: | ||
| 486 | _endhtent(); | ||
| 487 | if (p==NULL) | ||
| 488 | h_errno = HOST_NOT_FOUND; | ||
| 489 | return (p); | ||
| 490 | } | ||
| 491 | |||
| 492 | struct hostent * | ||
| 493 | _gethtbyaddr(addr, len, type) | ||
| 494 | const char *addr; | ||
| 495 | int len, type; | ||
| 496 | { | ||
| 497 | register struct hostent *p; | ||
| 498 | |||
| 499 | _sethtent(0); | ||
| 500 | while (p = _gethtent()) | ||
| 501 | if (p->h_addrtype == type && !bcmp(p->h_addr, addr, len)) | ||
| 502 | break; | ||
| 503 | _endhtent(); | ||
| 504 | if (p==NULL) | ||
| 505 | h_errno = HOST_NOT_FOUND; | ||
| 506 | return (p); | ||
| 507 | } | ||
| 508 | |||
| 509 | static int | ||
| 510 | qcomp(a1, a2) | ||
| 511 | struct in_addr **a1, **a2; | ||
| 512 | { | ||
| 513 | int pos1, pos2; | ||
| 514 | |||
| 515 | for (pos1 = 0; pos1 < _res.nsort; pos1++) | ||
| 516 | if (_res.sort_list[pos1].addr.s_addr == | ||
| 517 | ((*a1)->s_addr & _res.sort_list[pos1].mask)) | ||
| 518 | break; | ||
| 519 | for (pos2 = 0; pos2 < _res.nsort; pos2++) | ||
| 520 | if (_res.sort_list[pos2].addr.s_addr == | ||
| 521 | ((*a2)->s_addr & _res.sort_list[pos2].mask)) | ||
| 522 | break; | ||
| 523 | return pos1 - pos2; | ||
| 524 | } | ||
| 525 | |||
| 526 | #ifdef YP | ||
| 527 | struct hostent * | ||
| 528 | _yphostent(line) | ||
| 529 | char *line; | ||
| 530 | { | ||
| 531 | static struct in_addr host_addrs[MAXADDRS]; | ||
| 532 | char *p = line; | ||
| 533 | char *cp, **q; | ||
| 534 | char **hap; | ||
| 535 | struct in_addr *buf; | ||
| 536 | int more; | ||
| 537 | |||
| 538 | host.h_name = NULL; | ||
| 539 | host.h_addr_list = h_addr_ptrs; | ||
| 540 | host.h_length = sizeof(u_int32_t); | ||
| 541 | host.h_addrtype = AF_INET; | ||
| 542 | hap = h_addr_ptrs; | ||
| 543 | buf = host_addrs; | ||
| 544 | q = host.h_aliases = host_aliases; | ||
| 545 | |||
| 546 | nextline: | ||
| 547 | more = 0; | ||
| 548 | cp = strpbrk(p, " \t"); | ||
| 549 | if (cp == NULL) { | ||
| 550 | if (host.h_name == NULL) | ||
| 551 | return (NULL); | ||
| 552 | else | ||
| 553 | goto done; | ||
| 554 | } | ||
| 555 | *cp++ = '\0'; | ||
| 556 | |||
| 557 | *hap++ = (char *)buf; | ||
| 558 | (void) inet_aton(p, buf++); | ||
| 559 | |||
| 560 | while (*cp == ' ' || *cp == '\t') | ||
| 561 | cp++; | ||
| 562 | p = cp; | ||
| 563 | cp = strpbrk(p, " \t\n"); | ||
| 564 | if (cp != NULL) { | ||
| 565 | if (*cp == '\n') | ||
| 566 | more = 1; | ||
| 567 | *cp++ = '\0'; | ||
| 568 | } | ||
| 569 | if (!host.h_name) | ||
| 570 | host.h_name = p; | ||
| 571 | else if (strcmp(host.h_name, p)==0) | ||
| 572 | ; | ||
| 573 | else if (q < &host_aliases[MAXALIASES - 1]) | ||
| 574 | *q++ = p; | ||
| 575 | p = cp; | ||
| 576 | if (more) | ||
| 577 | goto nextline; | ||
| 578 | |||
| 579 | while (cp && *cp) { | ||
| 580 | if (*cp == ' ' || *cp == '\t') { | ||
| 581 | cp++; | ||
| 582 | continue; | ||
| 583 | } | ||
| 584 | if (*cp == '\n') { | ||
| 585 | cp++; | ||
| 586 | goto nextline; | ||
| 587 | } | ||
| 588 | if (q < &host_aliases[MAXALIASES - 1]) | ||
| 589 | *q++ = cp; | ||
| 590 | cp = strpbrk(cp, " \t"); | ||
| 591 | if (cp != NULL) | ||
| 592 | *cp++ = '\0'; | ||
| 593 | } | ||
| 594 | done: | ||
| 595 | *q = NULL; | ||
| 596 | *hap = NULL; | ||
| 597 | return (&host); | ||
| 598 | } | ||
| 599 | |||
| 600 | struct hostent * | ||
| 601 | _yp_gethtbyaddr(addr, len, type) | ||
| 602 | const char *addr; | ||
| 603 | int len, type; | ||
| 604 | { | ||
| 605 | struct hostent *hp = (struct hostent *)NULL; | ||
| 606 | static char *__ypcurrent; | ||
| 607 | int __ypcurrentlen, r; | ||
| 608 | char name[sizeof("xxx.xxx.xxx.xxx") + 1]; | ||
| 609 | |||
| 610 | if (!__ypdomain) { | ||
| 611 | if (_yp_check(&__ypdomain) == 0) | ||
| 612 | return (hp); | ||
| 613 | } | ||
| 614 | sprintf(name, "%u.%u.%u.%u", | ||
| 615 | ((unsigned)addr[0] & 0xff), | ||
| 616 | ((unsigned)addr[1] & 0xff), | ||
| 617 | ((unsigned)addr[2] & 0xff), | ||
| 618 | ((unsigned)addr[3] & 0xff)); | ||
| 619 | if (__ypcurrent) | ||
| 620 | free(__ypcurrent); | ||
| 621 | __ypcurrent = NULL; | ||
| 622 | r = yp_match(__ypdomain, "hosts.byaddr", name, | ||
| 623 | strlen(name), &__ypcurrent, &__ypcurrentlen); | ||
| 624 | if (r==0) | ||
| 625 | hp = _yphostent(__ypcurrent); | ||
| 626 | if (hp==NULL) | ||
| 627 | h_errno = HOST_NOT_FOUND; | ||
| 628 | return (hp); | ||
| 629 | } | ||
| 630 | |||
| 631 | struct hostent * | ||
| 632 | _yp_gethtbyname(name) | ||
| 633 | const char *name; | ||
| 634 | { | ||
| 635 | struct hostent *hp = (struct hostent *)NULL; | ||
| 636 | static char *__ypcurrent; | ||
| 637 | int __ypcurrentlen, r; | ||
| 638 | |||
| 639 | if (!__ypdomain) { | ||
| 640 | if (_yp_check(&__ypdomain) == 0) | ||
| 641 | return (hp); | ||
| 642 | } | ||
| 643 | if (__ypcurrent) | ||
| 644 | free(__ypcurrent); | ||
| 645 | __ypcurrent = NULL; | ||
| 646 | r = yp_match(__ypdomain, "hosts.byname", name, | ||
| 647 | strlen(name), &__ypcurrent, &__ypcurrentlen); | ||
| 648 | if (r==0) | ||
| 649 | hp = _yphostent(__ypcurrent); | ||
| 650 | if (hp==NULL) | ||
| 651 | h_errno = HOST_NOT_FOUND; | ||
| 652 | return (hp); | ||
| 653 | } | ||
| 654 | #endif | ||
diff --git a/src/lib/libc/net/getifaddrs.3 b/src/lib/libc/net/getifaddrs.3 new file mode 100644 index 0000000000..0b3538302a --- /dev/null +++ b/src/lib/libc/net/getifaddrs.3 | |||
| @@ -0,0 +1,160 @@ | |||
| 1 | .\" $OpenBSD: getifaddrs.3,v 1.19 2014/04/07 17:57:56 schwarze Exp $ | ||
| 2 | .\" BSDI getifaddrs.3,v 2.5 2000/02/23 14:51:59 dab Exp | ||
| 3 | .\" | ||
| 4 | .\" Copyright (c) 1995, 1999 | ||
| 5 | .\" Berkeley Software Design, Inc. All rights reserved. | ||
| 6 | .\" | ||
| 7 | .\" Redistribution and use in source and binary forms, with or without | ||
| 8 | .\" modification, are permitted provided that the following conditions | ||
| 9 | .\" are met: | ||
| 10 | .\" 1. Redistributions of source code must retain the above copyright | ||
| 11 | .\" notice, this list of conditions and the following disclaimer. | ||
| 12 | .\" | ||
| 13 | .\" THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND | ||
| 14 | .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 15 | .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 16 | .\" ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE | ||
| 17 | .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 18 | .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 19 | .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 20 | .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 21 | .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 22 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 23 | .\" SUCH DAMAGE. | ||
| 24 | .Dd $Mdocdate: April 7 2014 $ | ||
| 25 | .Dt GETIFADDRS 3 | ||
| 26 | .Os | ||
| 27 | .Sh NAME | ||
| 28 | .Nm getifaddrs , | ||
| 29 | .Nm freeifaddrs | ||
| 30 | .Nd get interface addresses | ||
| 31 | .Sh SYNOPSIS | ||
| 32 | .In sys/types.h | ||
| 33 | .In sys/socket.h | ||
| 34 | .In ifaddrs.h | ||
| 35 | .Ft int | ||
| 36 | .Fn getifaddrs "struct ifaddrs **ifap" | ||
| 37 | .Ft void | ||
| 38 | .Fn freeifaddrs "struct ifaddrs *ifap" | ||
| 39 | .Sh DESCRIPTION | ||
| 40 | The | ||
| 41 | .Fn getifaddrs | ||
| 42 | function stores a reference to a linked list of the network interfaces | ||
| 43 | on the local machine in the memory referenced by | ||
| 44 | .Fa ifap . | ||
| 45 | The list consists of | ||
| 46 | .Nm ifaddrs | ||
| 47 | structures, as defined in the include file | ||
| 48 | .In ifaddrs.h . | ||
| 49 | The | ||
| 50 | .Nm ifaddrs | ||
| 51 | structure contains at least the following entries: | ||
| 52 | .Bd -literal | ||
| 53 | struct ifaddrs *ifa_next; /* Pointer to next struct */ | ||
| 54 | char *ifa_name; /* Interface name */ | ||
| 55 | u_int ifa_flags; /* Interface flags */ | ||
| 56 | struct sockaddr *ifa_addr; /* Interface address */ | ||
| 57 | struct sockaddr *ifa_netmask; /* Interface netmask */ | ||
| 58 | struct sockaddr *ifa_broadaddr; /* Interface broadcast address */ | ||
| 59 | struct sockaddr *ifa_dstaddr; /* P2P interface destination */ | ||
| 60 | void *ifa_data; /* Address specific data */ | ||
| 61 | .Ed | ||
| 62 | .Bl -tag -width ifa_broadaddr | ||
| 63 | .It Fa ifa_next | ||
| 64 | Contains a pointer to the next structure on the list. | ||
| 65 | This field is set to | ||
| 66 | .Dv NULL | ||
| 67 | in the last structure on the list. | ||
| 68 | .It Fa ifa_name | ||
| 69 | Contains the interface name. | ||
| 70 | .It Fa ifa_flags | ||
| 71 | Contains the interface flags, as set by | ||
| 72 | .Xr ifconfig 8 . | ||
| 73 | .It Fa ifa_addr | ||
| 74 | References either the address of the interface or the link level | ||
| 75 | address of the interface, if one exists, otherwise it is | ||
| 76 | .Dv NULL . | ||
| 77 | (The | ||
| 78 | .Fa sa_family | ||
| 79 | field of the | ||
| 80 | .Fa ifa_addr | ||
| 81 | field should be consulted to determine the format of the | ||
| 82 | .Fa ifa_addr | ||
| 83 | address.) | ||
| 84 | .It Fa ifa_netmask | ||
| 85 | References the netmask associated with | ||
| 86 | .Fa ifa_addr , | ||
| 87 | if one is set, otherwise it is | ||
| 88 | .Dv NULL . | ||
| 89 | .It Fa ifa_broadaddr | ||
| 90 | This field, which should only be referenced for non-P2P interfaces, | ||
| 91 | references the broadcast address associated with | ||
| 92 | .Fa ifa_addr , | ||
| 93 | if one exists, otherwise it is | ||
| 94 | .Dv NULL . | ||
| 95 | .It Fa ifa_dstaddr | ||
| 96 | This field, which should only be referenced for P2P interfaces, | ||
| 97 | references the destination address on a P2P interface, | ||
| 98 | if one exists, otherwise it is | ||
| 99 | .Dv NULL . | ||
| 100 | .It Fa ifa_data | ||
| 101 | References address family specific data. | ||
| 102 | For | ||
| 103 | .Dv AF_LINK | ||
| 104 | addresses it contains a pointer to the | ||
| 105 | .Li struct if_data | ||
| 106 | (as defined in include file | ||
| 107 | .In net/if.h ) | ||
| 108 | which contains various interface attributes and statistics. | ||
| 109 | For all other address families, | ||
| 110 | .Fa ifa_data | ||
| 111 | is | ||
| 112 | .Dv NULL . | ||
| 113 | .El | ||
| 114 | .Pp | ||
| 115 | The data returned by | ||
| 116 | .Fn getifaddrs | ||
| 117 | is dynamically allocated and should be freed using | ||
| 118 | .Fn freeifaddrs | ||
| 119 | when no longer needed. | ||
| 120 | .Sh RETURN VALUES | ||
| 121 | Upon successful completion, a value of 0 is returned. | ||
| 122 | Otherwise, a value of \-1 is returned and | ||
| 123 | .Va errno | ||
| 124 | is set to indicate the error. | ||
| 125 | .Sh ERRORS | ||
| 126 | The | ||
| 127 | .Fn getifaddrs | ||
| 128 | may fail and set | ||
| 129 | .Va errno | ||
| 130 | for any of the errors specified for the library routines | ||
| 131 | .Xr ioctl 2 , | ||
| 132 | .Xr socket 2 , | ||
| 133 | .Xr malloc 3 , | ||
| 134 | or | ||
| 135 | .Xr sysctl 3 . | ||
| 136 | .Sh SEE ALSO | ||
| 137 | .Xr ioctl 2 , | ||
| 138 | .Xr socket 2 , | ||
| 139 | .Xr sysctl 3 , | ||
| 140 | .Xr networking 4 , | ||
| 141 | .Xr ifconfig 8 | ||
| 142 | .Sh HISTORY | ||
| 143 | The | ||
| 144 | .Fn getifaddrs | ||
| 145 | function first appeared in BSDI | ||
| 146 | .Bsx . | ||
| 147 | The function has been available on | ||
| 148 | .Ox | ||
| 149 | since | ||
| 150 | .Ox 2.7 . | ||
| 151 | .Sh BUGS | ||
| 152 | If both | ||
| 153 | .In net/if.h | ||
| 154 | and | ||
| 155 | .In ifaddrs.h | ||
| 156 | are being included, | ||
| 157 | .In net/if.h | ||
| 158 | .Em must | ||
| 159 | be included before | ||
| 160 | .In ifaddrs.h . | ||
diff --git a/src/lib/libc/net/getifaddrs.c b/src/lib/libc/net/getifaddrs.c new file mode 100644 index 0000000000..da42a23783 --- /dev/null +++ b/src/lib/libc/net/getifaddrs.c | |||
| @@ -0,0 +1,296 @@ | |||
| 1 | /* $OpenBSD: getifaddrs.c,v 1.11 2013/03/20 14:15:56 deraadt Exp $ */ | ||
| 2 | |||
| 3 | /* | ||
| 4 | * Copyright (c) 1995, 1999 | ||
| 5 | * Berkeley Software Design, Inc. All rights reserved. | ||
| 6 | * | ||
| 7 | * Redistribution and use in source and binary forms, with or without | ||
| 8 | * modification, are permitted provided that the following conditions | ||
| 9 | * are met: | ||
| 10 | * 1. Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * | ||
| 13 | * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND | ||
| 14 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 15 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 16 | * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE | ||
| 17 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 18 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 19 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 20 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 21 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 22 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 23 | * SUCH DAMAGE. | ||
| 24 | * | ||
| 25 | * BSDI getifaddrs.c,v 2.12 2000/02/23 14:51:59 dab Exp | ||
| 26 | */ | ||
| 27 | |||
| 28 | #include <sys/types.h> | ||
| 29 | #include <sys/ioctl.h> | ||
| 30 | #include <sys/socket.h> | ||
| 31 | #include <net/if.h> | ||
| 32 | #include <sys/param.h> | ||
| 33 | #include <net/route.h> | ||
| 34 | #include <sys/sysctl.h> | ||
| 35 | #include <net/if_dl.h> | ||
| 36 | |||
| 37 | #include <errno.h> | ||
| 38 | #include <ifaddrs.h> | ||
| 39 | #include <stddef.h> | ||
| 40 | #include <stdlib.h> | ||
| 41 | #include <string.h> | ||
| 42 | #include <unistd.h> | ||
| 43 | |||
| 44 | #define SALIGN (sizeof(long) - 1) | ||
| 45 | #define SA_RLEN(sa) ((sa)->sa_len ? (((sa)->sa_len + SALIGN) & ~SALIGN) : (SALIGN + 1)) | ||
| 46 | |||
| 47 | int | ||
| 48 | getifaddrs(struct ifaddrs **pif) | ||
| 49 | { | ||
| 50 | int icnt = 1; | ||
| 51 | int dcnt = 0; | ||
| 52 | int ncnt = 0; | ||
| 53 | int mib[6]; | ||
| 54 | size_t needed; | ||
| 55 | char *buf = NULL, *bufp; | ||
| 56 | char *next; | ||
| 57 | struct ifaddrs *cif = 0; | ||
| 58 | char *p, *p0; | ||
| 59 | struct rt_msghdr *rtm; | ||
| 60 | struct if_msghdr *ifm; | ||
| 61 | struct ifa_msghdr *ifam; | ||
| 62 | struct sockaddr_dl *dl; | ||
| 63 | struct sockaddr *sa; | ||
| 64 | u_short index = 0; | ||
| 65 | size_t len, alen, dlen; | ||
| 66 | struct ifaddrs *ifa, *ift; | ||
| 67 | int i; | ||
| 68 | char *data; | ||
| 69 | char *names; | ||
| 70 | |||
| 71 | mib[0] = CTL_NET; | ||
| 72 | mib[1] = PF_ROUTE; | ||
| 73 | mib[2] = 0; /* protocol */ | ||
| 74 | mib[3] = 0; /* wildcard address family */ | ||
| 75 | mib[4] = NET_RT_IFLIST; | ||
| 76 | mib[5] = 0; /* no flags */ | ||
| 77 | while (1) { | ||
| 78 | if (sysctl(mib, 6, NULL, &needed, NULL, 0) == -1) { | ||
| 79 | free(buf); | ||
| 80 | return (-1); | ||
| 81 | } | ||
| 82 | if (needed == 0) | ||
| 83 | break; | ||
| 84 | if ((bufp = realloc(buf, needed)) == NULL) { | ||
| 85 | free(buf); | ||
| 86 | return (-1); | ||
| 87 | } | ||
| 88 | buf = bufp; | ||
| 89 | if (sysctl(mib, 6, buf, &needed, NULL, 0) == -1) { | ||
| 90 | if (errno == ENOMEM) | ||
| 91 | continue; | ||
| 92 | free(buf); | ||
| 93 | return (-1); | ||
| 94 | } | ||
| 95 | break; | ||
| 96 | } | ||
| 97 | |||
| 98 | for (next = buf; next < buf + needed; next += rtm->rtm_msglen) { | ||
| 99 | rtm = (struct rt_msghdr *)next; | ||
| 100 | if (rtm->rtm_version != RTM_VERSION) | ||
| 101 | continue; | ||
| 102 | switch (rtm->rtm_type) { | ||
| 103 | case RTM_IFINFO: | ||
| 104 | ifm = (struct if_msghdr *)rtm; | ||
| 105 | if (ifm->ifm_addrs & RTA_IFP) { | ||
| 106 | index = ifm->ifm_index; | ||
| 107 | ++icnt; | ||
| 108 | dl = (struct sockaddr_dl *)(next + | ||
| 109 | rtm->rtm_hdrlen); | ||
| 110 | dcnt += SA_RLEN((struct sockaddr *)dl) + | ||
| 111 | ALIGNBYTES; | ||
| 112 | dcnt += sizeof(ifm->ifm_data); | ||
| 113 | ncnt += dl->sdl_nlen + 1; | ||
| 114 | } else | ||
| 115 | index = 0; | ||
| 116 | break; | ||
| 117 | |||
| 118 | case RTM_NEWADDR: | ||
| 119 | ifam = (struct ifa_msghdr *)rtm; | ||
| 120 | if (index && ifam->ifam_index != index) | ||
| 121 | abort(); /* XXX abort illegal in library */ | ||
| 122 | |||
| 123 | #define RTA_MASKS (RTA_NETMASK | RTA_IFA | RTA_BRD) | ||
| 124 | if (index == 0 || (ifam->ifam_addrs & RTA_MASKS) == 0) | ||
| 125 | break; | ||
| 126 | p = next + rtm->rtm_hdrlen; | ||
| 127 | ++icnt; | ||
| 128 | /* Scan to look for length of address */ | ||
| 129 | alen = 0; | ||
| 130 | for (p0 = p, i = 0; i < RTAX_MAX; i++) { | ||
| 131 | if ((RTA_MASKS & ifam->ifam_addrs & (1 << i)) | ||
| 132 | == 0) | ||
| 133 | continue; | ||
| 134 | sa = (struct sockaddr *)p; | ||
| 135 | len = SA_RLEN(sa); | ||
| 136 | if (i == RTAX_IFA) { | ||
| 137 | alen = len; | ||
| 138 | break; | ||
| 139 | } | ||
| 140 | p += len; | ||
| 141 | } | ||
| 142 | for (p = p0, i = 0; i < RTAX_MAX; i++) { | ||
| 143 | if ((RTA_MASKS & ifam->ifam_addrs & (1 << i)) | ||
| 144 | == 0) | ||
| 145 | continue; | ||
| 146 | sa = (struct sockaddr *)p; | ||
| 147 | len = SA_RLEN(sa); | ||
| 148 | if (i == RTAX_NETMASK && sa->sa_len == 0) | ||
| 149 | dcnt += alen; | ||
| 150 | else | ||
| 151 | dcnt += len; | ||
| 152 | p += len; | ||
| 153 | } | ||
| 154 | break; | ||
| 155 | } | ||
| 156 | } | ||
| 157 | |||
| 158 | if (icnt + dcnt + ncnt == 1) { | ||
| 159 | *pif = NULL; | ||
| 160 | free(buf); | ||
| 161 | return (0); | ||
| 162 | } | ||
| 163 | data = malloc(sizeof(struct ifaddrs) * icnt + dcnt + ncnt); | ||
| 164 | if (data == NULL) { | ||
| 165 | free(buf); | ||
| 166 | return(-1); | ||
| 167 | } | ||
| 168 | |||
| 169 | ifa = (struct ifaddrs *)data; | ||
| 170 | data += sizeof(struct ifaddrs) * icnt; | ||
| 171 | names = data + dcnt; | ||
| 172 | |||
| 173 | memset(ifa, 0, sizeof(struct ifaddrs) * icnt); | ||
| 174 | ift = ifa; | ||
| 175 | |||
| 176 | index = 0; | ||
| 177 | for (next = buf; next < buf + needed; next += rtm->rtm_msglen) { | ||
| 178 | rtm = (struct rt_msghdr *)next; | ||
| 179 | if (rtm->rtm_version != RTM_VERSION) | ||
| 180 | continue; | ||
| 181 | switch (rtm->rtm_type) { | ||
| 182 | case RTM_IFINFO: | ||
| 183 | ifm = (struct if_msghdr *)rtm; | ||
| 184 | if (ifm->ifm_addrs & RTA_IFP) { | ||
| 185 | index = ifm->ifm_index; | ||
| 186 | dl = (struct sockaddr_dl *)(next + | ||
| 187 | rtm->rtm_hdrlen); | ||
| 188 | |||
| 189 | cif = ift; | ||
| 190 | ift->ifa_name = names; | ||
| 191 | ift->ifa_flags = (int)ifm->ifm_flags; | ||
| 192 | memcpy(names, dl->sdl_data, dl->sdl_nlen); | ||
| 193 | names[dl->sdl_nlen] = 0; | ||
| 194 | names += dl->sdl_nlen + 1; | ||
| 195 | |||
| 196 | ift->ifa_addr = (struct sockaddr *)data; | ||
| 197 | memcpy(data, dl, | ||
| 198 | ((struct sockaddr *)dl)->sa_len); | ||
| 199 | data += SA_RLEN((struct sockaddr *)dl); | ||
| 200 | |||
| 201 | /* ifm_data needs to be aligned */ | ||
| 202 | ift->ifa_data = data = (void *)ALIGN(data); | ||
| 203 | dlen = rtm->rtm_hdrlen - | ||
| 204 | offsetof(struct if_msghdr, ifm_data); | ||
| 205 | if (dlen > sizeof(ifm->ifm_data)) | ||
| 206 | dlen = sizeof(ifm->ifm_data); | ||
| 207 | memcpy(data, &ifm->ifm_data, dlen); | ||
| 208 | data += sizeof(ifm->ifm_data); | ||
| 209 | |||
| 210 | ift = (ift->ifa_next = ift + 1); | ||
| 211 | } else | ||
| 212 | index = 0; | ||
| 213 | break; | ||
| 214 | |||
| 215 | case RTM_NEWADDR: | ||
| 216 | ifam = (struct ifa_msghdr *)rtm; | ||
| 217 | if (index && ifam->ifam_index != index) | ||
| 218 | abort(); /* XXX abort illegal in library */ | ||
| 219 | |||
| 220 | if (index == 0 || (ifam->ifam_addrs & RTA_MASKS) == 0) | ||
| 221 | break; | ||
| 222 | ift->ifa_name = cif->ifa_name; | ||
| 223 | ift->ifa_flags = cif->ifa_flags; | ||
| 224 | ift->ifa_data = NULL; | ||
| 225 | p = next + rtm->rtm_hdrlen; | ||
| 226 | /* Scan to look for length of address */ | ||
| 227 | alen = 0; | ||
| 228 | for (p0 = p, i = 0; i < RTAX_MAX; i++) { | ||
| 229 | if ((RTA_MASKS & ifam->ifam_addrs & (1 << i)) | ||
| 230 | == 0) | ||
| 231 | continue; | ||
| 232 | sa = (struct sockaddr *)p; | ||
| 233 | len = SA_RLEN(sa); | ||
| 234 | if (i == RTAX_IFA) { | ||
| 235 | alen = len; | ||
| 236 | break; | ||
| 237 | } | ||
| 238 | p += len; | ||
| 239 | } | ||
| 240 | for (p = p0, i = 0; i < RTAX_MAX; i++) { | ||
| 241 | if ((RTA_MASKS & ifam->ifam_addrs & (1 << i)) | ||
| 242 | == 0) | ||
| 243 | continue; | ||
| 244 | sa = (struct sockaddr *)p; | ||
| 245 | len = SA_RLEN(sa); | ||
| 246 | switch (i) { | ||
| 247 | case RTAX_IFA: | ||
| 248 | ift->ifa_addr = (struct sockaddr *)data; | ||
| 249 | memcpy(data, p, len); | ||
| 250 | data += len; | ||
| 251 | break; | ||
| 252 | |||
| 253 | case RTAX_NETMASK: | ||
| 254 | ift->ifa_netmask = | ||
| 255 | (struct sockaddr *)data; | ||
| 256 | if (sa->sa_len == 0) { | ||
| 257 | memset(data, 0, alen); | ||
| 258 | data += alen; | ||
| 259 | break; | ||
| 260 | } | ||
| 261 | memcpy(data, p, len); | ||
| 262 | data += len; | ||
| 263 | break; | ||
| 264 | |||
| 265 | case RTAX_BRD: | ||
| 266 | ift->ifa_broadaddr = | ||
| 267 | (struct sockaddr *)data; | ||
| 268 | memcpy(data, p, len); | ||
| 269 | data += len; | ||
| 270 | break; | ||
| 271 | } | ||
| 272 | p += len; | ||
| 273 | } | ||
| 274 | |||
| 275 | |||
| 276 | ift = (ift->ifa_next = ift + 1); | ||
| 277 | break; | ||
| 278 | } | ||
| 279 | } | ||
| 280 | |||
| 281 | free(buf); | ||
| 282 | if (--ift >= ifa) { | ||
| 283 | ift->ifa_next = NULL; | ||
| 284 | *pif = ifa; | ||
| 285 | } else { | ||
| 286 | *pif = NULL; | ||
| 287 | free(ifa); | ||
| 288 | } | ||
| 289 | return (0); | ||
| 290 | } | ||
| 291 | |||
| 292 | void | ||
| 293 | freeifaddrs(struct ifaddrs *ifp) | ||
| 294 | { | ||
| 295 | free(ifp); | ||
| 296 | } | ||
diff --git a/src/lib/libc/net/getnameinfo.3 b/src/lib/libc/net/getnameinfo.3 new file mode 100644 index 0000000000..d023b2523d --- /dev/null +++ b/src/lib/libc/net/getnameinfo.3 | |||
| @@ -0,0 +1,265 @@ | |||
| 1 | .\" $OpenBSD: getnameinfo.3,v 1.46 2014/01/21 03:15:45 schwarze Exp $ | ||
| 2 | .\" $KAME: getnameinfo.3,v 1.37 2005/01/05 03:23:05 itojun Exp $ | ||
| 3 | .\" | ||
| 4 | .\" Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") | ||
| 5 | .\" Copyright (C) 2000, 2001 Internet Software Consortium. | ||
| 6 | .\" | ||
| 7 | .\" Permission to use, copy, modify, and distribute this software for any | ||
| 8 | .\" purpose with or without fee is hereby granted, provided that the above | ||
| 9 | .\" copyright notice and this permission notice appear in all copies. | ||
| 10 | .\" | ||
| 11 | .\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH | ||
| 12 | .\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY | ||
| 13 | .\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, | ||
| 14 | .\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM | ||
| 15 | .\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE | ||
| 16 | .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | ||
| 17 | .\" PERFORMANCE OF THIS SOFTWARE. | ||
| 18 | .\" | ||
| 19 | .Dd $Mdocdate: January 21 2014 $ | ||
| 20 | .Dt GETNAMEINFO 3 | ||
| 21 | .Os | ||
| 22 | .Sh NAME | ||
| 23 | .Nm getnameinfo | ||
| 24 | .Nd socket address structure to hostname and service name | ||
| 25 | .Sh SYNOPSIS | ||
| 26 | .In sys/types.h | ||
| 27 | .In sys/socket.h | ||
| 28 | .In netdb.h | ||
| 29 | .Ft int | ||
| 30 | .Fn getnameinfo "const struct sockaddr *sa" "socklen_t salen" "char *host" \ | ||
| 31 | "size_t hostlen" "char *serv" "size_t servlen" "int flags" | ||
| 32 | .Sh DESCRIPTION | ||
| 33 | The | ||
| 34 | .Fn getnameinfo | ||
| 35 | function is used to convert a | ||
| 36 | .Li sockaddr | ||
| 37 | structure to a pair of host name and service strings. | ||
| 38 | It is a replacement for and provides more flexibility than the | ||
| 39 | .Xr gethostbyaddr 3 | ||
| 40 | and | ||
| 41 | .Xr getservbyport 3 | ||
| 42 | functions and is the converse of the | ||
| 43 | .Xr getaddrinfo 3 | ||
| 44 | function. | ||
| 45 | .Pp | ||
| 46 | The | ||
| 47 | .Li sockaddr | ||
| 48 | structure | ||
| 49 | .Fa sa | ||
| 50 | should point to either a | ||
| 51 | .Li sockaddr_in | ||
| 52 | or | ||
| 53 | .Li sockaddr_in6 | ||
| 54 | structure (for IPv4 or IPv6 respectively) that is | ||
| 55 | .Fa salen | ||
| 56 | bytes long. | ||
| 57 | .Pp | ||
| 58 | The host and service names associated with | ||
| 59 | .Fa sa | ||
| 60 | are stored in | ||
| 61 | .Fa host | ||
| 62 | and | ||
| 63 | .Fa serv | ||
| 64 | which have length parameters | ||
| 65 | .Fa hostlen | ||
| 66 | and | ||
| 67 | .Fa servlen . | ||
| 68 | The maximum value for | ||
| 69 | .Fa hostlen | ||
| 70 | is | ||
| 71 | .Dv NI_MAXHOST | ||
| 72 | and | ||
| 73 | the maximum value for | ||
| 74 | .Fa servlen | ||
| 75 | is | ||
| 76 | .Dv NI_MAXSERV , | ||
| 77 | as defined by | ||
| 78 | .In netdb.h . | ||
| 79 | If a length parameter is zero, no string will be stored. | ||
| 80 | Otherwise, enough space must be provided to store the | ||
| 81 | host name or service string plus a byte for the NUL terminator. | ||
| 82 | .Pp | ||
| 83 | The | ||
| 84 | .Fa flags | ||
| 85 | argument is formed by | ||
| 86 | .Tn OR Ns 'ing | ||
| 87 | the following values: | ||
| 88 | .Bl -tag -width "NI_NUMERICHOSTXX" | ||
| 89 | .It Dv NI_NOFQDN | ||
| 90 | A fully qualified domain name is not required for local hosts. | ||
| 91 | The local part of the fully qualified domain name is returned instead. | ||
| 92 | .It Dv NI_NUMERICHOST | ||
| 93 | Return the address in numeric form, as if calling | ||
| 94 | .Xr inet_ntop 3 , | ||
| 95 | instead of a host name. | ||
| 96 | .It Dv NI_NAMEREQD | ||
| 97 | A name is required. | ||
| 98 | If the host name cannot be found in DNS and this flag is set, | ||
| 99 | a non-zero error code is returned. | ||
| 100 | If the host name is not found and the flag is not set, the | ||
| 101 | address is returned in numeric form. | ||
| 102 | .It NI_NUMERICSERV | ||
| 103 | The service name is returned as a digit string representing the port number. | ||
| 104 | .It NI_DGRAM | ||
| 105 | Specifies that the service being looked up is a datagram | ||
| 106 | service, and causes | ||
| 107 | .Xr getservbyport 3 | ||
| 108 | to be called with a second argument of | ||
| 109 | .Dq udp | ||
| 110 | instead of its default of | ||
| 111 | .Dq tcp . | ||
| 112 | This is required for the few ports (512\-514) that have different services | ||
| 113 | for | ||
| 114 | .Tn UDP | ||
| 115 | and | ||
| 116 | .Tn TCP . | ||
| 117 | .El | ||
| 118 | .Pp | ||
| 119 | This implementation allows numeric IPv6 address notation with scope identifier, | ||
| 120 | as documented in RFC 4007. | ||
| 121 | IPv6 link-local address will appear as a string like | ||
| 122 | .Dq Li fe80::1%ne0 . | ||
| 123 | Refer to | ||
| 124 | .Xr getaddrinfo 3 | ||
| 125 | for more information. | ||
| 126 | .Sh RETURN VALUES | ||
| 127 | .Fn getnameinfo | ||
| 128 | returns zero on success or one of the error codes listed in | ||
| 129 | .Xr gai_strerror 3 | ||
| 130 | if an error occurs. | ||
| 131 | .Sh EXAMPLES | ||
| 132 | The following code tries to get a numeric host name, and service name, | ||
| 133 | for a given socket address. | ||
| 134 | Observe that there is no hardcoded reference to a particular address family. | ||
| 135 | .Bd -literal -offset indent | ||
| 136 | struct sockaddr *sa; /* input */ | ||
| 137 | char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; | ||
| 138 | |||
| 139 | if (getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf), sbuf, | ||
| 140 | sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV)) | ||
| 141 | errx(1, "could not get numeric hostname"); | ||
| 142 | printf("host=%s, serv=%s\en", hbuf, sbuf); | ||
| 143 | .Ed | ||
| 144 | .Pp | ||
| 145 | The following version checks if the socket address has a reverse address mapping: | ||
| 146 | .Bd -literal -offset indent | ||
| 147 | struct sockaddr *sa; /* input */ | ||
| 148 | char hbuf[NI_MAXHOST]; | ||
| 149 | |||
| 150 | if (getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf), NULL, 0, | ||
| 151 | NI_NAMEREQD)) | ||
| 152 | errx(1, "could not resolve hostname"); | ||
| 153 | printf("host=%s\en", hbuf); | ||
| 154 | .Ed | ||
| 155 | .Sh SEE ALSO | ||
| 156 | .Xr gai_strerror 3 , | ||
| 157 | .Xr getaddrinfo 3 , | ||
| 158 | .Xr gethostbyaddr 3 , | ||
| 159 | .Xr getservbyport 3 , | ||
| 160 | .Xr inet_ntop 3 , | ||
| 161 | .Xr resolver 3 , | ||
| 162 | .Xr hosts 5 , | ||
| 163 | .Xr resolv.conf 5 , | ||
| 164 | .Xr services 5 , | ||
| 165 | .Xr hostname 7 , | ||
| 166 | .Xr named 8 | ||
| 167 | .Rs | ||
| 168 | .%A Craig Metz | ||
| 169 | .%T Protocol Independence Using the Sockets API | ||
| 170 | .%B Proceedings of the Freenix Track: 2000 USENIX Annual Technical Conference | ||
| 171 | .%D June 2000 | ||
| 172 | .Re | ||
| 173 | .Sh STANDARDS | ||
| 174 | The | ||
| 175 | .Fn getnameinfo | ||
| 176 | function is defined by the | ||
| 177 | .St -p1003.1g-2000 | ||
| 178 | draft specification and documented in RFC 3493. | ||
| 179 | .Pp | ||
| 180 | .Rs | ||
| 181 | .%A R. Gilligan | ||
| 182 | .%A S. Thomson | ||
| 183 | .%A J. Bound | ||
| 184 | .%A J. McCann | ||
| 185 | .%A W. Stevens | ||
| 186 | .%D February 2003 | ||
| 187 | .%R RFC 3493 | ||
| 188 | .%T Basic Socket Interface Extensions for IPv6 | ||
| 189 | .Re | ||
| 190 | .Pp | ||
| 191 | .Rs | ||
| 192 | .%A S. Deering | ||
| 193 | .%A B. Haberman | ||
| 194 | .%A T. Jinmei | ||
| 195 | .%A E. Nordmark | ||
| 196 | .%A B. Zill | ||
| 197 | .%D March 2005 | ||
| 198 | .%R RFC 4007 | ||
| 199 | .%T IPv6 Scoped Address Architecture | ||
| 200 | .Re | ||
| 201 | .Sh CAVEATS | ||
| 202 | .Fn getnameinfo | ||
| 203 | can return both numeric and FQDN forms of the address specified in | ||
| 204 | .Fa sa . | ||
| 205 | There is no return value that indicates whether the string returned in | ||
| 206 | .Fa host | ||
| 207 | is a result of binary to numeric-text translation (like | ||
| 208 | .Xr inet_ntop 3 ) , | ||
| 209 | or is the result of a DNS reverse lookup. | ||
| 210 | Because of this, malicious parties could set up a PTR record as follows: | ||
| 211 | .Bd -literal -offset indent | ||
| 212 | 1.0.0.127.in-addr.arpa. IN PTR 10.1.1.1 | ||
| 213 | .Ed | ||
| 214 | .Pp | ||
| 215 | and trick the caller of | ||
| 216 | .Fn getnameinfo | ||
| 217 | into believing that | ||
| 218 | .Fa sa | ||
| 219 | is | ||
| 220 | .Li 10.1.1.1 | ||
| 221 | when it is actually | ||
| 222 | .Li 127.0.0.1 . | ||
| 223 | .Pp | ||
| 224 | To prevent such attacks, the use of | ||
| 225 | .Dv NI_NAMEREQD | ||
| 226 | is recommended when the result of | ||
| 227 | .Fn getnameinfo | ||
| 228 | is used | ||
| 229 | for access control purposes: | ||
| 230 | .Bd -literal -offset indent | ||
| 231 | struct sockaddr *sa; | ||
| 232 | char addr[NI_MAXHOST]; | ||
| 233 | struct addrinfo hints, *res; | ||
| 234 | int error; | ||
| 235 | |||
| 236 | error = getnameinfo(sa, sa->sa_len, addr, sizeof(addr), | ||
| 237 | NULL, 0, NI_NAMEREQD); | ||
| 238 | if (error == 0) { | ||
| 239 | memset(&hints, 0, sizeof(hints)); | ||
| 240 | hints.ai_socktype = SOCK_DGRAM; /*dummy*/ | ||
| 241 | hints.ai_flags = AI_NUMERICHOST; | ||
| 242 | if (getaddrinfo(addr, "0", &hints, &res) == 0) { | ||
| 243 | /* malicious PTR record */ | ||
| 244 | freeaddrinfo(res); | ||
| 245 | printf("bogus PTR record\en"); | ||
| 246 | return -1; | ||
| 247 | } | ||
| 248 | /* addr is FQDN as a result of PTR lookup */ | ||
| 249 | } else { | ||
| 250 | /* addr is numeric string */ | ||
| 251 | error = getnameinfo(sa, sa->sa_len, addr, sizeof(addr), | ||
| 252 | NULL, 0, NI_NUMERICHOST); | ||
| 253 | } | ||
| 254 | .Ed | ||
| 255 | .Sh BUGS | ||
| 256 | The implementation of | ||
| 257 | .Fn getnameinfo | ||
| 258 | is not thread-safe. | ||
| 259 | .Pp | ||
| 260 | .Ox | ||
| 261 | intentionally uses a different | ||
| 262 | .Dv NI_MAXHOST | ||
| 263 | value from what | ||
| 264 | .Tn "RFC 2553" | ||
| 265 | suggests, to avoid buffer length handling mistakes. | ||
diff --git a/src/lib/libc/net/getnetbyaddr.c b/src/lib/libc/net/getnetbyaddr.c index c193860e36..a85106630c 100644 --- a/src/lib/libc/net/getnetbyaddr.c +++ b/src/lib/libc/net/getnetbyaddr.c | |||
| @@ -1,5 +1,4 @@ | |||
| 1 | /* $NetBSD: getnetbyaddr.c,v 1.4 1995/02/25 06:20:30 cgd Exp $ */ | 1 | /* $OpenBSD: getnetbyaddr.c,v 1.8 2005/08/06 20:30:03 espie Exp $ */ |
| 2 | |||
| 3 | /* | 2 | /* |
| 4 | * Copyright (c) 1983, 1993 | 3 | * Copyright (c) 1983, 1993 |
| 5 | * The Regents of the University of California. All rights reserved. | 4 | * The Regents of the University of California. All rights reserved. |
| @@ -12,11 +11,7 @@ | |||
| 12 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
| 13 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the |
| 14 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. |
| 15 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. Neither the name of the University nor the names of its contributors |
| 16 | * must display the following acknowledgement: | ||
| 17 | * This product includes software developed by the University of | ||
| 18 | * California, Berkeley and its contributors. | ||
| 19 | * 4. Neither the name of the University nor the names of its contributors | ||
| 20 | * may be used to endorse or promote products derived from this software | 15 | * may be used to endorse or promote products derived from this software |
| 21 | * without specific prior written permission. | 16 | * without specific prior written permission. |
| 22 | * | 17 | * |
| @@ -33,27 +28,17 @@ | |||
| 33 | * SUCH DAMAGE. | 28 | * SUCH DAMAGE. |
| 34 | */ | 29 | */ |
| 35 | 30 | ||
| 36 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 37 | #if 0 | ||
| 38 | static char sccsid[] = "@(#)getnetbyaddr.c 8.1 (Berkeley) 6/4/93"; | ||
| 39 | #else | ||
| 40 | static char rcsid[] = "$NetBSD: getnetbyaddr.c,v 1.4 1995/02/25 06:20:30 cgd Exp $"; | ||
| 41 | #endif | ||
| 42 | #endif /* LIBC_SCCS and not lint */ | ||
| 43 | |||
| 44 | #include <netdb.h> | 31 | #include <netdb.h> |
| 45 | 32 | ||
| 46 | extern int _net_stayopen; | 33 | extern int _net_stayopen; |
| 47 | 34 | ||
| 48 | struct netent * | 35 | struct netent * |
| 49 | getnetbyaddr(net, type) | 36 | _getnetbyaddr(in_addr_t net, int type) |
| 50 | register long net; | ||
| 51 | register int type; | ||
| 52 | { | 37 | { |
| 53 | register struct netent *p; | 38 | struct netent *p; |
| 54 | 39 | ||
| 55 | setnetent(_net_stayopen); | 40 | setnetent(_net_stayopen); |
| 56 | while (p = getnetent()) | 41 | while ((p = getnetent())) |
| 57 | if (p->n_addrtype == type && p->n_net == net) | 42 | if (p->n_addrtype == type && p->n_net == net) |
| 58 | break; | 43 | break; |
| 59 | if (!_net_stayopen) | 44 | if (!_net_stayopen) |
diff --git a/src/lib/libc/net/getnetbyname.c b/src/lib/libc/net/getnetbyname.c index 93a2e1256c..e6540cf12c 100644 --- a/src/lib/libc/net/getnetbyname.c +++ b/src/lib/libc/net/getnetbyname.c | |||
| @@ -1,5 +1,4 @@ | |||
| 1 | /* $NetBSD: getnetbyname.c,v 1.4 1995/02/25 06:20:31 cgd Exp $ */ | 1 | /* $OpenBSD: getnetbyname.c,v 1.8 2005/08/06 20:30:03 espie Exp $ */ |
| 2 | |||
| 3 | /* | 2 | /* |
| 4 | * Copyright (c) 1983, 1993 | 3 | * Copyright (c) 1983, 1993 |
| 5 | * The Regents of the University of California. All rights reserved. | 4 | * The Regents of the University of California. All rights reserved. |
| @@ -12,11 +11,7 @@ | |||
| 12 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
| 13 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the |
| 14 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. |
| 15 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. Neither the name of the University nor the names of its contributors |
| 16 | * must display the following acknowledgement: | ||
| 17 | * This product includes software developed by the University of | ||
| 18 | * California, Berkeley and its contributors. | ||
| 19 | * 4. Neither the name of the University nor the names of its contributors | ||
| 20 | * may be used to endorse or promote products derived from this software | 15 | * may be used to endorse or promote products derived from this software |
| 21 | * without specific prior written permission. | 16 | * without specific prior written permission. |
| 22 | * | 17 | * |
| @@ -33,32 +28,23 @@ | |||
| 33 | * SUCH DAMAGE. | 28 | * SUCH DAMAGE. |
| 34 | */ | 29 | */ |
| 35 | 30 | ||
| 36 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 37 | #if 0 | ||
| 38 | static char sccsid[] = "@(#)getnetbyname.c 8.1 (Berkeley) 6/4/93"; | ||
| 39 | #else | ||
| 40 | static char rcsid[] = "$NetBSD: getnetbyname.c,v 1.4 1995/02/25 06:20:31 cgd Exp $"; | ||
| 41 | #endif | ||
| 42 | #endif /* LIBC_SCCS and not lint */ | ||
| 43 | |||
| 44 | #include <netdb.h> | 31 | #include <netdb.h> |
| 45 | #include <string.h> | 32 | #include <string.h> |
| 46 | 33 | ||
| 47 | extern int _net_stayopen; | 34 | extern int _net_stayopen; |
| 48 | 35 | ||
| 49 | struct netent * | 36 | struct netent * |
| 50 | getnetbyname(name) | 37 | _getnetbyname(const char *name) |
| 51 | register const char *name; | ||
| 52 | { | 38 | { |
| 53 | register struct netent *p; | 39 | struct netent *p; |
| 54 | register char **cp; | 40 | char **cp; |
| 55 | 41 | ||
| 56 | setnetent(_net_stayopen); | 42 | setnetent(_net_stayopen); |
| 57 | while (p = getnetent()) { | 43 | while ((p = getnetent())) { |
| 58 | if (strcmp(p->n_name, name) == 0) | 44 | if (strcasecmp(p->n_name, name) == 0) |
| 59 | break; | 45 | break; |
| 60 | for (cp = p->n_aliases; *cp != 0; cp++) | 46 | for (cp = p->n_aliases; *cp != 0; cp++) |
| 61 | if (strcmp(*cp, name) == 0) | 47 | if (strcasecmp(*cp, name) == 0) |
| 62 | goto found; | 48 | goto found; |
| 63 | } | 49 | } |
| 64 | found: | 50 | found: |
diff --git a/src/lib/libc/net/getnetent.3 b/src/lib/libc/net/getnetent.3 index d4f0bedbf9..e0344e2dd0 100644 --- a/src/lib/libc/net/getnetent.3 +++ b/src/lib/libc/net/getnetent.3 | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | .\" $NetBSD: getnetent.3,v 1.3 1995/02/25 06:20:32 cgd Exp $ | 1 | .\" $OpenBSD: getnetent.3,v 1.16 2013/06/05 03:39:23 tedu Exp $ |
| 2 | .\" | 2 | .\" |
| 3 | .\" Copyright (c) 1983, 1991, 1993 | 3 | .\" Copyright (c) 1983, 1991, 1993 |
| 4 | .\" The Regents of the University of California. All rights reserved. | 4 | .\" The Regents of the University of California. All rights reserved. |
| @@ -11,11 +11,7 @@ | |||
| 11 | .\" 2. Redistributions in binary form must reproduce the above copyright | 11 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 12 | .\" notice, this list of conditions and the following disclaimer in the | 12 | .\" notice, this list of conditions and the following disclaimer in the |
| 13 | .\" documentation and/or other materials provided with the distribution. | 13 | .\" documentation and/or other materials provided with the distribution. |
| 14 | .\" 3. All advertising materials mentioning features or use of this software | 14 | .\" 3. Neither the name of the University nor the names of its contributors |
| 15 | .\" must display the following acknowledgement: | ||
| 16 | .\" This product includes software developed by the University of | ||
| 17 | .\" California, Berkeley and its contributors. | ||
| 18 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 19 | .\" may be used to endorse or promote products derived from this software | 15 | .\" may be used to endorse or promote products derived from this software |
| 20 | .\" without specific prior written permission. | 16 | .\" without specific prior written permission. |
| 21 | .\" | 17 | .\" |
| @@ -31,11 +27,9 @@ | |||
| 31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 27 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 32 | .\" SUCH DAMAGE. | 28 | .\" SUCH DAMAGE. |
| 33 | .\" | 29 | .\" |
| 34 | .\" @(#)getnetent.3 8.1 (Berkeley) 6/4/93 | 30 | .Dd $Mdocdate: June 5 2013 $ |
| 35 | .\" | ||
| 36 | .Dd June 4, 1993 | ||
| 37 | .Dt GETNETENT 3 | 31 | .Dt GETNETENT 3 |
| 38 | .Os BSD 4.2 | 32 | .Os |
| 39 | .Sh NAME | 33 | .Sh NAME |
| 40 | .Nm getnetent , | 34 | .Nm getnetent , |
| 41 | .Nm getnetbyaddr , | 35 | .Nm getnetbyaddr , |
| @@ -44,33 +38,32 @@ | |||
| 44 | .Nm endnetent | 38 | .Nm endnetent |
| 45 | .Nd get network entry | 39 | .Nd get network entry |
| 46 | .Sh SYNOPSIS | 40 | .Sh SYNOPSIS |
| 47 | .Fd #include <netdb.h> | 41 | .In netdb.h |
| 48 | .Ft struct netent * | 42 | .Ft struct netent * |
| 49 | .Fn getnetent | 43 | .Fn getnetent "void" |
| 50 | .Ft struct netent * | 44 | .Ft struct netent * |
| 51 | .Fn getnetbyname "char *name" | 45 | .Fn getnetbyname "const char *name" |
| 52 | .Ft struct netent * | 46 | .Ft struct netent * |
| 53 | .Fn getnetbyaddr "long net" "int type" | 47 | .Fn getnetbyaddr "in_addr_t net" "int type" |
| 48 | .Ft void | ||
| 54 | .Fn setnetent "int stayopen" | 49 | .Fn setnetent "int stayopen" |
| 55 | .Fn endnetent | 50 | .Ft void |
| 51 | .Fn endnetent "void" | ||
| 56 | .Sh DESCRIPTION | 52 | .Sh DESCRIPTION |
| 57 | The | 53 | The |
| 58 | .Fn getnetent , | 54 | .Fn getnetent , |
| 59 | .Fn getnetbyname , | 55 | .Fn getnetbyname , |
| 60 | and | 56 | and |
| 61 | .Fn getnetbyaddr | 57 | .Fn getnetbyaddr |
| 62 | functions | 58 | functions each return a pointer to an object with the following structure |
| 63 | each return a pointer to an object with the | 59 | containing the broken-out fields of a line in the network database, |
| 64 | following structure | ||
| 65 | containing the broken-out | ||
| 66 | fields of a line in the network data base, | ||
| 67 | .Pa /etc/networks . | 60 | .Pa /etc/networks . |
| 68 | .Bd -literal -offset indent | 61 | .Bd -literal -offset indent |
| 69 | struct netent { | 62 | struct netent { |
| 70 | char *n_name; /* official name of net */ | 63 | char *n_name; /* official name of net */ |
| 71 | char **n_aliases; /* alias list */ | 64 | char **n_aliases; /* alias list */ |
| 72 | int n_addrtype; /* net number type */ | 65 | int n_addrtype; /* net number type */ |
| 73 | unsigned long n_net; /* net number */ | 66 | in_addr_t n_net; /* net number */ |
| 74 | }; | 67 | }; |
| 75 | .Ed | 68 | .Ed |
| 76 | .Pp | 69 | .Pp |
| @@ -79,45 +72,42 @@ The members of this structure are: | |||
| 79 | .It Fa n_name | 72 | .It Fa n_name |
| 80 | The official name of the network. | 73 | The official name of the network. |
| 81 | .It Fa n_aliases | 74 | .It Fa n_aliases |
| 82 | A zero terminated list of alternate names for the network. | 75 | A null-terminated list of alternate names for the network. |
| 83 | .It Fa n_addrtype | 76 | .It Fa n_addrtype |
| 84 | The type of the network number returned; currently only AF_INET. | 77 | The type of the network number returned; currently only |
| 78 | .Dv AF_INET . | ||
| 85 | .It Fa n_net | 79 | .It Fa n_net |
| 86 | The network number. Network numbers are returned in machine byte | 80 | The network number. |
| 87 | order. | 81 | Network numbers are returned in machine byte order. |
| 88 | .El | 82 | .El |
| 89 | .Pp | 83 | .Pp |
| 90 | The | 84 | The |
| 91 | .Fn getnetent | 85 | .Fn getnetent |
| 92 | function | 86 | function reads the next line of the file, opening the file if necessary. |
| 93 | reads the next line of the file, opening the file if necessary. | ||
| 94 | .Pp | 87 | .Pp |
| 95 | The | 88 | The |
| 96 | .Fn setnetent | 89 | .Fn setnetent |
| 97 | function | 90 | function opens and rewinds the file. |
| 98 | opens and rewinds the file. If the | 91 | If the |
| 99 | .Fa stayopen | 92 | .Fa stayopen |
| 100 | flag is non-zero, | 93 | flag is non-zero, |
| 101 | the net data base will not be closed after each call to | 94 | the net database will not be closed after each call to |
| 102 | .Fn getnetbyname | 95 | .Fn getnetbyname |
| 103 | or | 96 | or |
| 104 | .Fn getnetbyaddr . | 97 | .Fn getnetbyaddr . |
| 105 | .Pp | 98 | .Pp |
| 106 | The | 99 | The |
| 107 | .Fn endnetent | 100 | .Fn endnetent |
| 108 | function | 101 | function closes the file. |
| 109 | closes the file. | ||
| 110 | .Pp | 102 | .Pp |
| 111 | The | 103 | The |
| 112 | .Fn getnetbyname | 104 | .Fn getnetbyname |
| 113 | function | ||
| 114 | and | 105 | and |
| 115 | .Fn getnetbyaddr | 106 | .Fn getnetbyaddr |
| 116 | sequentially search from the beginning | 107 | functions search the domain name server if the system is configured to use one. |
| 117 | of the file until a matching | 108 | If the search fails, or no name server is configured, they sequentially |
| 118 | net name or | 109 | search from the beginning of the file until a matching net name or |
| 119 | net address and type is found, | 110 | net address and type is found, or until |
| 120 | or until | ||
| 121 | .Dv EOF | 111 | .Dv EOF |
| 122 | is encountered. | 112 | is encountered. |
| 123 | Network numbers are supplied in host order. | 113 | Network numbers are supplied in host order. |
| @@ -126,11 +116,11 @@ Network numbers are supplied in host order. | |||
| 126 | .It Pa /etc/networks | 116 | .It Pa /etc/networks |
| 127 | .El | 117 | .El |
| 128 | .Sh DIAGNOSTICS | 118 | .Sh DIAGNOSTICS |
| 129 | Null pointer | 119 | Null pointer (0) returned on |
| 130 | (0) returned on | ||
| 131 | .Dv EOF | 120 | .Dv EOF |
| 132 | or error. | 121 | or error. |
| 133 | .Sh SEE ALSO | 122 | .Sh SEE ALSO |
| 123 | .Xr resolver 3 , | ||
| 134 | .Xr networks 5 | 124 | .Xr networks 5 |
| 135 | .Sh HISTORY | 125 | .Sh HISTORY |
| 136 | The | 126 | The |
| @@ -140,14 +130,11 @@ The | |||
| 140 | .Fn setnetent , | 130 | .Fn setnetent , |
| 141 | and | 131 | and |
| 142 | .Fn endnetent | 132 | .Fn endnetent |
| 143 | functions appeared in | 133 | functions appeared in |
| 144 | .Bx 4.2 . | 134 | .Bx 4.2 . |
| 145 | .Sh BUGS | 135 | .Sh BUGS |
| 146 | The data space used by | 136 | The data space used by these functions is static; if future use |
| 147 | these functions is static; if future use requires the data, it should be | 137 | requires the data, it should be copied before any subsequent calls |
| 148 | copied before any subsequent calls to these functions overwrite it. | 138 | to these functions overwrite it. |
| 149 | Only Internet network | 139 | Only Internet network numbers are currently understood. |
| 150 | numbers are currently understood. | 140 | Expecting network numbers to fit in no more than 32 bits is naive. |
| 151 | Expecting network numbers to fit | ||
| 152 | in no more than 32 bits is probably | ||
| 153 | naive. | ||
diff --git a/src/lib/libc/net/getnetent.c b/src/lib/libc/net/getnetent.c index b4e16b8f5d..57fe459e2b 100644 --- a/src/lib/libc/net/getnetent.c +++ b/src/lib/libc/net/getnetent.c | |||
| @@ -1,5 +1,4 @@ | |||
| 1 | /* $NetBSD: getnetent.c,v 1.4 1995/02/25 06:20:33 cgd Exp $ */ | 1 | /* $OpenBSD: getnetent.c,v 1.13 2012/04/10 16:41:10 eric Exp $ */ |
| 2 | |||
| 3 | /* | 2 | /* |
| 4 | * Copyright (c) 1983, 1993 | 3 | * Copyright (c) 1983, 1993 |
| 5 | * The Regents of the University of California. All rights reserved. | 4 | * The Regents of the University of California. All rights reserved. |
| @@ -12,11 +11,7 @@ | |||
| 12 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
| 13 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the |
| 14 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. |
| 15 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. Neither the name of the University nor the names of its contributors |
| 16 | * must display the following acknowledgement: | ||
| 17 | * This product includes software developed by the University of | ||
| 18 | * California, Berkeley and its contributors. | ||
| 19 | * 4. Neither the name of the University nor the names of its contributors | ||
| 20 | * may be used to endorse or promote products derived from this software | 15 | * may be used to endorse or promote products derived from this software |
| 21 | * without specific prior written permission. | 16 | * without specific prior written permission. |
| 22 | * | 17 | * |
| @@ -33,15 +28,7 @@ | |||
| 33 | * SUCH DAMAGE. | 28 | * SUCH DAMAGE. |
| 34 | */ | 29 | */ |
| 35 | 30 | ||
| 36 | #if defined(LIBC_SCCS) && !defined(lint) | 31 | #include <sys/param.h> |
| 37 | #if 0 | ||
| 38 | static char sccsid[] = "@(#)getnetent.c 8.1 (Berkeley) 6/4/93"; | ||
| 39 | #else | ||
| 40 | static char rcsid[] = "$NetBSD: getnetent.c,v 1.4 1995/02/25 06:20:33 cgd Exp $"; | ||
| 41 | #endif | ||
| 42 | #endif /* LIBC_SCCS and not lint */ | ||
| 43 | |||
| 44 | #include <sys/types.h> | ||
| 45 | #include <sys/socket.h> | 32 | #include <sys/socket.h> |
| 46 | #include <netinet/in.h> | 33 | #include <netinet/in.h> |
| 47 | #include <arpa/inet.h> | 34 | #include <arpa/inet.h> |
| @@ -58,8 +45,7 @@ static char *net_aliases[MAXALIASES]; | |||
| 58 | int _net_stayopen; | 45 | int _net_stayopen; |
| 59 | 46 | ||
| 60 | void | 47 | void |
| 61 | setnetent(f) | 48 | setnetent(int f) |
| 62 | int f; | ||
| 63 | { | 49 | { |
| 64 | if (netf == NULL) | 50 | if (netf == NULL) |
| 65 | netf = fopen(_PATH_NETWORKS, "r" ); | 51 | netf = fopen(_PATH_NETWORKS, "r" ); |
| @@ -69,7 +55,7 @@ setnetent(f) | |||
| 69 | } | 55 | } |
| 70 | 56 | ||
| 71 | void | 57 | void |
| 72 | endnetent() | 58 | endnetent(void) |
| 73 | { | 59 | { |
| 74 | if (netf) { | 60 | if (netf) { |
| 75 | fclose(netf); | 61 | fclose(netf); |
| @@ -79,24 +65,29 @@ endnetent() | |||
| 79 | } | 65 | } |
| 80 | 66 | ||
| 81 | struct netent * | 67 | struct netent * |
| 82 | getnetent() | 68 | getnetent(void) |
| 83 | { | 69 | { |
| 84 | char *p; | 70 | char *p, *cp, **q; |
| 85 | register char *cp, **q; | 71 | size_t len; |
| 86 | 72 | ||
| 87 | if (netf == NULL && (netf = fopen(_PATH_NETWORKS, "r" )) == NULL) | 73 | if (netf == NULL && (netf = fopen(_PATH_NETWORKS, "r" )) == NULL) |
| 88 | return (NULL); | 74 | return (NULL); |
| 89 | again: | 75 | again: |
| 90 | p = fgets(line, BUFSIZ, netf); | 76 | if ((p = fgetln(netf, &len)) == NULL) |
| 91 | if (p == NULL) | ||
| 92 | return (NULL); | 77 | return (NULL); |
| 93 | if (*p == '#') | 78 | if (p[len-1] == '\n') |
| 79 | len--; | ||
| 80 | if (len >= sizeof(line) || len == 0) | ||
| 94 | goto again; | 81 | goto again; |
| 95 | cp = strpbrk(p, "#\n"); | 82 | p = memcpy(line, p, len); |
| 96 | if (cp == NULL) | 83 | line[len] = '\0'; |
| 84 | if (*p == '#') | ||
| 97 | goto again; | 85 | goto again; |
| 98 | *cp = '\0'; | 86 | if ((cp = strchr(p, '#')) != NULL) |
| 87 | *cp = '\0'; | ||
| 99 | net.n_name = p; | 88 | net.n_name = p; |
| 89 | if (strlen(net.n_name) >= MAXHOSTNAMELEN-1) | ||
| 90 | net.n_name[MAXHOSTNAMELEN-1] = '\0'; | ||
| 100 | cp = strpbrk(p, " \t"); | 91 | cp = strpbrk(p, " \t"); |
| 101 | if (cp == NULL) | 92 | if (cp == NULL) |
| 102 | goto again; | 93 | goto again; |
| @@ -109,15 +100,17 @@ again: | |||
| 109 | net.n_net = inet_network(cp); | 100 | net.n_net = inet_network(cp); |
| 110 | net.n_addrtype = AF_INET; | 101 | net.n_addrtype = AF_INET; |
| 111 | q = net.n_aliases = net_aliases; | 102 | q = net.n_aliases = net_aliases; |
| 112 | if (p != NULL) | 103 | cp = p; |
| 113 | cp = p; | ||
| 114 | while (cp && *cp) { | 104 | while (cp && *cp) { |
| 115 | if (*cp == ' ' || *cp == '\t') { | 105 | if (*cp == ' ' || *cp == '\t') { |
| 116 | cp++; | 106 | cp++; |
| 117 | continue; | 107 | continue; |
| 118 | } | 108 | } |
| 119 | if (q < &net_aliases[MAXALIASES - 1]) | 109 | if (q < &net_aliases[MAXALIASES - 1]) { |
| 120 | *q++ = cp; | 110 | *q++ = cp; |
| 111 | if (strlen(cp) >= MAXHOSTNAMELEN-1) | ||
| 112 | cp[MAXHOSTNAMELEN-1] = '\0'; | ||
| 113 | } | ||
| 121 | cp = strpbrk(cp, " \t"); | 114 | cp = strpbrk(cp, " \t"); |
| 122 | if (cp != NULL) | 115 | if (cp != NULL) |
| 123 | *cp++ = '\0'; | 116 | *cp++ = '\0'; |
diff --git a/src/lib/libc/net/getpeereid.3 b/src/lib/libc/net/getpeereid.3 new file mode 100644 index 0000000000..9c5742a245 --- /dev/null +++ b/src/lib/libc/net/getpeereid.3 | |||
| @@ -0,0 +1,121 @@ | |||
| 1 | .\" $OpenBSD: getpeereid.3,v 1.3 2013/06/05 03:39:23 tedu Exp $ | ||
| 2 | .\" | ||
| 3 | .\" Copyright (c) 1983, 1991, 1993 | ||
| 4 | .\" The Regents of the University of California. All rights reserved. | ||
| 5 | .\" | ||
| 6 | .\" Redistribution and use in source and binary forms, with or without | ||
| 7 | .\" modification, are permitted provided that the following conditions | ||
| 8 | .\" are met: | ||
| 9 | .\" 1. Redistributions of source code must retain the above copyright | ||
| 10 | .\" notice, this list of conditions and the following disclaimer. | ||
| 11 | .\" 2. Redistributions in binary form must reproduce the above copyright | ||
| 12 | .\" notice, this list of conditions and the following disclaimer in the | ||
| 13 | .\" documentation and/or other materials provided with the distribution. | ||
| 14 | .\" 3. Neither the name of the University nor the names of its contributors | ||
| 15 | .\" may be used to endorse or promote products derived from this software | ||
| 16 | .\" without specific prior written permission. | ||
| 17 | .\" | ||
| 18 | .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
| 19 | .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 20 | .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 21 | .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
| 22 | .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 23 | .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 24 | .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 25 | .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 26 | .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 27 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 28 | .\" SUCH DAMAGE. | ||
| 29 | .Dd $Mdocdate: June 5 2013 $ | ||
| 30 | .Dt GETPEEREID 3 | ||
| 31 | .Os | ||
| 32 | .Sh NAME | ||
| 33 | .Nm getpeereid | ||
| 34 | .Nd get effective user and group identification of locally-connected peer | ||
| 35 | .Sh SYNOPSIS | ||
| 36 | .In sys/types.h | ||
| 37 | .In sys/socket.h | ||
| 38 | .Ft int | ||
| 39 | .Fn getpeereid "int s" "uid_t *euid" "gid_t *egid" | ||
| 40 | .Sh DESCRIPTION | ||
| 41 | .Fn getpeereid | ||
| 42 | returns the effective user ID and group ID of the peer connected to | ||
| 43 | a | ||
| 44 | .Ux Ns -domain | ||
| 45 | socket (see | ||
| 46 | .Xr unix 4 ) . | ||
| 47 | The argument | ||
| 48 | .Fa s | ||
| 49 | must be of type | ||
| 50 | .Dv SOCK_STREAM | ||
| 51 | or | ||
| 52 | .Dv SOCK_SEQPACKET . | ||
| 53 | .Pp | ||
| 54 | One common use is for | ||
| 55 | .Ux Ns -domain | ||
| 56 | servers to determine the credentials of clients that have connected to it. | ||
| 57 | .Pp | ||
| 58 | .Fn getpeereid | ||
| 59 | takes three parameters: | ||
| 60 | .Bl -bullet | ||
| 61 | .It | ||
| 62 | .Fa s | ||
| 63 | contains the file descriptor of the socket whose peer credentials | ||
| 64 | should be looked up. | ||
| 65 | .It | ||
| 66 | .Fa euid | ||
| 67 | points to a | ||
| 68 | .Li uid_t | ||
| 69 | variable into which the effective user ID for the connected peer will | ||
| 70 | be stored. | ||
| 71 | .It | ||
| 72 | .Fa egid | ||
| 73 | points to a | ||
| 74 | .Li gid_t | ||
| 75 | variable into which the effective group ID for the connected peer will | ||
| 76 | be stored. | ||
| 77 | .El | ||
| 78 | .Sh RETURN VALUES | ||
| 79 | If the call succeeds, a 0 is returned and | ||
| 80 | .Fa euid | ||
| 81 | and | ||
| 82 | .Fa egid | ||
| 83 | are set to the effective user ID and group ID of the connected peer. | ||
| 84 | Otherwise, | ||
| 85 | .Va errno | ||
| 86 | is set and a value of \-1 is returned. | ||
| 87 | .Sh ERRORS | ||
| 88 | On failure, | ||
| 89 | .Va errno | ||
| 90 | is set to one of the following: | ||
| 91 | .Bl -tag -width Er | ||
| 92 | .It Bq Er EBADF | ||
| 93 | The argument | ||
| 94 | .Fa s | ||
| 95 | is not a valid descriptor. | ||
| 96 | .It Bq Er ENOTSOCK | ||
| 97 | The argument | ||
| 98 | .Fa s | ||
| 99 | is a file, not a socket. | ||
| 100 | .It Bq Er EOPNOTSUPP | ||
| 101 | The socket is not in the | ||
| 102 | .Ux Ns -domain . | ||
| 103 | .It Bq Er ENOTCONN | ||
| 104 | The socket is not connected. | ||
| 105 | .It Bq Er ENOBUFS | ||
| 106 | Insufficient resources were available in the system | ||
| 107 | to perform the operation. | ||
| 108 | .El | ||
| 109 | .Sh SEE ALSO | ||
| 110 | .Xr accept 2 , | ||
| 111 | .Xr bind 2 , | ||
| 112 | .Xr getpeername 2 , | ||
| 113 | .Xr getsockname 2 , | ||
| 114 | .Xr getsockopt 2 , | ||
| 115 | .Xr socket 2 , | ||
| 116 | .Xr unix 4 | ||
| 117 | .Sh HISTORY | ||
| 118 | The | ||
| 119 | .Fn getpeereid | ||
| 120 | function call appeared in | ||
| 121 | .Ox 3.0 . | ||
diff --git a/src/lib/libc/net/getpeereid.c b/src/lib/libc/net/getpeereid.c new file mode 100644 index 0000000000..208e541f17 --- /dev/null +++ b/src/lib/libc/net/getpeereid.c | |||
| @@ -0,0 +1,36 @@ | |||
| 1 | /* $OpenBSD: getpeereid.c,v 1.1 2010/07/01 19:15:30 deraadt Exp $ */ | ||
| 2 | |||
| 3 | /* | ||
| 4 | * Copyright (c) 2010 Theo de Raadt <deraadt@openbsd.org> | ||
| 5 | * | ||
| 6 | * Permission to use, copy, modify, and distribute this software for any | ||
| 7 | * purpose with or without fee is hereby granted, provided that the above | ||
| 8 | * copyright notice and this permission notice appear in all copies. | ||
| 9 | * | ||
| 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <sys/types.h> | ||
| 20 | #include <sys/socket.h> | ||
| 21 | |||
| 22 | int | ||
| 23 | getpeereid(int s, uid_t *euid, gid_t *egid) | ||
| 24 | { | ||
| 25 | struct sockpeercred creds; | ||
| 26 | socklen_t credslen = sizeof(creds); | ||
| 27 | int error; | ||
| 28 | |||
| 29 | error = getsockopt(s, SOL_SOCKET, SO_PEERCRED, | ||
| 30 | &creds, &credslen); | ||
| 31 | if (error) | ||
| 32 | return (error); | ||
| 33 | *euid = creds.uid; | ||
| 34 | *egid = creds.gid; | ||
| 35 | return (0); | ||
| 36 | } | ||
diff --git a/src/lib/libc/net/getproto.c b/src/lib/libc/net/getproto.c index 49c09b0806..07fa33288d 100644 --- a/src/lib/libc/net/getproto.c +++ b/src/lib/libc/net/getproto.c | |||
| @@ -1,5 +1,4 @@ | |||
| 1 | /* $NetBSD: getproto.c,v 1.4 1995/02/25 06:20:33 cgd Exp $ */ | 1 | /* $OpenBSD: getproto.c,v 1.7 2005/08/06 20:30:03 espie Exp $ */ |
| 2 | |||
| 3 | /* | 2 | /* |
| 4 | * Copyright (c) 1983, 1993 | 3 | * Copyright (c) 1983, 1993 |
| 5 | * The Regents of the University of California. All rights reserved. | 4 | * The Regents of the University of California. All rights reserved. |
| @@ -12,11 +11,7 @@ | |||
| 12 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
| 13 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the |
| 14 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. |
| 15 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. Neither the name of the University nor the names of its contributors |
| 16 | * must display the following acknowledgement: | ||
| 17 | * This product includes software developed by the University of | ||
| 18 | * California, Berkeley and its contributors. | ||
| 19 | * 4. Neither the name of the University nor the names of its contributors | ||
| 20 | * may be used to endorse or promote products derived from this software | 15 | * may be used to endorse or promote products derived from this software |
| 21 | * without specific prior written permission. | 16 | * without specific prior written permission. |
| 22 | * | 17 | * |
| @@ -33,29 +28,32 @@ | |||
| 33 | * SUCH DAMAGE. | 28 | * SUCH DAMAGE. |
| 34 | */ | 29 | */ |
| 35 | 30 | ||
| 36 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 37 | #if 0 | ||
| 38 | static char sccsid[] = "@(#)getproto.c 8.1 (Berkeley) 6/4/93"; | ||
| 39 | #else | ||
| 40 | static char rcsid[] = "$NetBSD: getproto.c,v 1.4 1995/02/25 06:20:33 cgd Exp $"; | ||
| 41 | #endif | ||
| 42 | #endif /* LIBC_SCCS and not lint */ | ||
| 43 | |||
| 44 | #include <netdb.h> | 31 | #include <netdb.h> |
| 32 | #include <stdio.h> | ||
| 45 | 33 | ||
| 46 | extern int _proto_stayopen; | 34 | int |
| 35 | getprotobynumber_r(int num, struct protoent *pe, struct protoent_data *pd) | ||
| 36 | { | ||
| 37 | int error; | ||
| 38 | |||
| 39 | setprotoent_r(pd->stayopen, pd); | ||
| 40 | while ((error = getprotoent_r(pe, pd)) == 0) | ||
| 41 | if (pe->p_proto == num) | ||
| 42 | break; | ||
| 43 | if (!pd->stayopen && pd->fp != NULL) { | ||
| 44 | (void)fclose(pd->fp); | ||
| 45 | pd->fp = NULL; | ||
| 46 | } | ||
| 47 | return (error); | ||
| 48 | } | ||
| 47 | 49 | ||
| 48 | struct protoent * | 50 | struct protoent * |
| 49 | getprotobynumber(proto) | 51 | getprotobynumber(int num) |
| 50 | register int proto; | ||
| 51 | { | 52 | { |
| 52 | register struct protoent *p; | 53 | extern struct protoent_data _protoent_data; |
| 54 | static struct protoent proto; | ||
| 53 | 55 | ||
| 54 | setprotoent(_proto_stayopen); | 56 | if (getprotobynumber_r(num, &proto, &_protoent_data) != 0) |
| 55 | while (p = getprotoent()) | 57 | return (NULL); |
| 56 | if (p->p_proto == proto) | 58 | return (&proto); |
| 57 | break; | ||
| 58 | if (!_proto_stayopen) | ||
| 59 | endprotoent(); | ||
| 60 | return (p); | ||
| 61 | } | 59 | } |
diff --git a/src/lib/libc/net/getprotoent.3 b/src/lib/libc/net/getprotoent.3 index 8d607199ef..cc2c69836a 100644 --- a/src/lib/libc/net/getprotoent.3 +++ b/src/lib/libc/net/getprotoent.3 | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | .\" $NetBSD: getprotoent.3,v 1.3 1995/02/25 06:20:34 cgd Exp $ | 1 | .\" $OpenBSD: getprotoent.3,v 1.18 2013/06/05 03:39:23 tedu Exp $ |
| 2 | .\" | 2 | .\" |
| 3 | .\" Copyright (c) 1983, 1991, 1993 | 3 | .\" Copyright (c) 1983, 1991, 1993 |
| 4 | .\" The Regents of the University of California. All rights reserved. | 4 | .\" The Regents of the University of California. All rights reserved. |
| @@ -11,11 +11,7 @@ | |||
| 11 | .\" 2. Redistributions in binary form must reproduce the above copyright | 11 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 12 | .\" notice, this list of conditions and the following disclaimer in the | 12 | .\" notice, this list of conditions and the following disclaimer in the |
| 13 | .\" documentation and/or other materials provided with the distribution. | 13 | .\" documentation and/or other materials provided with the distribution. |
| 14 | .\" 3. All advertising materials mentioning features or use of this software | 14 | .\" 3. Neither the name of the University nor the names of its contributors |
| 15 | .\" must display the following acknowledgement: | ||
| 16 | .\" This product includes software developed by the University of | ||
| 17 | .\" California, Berkeley and its contributors. | ||
| 18 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 19 | .\" may be used to endorse or promote products derived from this software | 15 | .\" may be used to endorse or promote products derived from this software |
| 20 | .\" without specific prior written permission. | 16 | .\" without specific prior written permission. |
| 21 | .\" | 17 | .\" |
| @@ -31,39 +27,51 @@ | |||
| 31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 27 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 32 | .\" SUCH DAMAGE. | 28 | .\" SUCH DAMAGE. |
| 33 | .\" | 29 | .\" |
| 34 | .\" @(#)getprotoent.3 8.1 (Berkeley) 6/4/93 | 30 | .Dd $Mdocdate: June 5 2013 $ |
| 35 | .\" | ||
| 36 | .Dd June 4, 1993 | ||
| 37 | .Dt GETPROTOENT 3 | 31 | .Dt GETPROTOENT 3 |
| 38 | .Os BSD 4.2 | 32 | .Os |
| 39 | .Sh NAME | 33 | .Sh NAME |
| 40 | .Nm getprotoent , | 34 | .Nm getprotoent , |
| 35 | .Nm getprotoent_r , | ||
| 41 | .Nm getprotobynumber , | 36 | .Nm getprotobynumber , |
| 37 | .Nm getprotobynumber_r , | ||
| 42 | .Nm getprotobyname , | 38 | .Nm getprotobyname , |
| 39 | .Nm getprotobyname_r , | ||
| 43 | .Nm setprotoent , | 40 | .Nm setprotoent , |
| 44 | .Nm endprotoent | 41 | .Nm setprotoent_r , |
| 42 | .Nm endprotoent , | ||
| 43 | .Nm endprotoent_r | ||
| 45 | .Nd get protocol entry | 44 | .Nd get protocol entry |
| 46 | .Sh SYNOPSIS | 45 | .Sh SYNOPSIS |
| 47 | .Fd #include <netdb.h> | 46 | .In netdb.h |
| 48 | .Ft struct protoent * | 47 | .Ft struct protoent * |
| 49 | .Fn getprotoent | 48 | .Fn getprotoent "void" |
| 49 | .Ft int | ||
| 50 | .Fn getprotoent_r "struct protoent *protoent" "struct protoent_data *protoent_data" | ||
| 50 | .Ft struct protoent * | 51 | .Ft struct protoent * |
| 51 | .Fn getprotobyname "char *name" | 52 | .Fn getprotobyname "const char *name" |
| 53 | .Ft int | ||
| 54 | .Fn getprotobyname_r "const char *name" "struct protoent *protoent" "struct protoent_data *protoent_data" | ||
| 52 | .Ft struct protoent * | 55 | .Ft struct protoent * |
| 53 | .Fn getprotobynumber "int proto" | 56 | .Fn getprotobynumber "int proto" |
| 57 | .Ft int | ||
| 58 | .Fn getprotobynumber_r "int proto" "struct protoent *protoent" "struct protoent_data *protoent_data" | ||
| 59 | .Ft void | ||
| 54 | .Fn setprotoent "int stayopen" | 60 | .Fn setprotoent "int stayopen" |
| 55 | .Fn endprotoent | 61 | .Ft void |
| 62 | .Fn setprotoent_r "int stayopen" "struct protoent_data *protoent_data" | ||
| 63 | .Ft void | ||
| 64 | .Fn endprotoent "void" | ||
| 65 | .Ft void | ||
| 66 | .Fn endprotoent_r "struct protoent_data *protoent_data" | ||
| 56 | .Sh DESCRIPTION | 67 | .Sh DESCRIPTION |
| 57 | The | 68 | The |
| 58 | .Fn getprotoent , | 69 | .Fn getprotoent , |
| 59 | .Fn getprotobyname , | 70 | .Fn getprotobyname , |
| 60 | and | 71 | and |
| 61 | .Fn getprotobynumber | 72 | .Fn getprotobynumber |
| 62 | functions | 73 | functions each return a pointer to an object with the following structure |
| 63 | each return a pointer to an object with the | 74 | containing the broken-out fields of a line in the network protocol database, |
| 64 | following structure | ||
| 65 | containing the broken-out | ||
| 66 | fields of a line in the network protocol data base, | ||
| 67 | .Pa /etc/protocols . | 75 | .Pa /etc/protocols . |
| 68 | .Bd -literal -offset indent | 76 | .Bd -literal -offset indent |
| 69 | .Pp | 77 | .Pp |
| @@ -79,55 +87,106 @@ The members of this structure are: | |||
| 79 | .It Fa p_name | 87 | .It Fa p_name |
| 80 | The official name of the protocol. | 88 | The official name of the protocol. |
| 81 | .It Fa p_aliases | 89 | .It Fa p_aliases |
| 82 | A zero terminated list of alternate names for the protocol. | 90 | A null-terminated list of alternate names for the protocol. |
| 83 | .It Fa p_proto | 91 | .It Fa p_proto |
| 84 | The protocol number. | 92 | The protocol number. |
| 85 | .El | 93 | .El |
| 86 | .Pp | 94 | .Pp |
| 87 | The | 95 | The |
| 88 | .Fn getprotoent | 96 | .Fn getprotoent |
| 89 | function | 97 | function reads the next line of the file, opening the file if necessary. |
| 90 | reads the next line of the file, opening the file if necessary. | ||
| 91 | .Pp | 98 | .Pp |
| 92 | The | 99 | The |
| 93 | .Fn setprotoent | 100 | .Fn setprotoent |
| 94 | function | 101 | function opens and rewinds the file. |
| 95 | opens and rewinds the file. If the | 102 | If the |
| 96 | .Fa stayopen | 103 | .Fa stayopen |
| 97 | flag is non-zero, | 104 | flag is non-zero, |
| 98 | the net data base will not be closed after each call to | 105 | the protocol database will not be closed after each call to |
| 99 | .Fn getprotobyname | 106 | .Fn getprotobyname |
| 100 | or | 107 | or |
| 101 | .Fn getprotobynumber . | 108 | .Fn getprotobynumber . |
| 102 | .Pp | 109 | .Pp |
| 103 | The | 110 | The |
| 104 | .Fn endprotoent | 111 | .Fn endprotoent |
| 105 | function | 112 | function closes the file. |
| 106 | closes the file. | ||
| 107 | .Pp | 113 | .Pp |
| 108 | The | 114 | The |
| 109 | .Fn getprotobyname | 115 | .Fn getprotobyname |
| 110 | function | ||
| 111 | and | 116 | and |
| 112 | .Fn getprotobynumber | 117 | .Fn getprotobynumber |
| 113 | sequentially search from the beginning | 118 | functions sequentially search from the beginning of the file until a |
| 114 | of the file until a matching | 119 | matching protocol name or protocol number is found, or until |
| 115 | protocol name or | ||
| 116 | protocol number is found, | ||
| 117 | or until | ||
| 118 | .Dv EOF | 120 | .Dv EOF |
| 119 | is encountered. | 121 | is encountered. |
| 122 | .Pp | ||
| 123 | The | ||
| 124 | .Fn getprotoent_r , | ||
| 125 | .Fn getprotobyport_r , | ||
| 126 | .Fn getprotobyname_r , | ||
| 127 | .Fn setprotoent_r , | ||
| 128 | and | ||
| 129 | .Fn endprotoent_r | ||
| 130 | functions are reentrant versions of the above functions that take a | ||
| 131 | pointer to a | ||
| 132 | .Vt protoent_data | ||
| 133 | structure which is used to store state information. | ||
| 134 | The structure must be zero-filled before it is used | ||
| 135 | and should be considered opaque for the sake of portability. | ||
| 136 | .Pp | ||
| 137 | The | ||
| 138 | .Fn getprotoent_r , | ||
| 139 | .Fn getprotobyport_r , | ||
| 140 | and | ||
| 141 | .Fn getprotobyname_r | ||
| 142 | functions | ||
| 143 | also take a pointer to a | ||
| 144 | .Vt protoent | ||
| 145 | structure which is used to store the results of the database lookup. | ||
| 120 | .Sh RETURN VALUES | 146 | .Sh RETURN VALUES |
| 121 | Null pointer | 147 | The |
| 122 | (0) returned on | 148 | .Fn getprotoent , |
| 123 | .Dv EOF | 149 | .Fn getprotobyport , |
| 124 | or error. | 150 | and |
| 151 | .Fn getprotobyname | ||
| 152 | functions return a pointer to a | ||
| 153 | .Vt protoent | ||
| 154 | structure on success or a null pointer if end-of-file | ||
| 155 | is reached or an error occurs. | ||
| 156 | .Pp | ||
| 157 | The | ||
| 158 | .Fn getprotoent_r , | ||
| 159 | .Fn getprotobyport_r , | ||
| 160 | and | ||
| 161 | .Fn getprotobyname_r | ||
| 162 | functions return 0 on success or \-1 if end-of-file | ||
| 163 | is reached or an error occurs. | ||
| 125 | .Sh FILES | 164 | .Sh FILES |
| 126 | .Bl -tag -width /etc/protocols -compact | 165 | .Bl -tag -width /etc/protocols -compact |
| 127 | .It Pa /etc/protocols | 166 | .It Pa /etc/protocols |
| 128 | .El | 167 | .El |
| 129 | .Sh SEE ALSO | 168 | .Sh SEE ALSO |
| 130 | .Xr protocols 5 | 169 | .Xr protocols 5 |
| 170 | .Sh STANDARDS | ||
| 171 | The | ||
| 172 | .Fn getprotoent , | ||
| 173 | .Fn getprotobynumber , | ||
| 174 | .Fn getprotobyname , | ||
| 175 | .Fn setprotoent , | ||
| 176 | and | ||
| 177 | .Fn endprotoent | ||
| 178 | functions conform to | ||
| 179 | .St -p1003.1-2004 . | ||
| 180 | .Pp | ||
| 181 | The | ||
| 182 | .Fn getprotoent_r , | ||
| 183 | .Fn getprotobyport_r , | ||
| 184 | .Fn getprotobyname_r , | ||
| 185 | .Fn setprotoent_r , | ||
| 186 | and | ||
| 187 | .Fn endprotoent_r | ||
| 188 | functions are not currently standardized. | ||
| 189 | This implementation follows the API used by HP, IBM, and Digital. | ||
| 131 | .Sh HISTORY | 190 | .Sh HISTORY |
| 132 | The | 191 | The |
| 133 | .Fn getprotoent , | 192 | .Fn getprotoent , |
| @@ -136,11 +195,19 @@ The | |||
| 136 | .Fn setprotoent , | 195 | .Fn setprotoent , |
| 137 | and | 196 | and |
| 138 | .Fn endprotoent | 197 | .Fn endprotoent |
| 139 | functions appeared in | 198 | functions appeared in |
| 140 | .Bx 4.2 . | 199 | .Bx 4.2 . |
| 200 | .Pp | ||
| 201 | The | ||
| 202 | .Fn getprotoent_r , | ||
| 203 | .Fn getprotobyport_r , | ||
| 204 | .Fn getprotobyname_r , | ||
| 205 | .Fn setprotoent_r , | ||
| 206 | and | ||
| 207 | .Fn endprotoent_r | ||
| 208 | functions appeared in | ||
| 209 | .Ox 3.7 . | ||
| 141 | .Sh BUGS | 210 | .Sh BUGS |
| 142 | These functions use a static data space; | 211 | The non-reentrant functions use a static data space; if the data is needed |
| 143 | if the data is needed for future use, it should be | 212 | for future use, it should be copied before any subsequent calls overwrite it. |
| 144 | copied before any subsequent calls overwrite it. | 213 | Only the Internet protocols are currently understood. |
| 145 | Only the Internet | ||
| 146 | protocols are currently understood. | ||
diff --git a/src/lib/libc/net/getprotoent.c b/src/lib/libc/net/getprotoent.c index 1179b9029b..f0705e0765 100644 --- a/src/lib/libc/net/getprotoent.c +++ b/src/lib/libc/net/getprotoent.c | |||
| @@ -1,5 +1,4 @@ | |||
| 1 | /* $NetBSD: getprotoent.c,v 1.4 1995/02/25 06:20:35 cgd Exp $ */ | 1 | /* $OpenBSD: getprotoent.c,v 1.10 2007/09/02 15:19:17 deraadt Exp $ */ |
| 2 | |||
| 3 | /* | 2 | /* |
| 4 | * Copyright (c) 1983, 1993 | 3 | * Copyright (c) 1983, 1993 |
| 5 | * The Regents of the University of California. All rights reserved. | 4 | * The Regents of the University of California. All rights reserved. |
| @@ -12,11 +11,7 @@ | |||
| 12 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
| 13 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the |
| 14 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. |
| 15 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. Neither the name of the University nor the names of its contributors |
| 16 | * must display the following acknowledgement: | ||
| 17 | * This product includes software developed by the University of | ||
| 18 | * California, Berkeley and its contributors. | ||
| 19 | * 4. Neither the name of the University nor the names of its contributors | ||
| 20 | * may be used to endorse or promote products derived from this software | 15 | * may be used to endorse or promote products derived from this software |
| 21 | * without specific prior written permission. | 16 | * without specific prior written permission. |
| 22 | * | 17 | * |
| @@ -33,69 +28,66 @@ | |||
| 33 | * SUCH DAMAGE. | 28 | * SUCH DAMAGE. |
| 34 | */ | 29 | */ |
| 35 | 30 | ||
| 36 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 37 | #if 0 | ||
| 38 | static char sccsid[] = "@(#)getprotoent.c 8.1 (Berkeley) 6/4/93"; | ||
| 39 | #else | ||
| 40 | static char rcsid[] = "$NetBSD: getprotoent.c,v 1.4 1995/02/25 06:20:35 cgd Exp $"; | ||
| 41 | #endif | ||
| 42 | #endif /* LIBC_SCCS and not lint */ | ||
| 43 | |||
| 44 | #include <sys/types.h> | 31 | #include <sys/types.h> |
| 45 | #include <sys/socket.h> | 32 | #include <sys/socket.h> |
| 33 | |||
| 34 | #include <errno.h> | ||
| 35 | #include <limits.h> | ||
| 46 | #include <netdb.h> | 36 | #include <netdb.h> |
| 47 | #include <stdio.h> | 37 | #include <stdio.h> |
| 48 | #include <stdlib.h> | 38 | #include <stdlib.h> |
| 49 | #include <string.h> | 39 | #include <string.h> |
| 50 | 40 | ||
| 51 | #define MAXALIASES 35 | ||
| 52 | |||
| 53 | static FILE *protof = NULL; | ||
| 54 | static char line[BUFSIZ+1]; | ||
| 55 | static struct protoent proto; | ||
| 56 | static char *proto_aliases[MAXALIASES]; | ||
| 57 | int _proto_stayopen; | ||
| 58 | |||
| 59 | void | 41 | void |
| 60 | setprotoent(f) | 42 | setprotoent_r(int f, struct protoent_data *pd) |
| 61 | int f; | ||
| 62 | { | 43 | { |
| 63 | if (protof == NULL) | 44 | if (pd->fp == NULL) |
| 64 | protof = fopen(_PATH_PROTOCOLS, "r" ); | 45 | pd->fp = fopen(_PATH_PROTOCOLS, "r" ); |
| 65 | else | 46 | else |
| 66 | rewind(protof); | 47 | rewind(pd->fp); |
| 67 | _proto_stayopen |= f; | 48 | pd->stayopen |= f; |
| 68 | } | 49 | } |
| 69 | 50 | ||
| 70 | void | 51 | void |
| 71 | endprotoent() | 52 | endprotoent_r(struct protoent_data *pd) |
| 72 | { | 53 | { |
| 73 | if (protof) { | 54 | if (pd->fp) { |
| 74 | fclose(protof); | 55 | fclose(pd->fp); |
| 75 | protof = NULL; | 56 | pd->fp = NULL; |
| 76 | } | 57 | } |
| 77 | _proto_stayopen = 0; | 58 | free(pd->aliases); |
| 59 | pd->aliases = NULL; | ||
| 60 | pd->maxaliases = 0; | ||
| 61 | free(pd->line); | ||
| 62 | pd->line = NULL; | ||
| 63 | pd->stayopen = 0; | ||
| 78 | } | 64 | } |
| 79 | 65 | ||
| 80 | struct protoent * | 66 | int |
| 81 | getprotoent() | 67 | getprotoent_r(struct protoent *pe, struct protoent_data *pd) |
| 82 | { | 68 | { |
| 83 | char *p; | 69 | char *p, *cp, **q, *endp; |
| 84 | register char *cp, **q; | 70 | size_t len; |
| 71 | long l; | ||
| 72 | int serrno; | ||
| 85 | 73 | ||
| 86 | if (protof == NULL && (protof = fopen(_PATH_PROTOCOLS, "r" )) == NULL) | 74 | if (pd->fp == NULL && (pd->fp = fopen(_PATH_PROTOCOLS, "r" )) == NULL) |
| 87 | return (NULL); | 75 | return (-1); |
| 88 | again: | 76 | again: |
| 89 | if ((p = fgets(line, BUFSIZ, protof)) == NULL) | 77 | if ((p = fgetln(pd->fp, &len)) == NULL) |
| 90 | return (NULL); | 78 | return (-1); |
| 91 | if (*p == '#') | 79 | if (len == 0 || *p == '#' || *p == '\n') |
| 92 | goto again; | 80 | goto again; |
| 93 | cp = strpbrk(p, "#\n"); | 81 | if (p[len-1] == '\n') |
| 82 | len--; | ||
| 83 | if ((cp = memchr(p, '#', len)) != NULL) | ||
| 84 | len = cp - p; | ||
| 85 | cp = realloc(pd->line, len + 1); | ||
| 94 | if (cp == NULL) | 86 | if (cp == NULL) |
| 95 | goto again; | 87 | return (-1); |
| 96 | *cp = '\0'; | 88 | pd->line = pe->p_name = memcpy(cp, p, len); |
| 97 | proto.p_name = p; | 89 | cp[len] = '\0'; |
| 98 | cp = strpbrk(p, " \t"); | 90 | cp = strpbrk(cp, " \t"); |
| 99 | if (cp == NULL) | 91 | if (cp == NULL) |
| 100 | goto again; | 92 | goto again; |
| 101 | *cp++ = '\0'; | 93 | *cp++ = '\0'; |
| @@ -104,8 +96,21 @@ again: | |||
| 104 | p = strpbrk(cp, " \t"); | 96 | p = strpbrk(cp, " \t"); |
| 105 | if (p != NULL) | 97 | if (p != NULL) |
| 106 | *p++ = '\0'; | 98 | *p++ = '\0'; |
| 107 | proto.p_proto = atoi(cp); | 99 | l = strtol(cp, &endp, 10); |
| 108 | q = proto.p_aliases = proto_aliases; | 100 | if (endp == cp || *endp != '\0' || l < 0 || l >= INT_MAX) |
| 101 | goto again; | ||
| 102 | pe->p_proto = l; | ||
| 103 | if (pd->aliases == NULL) { | ||
| 104 | pd->maxaliases = 5; | ||
| 105 | pd->aliases = calloc(pd->maxaliases, sizeof(char *)); | ||
| 106 | if (pd->aliases == NULL) { | ||
| 107 | serrno = errno; | ||
| 108 | endprotoent_r(pd); | ||
| 109 | errno = serrno; | ||
| 110 | return (-1); | ||
| 111 | } | ||
| 112 | } | ||
| 113 | q = pe->p_aliases = pd->aliases; | ||
| 109 | if (p != NULL) { | 114 | if (p != NULL) { |
| 110 | cp = p; | 115 | cp = p; |
| 111 | while (cp && *cp) { | 116 | while (cp && *cp) { |
| @@ -113,13 +118,49 @@ again: | |||
| 113 | cp++; | 118 | cp++; |
| 114 | continue; | 119 | continue; |
| 115 | } | 120 | } |
| 116 | if (q < &proto_aliases[MAXALIASES - 1]) | 121 | if (q == &pe->p_aliases[pd->maxaliases - 1]) { |
| 117 | *q++ = cp; | 122 | p = realloc(pe->p_aliases, |
| 123 | 2 * pd->maxaliases * sizeof(char *)); | ||
| 124 | if (p == NULL) { | ||
| 125 | serrno = errno; | ||
| 126 | endprotoent_r(pd); | ||
| 127 | errno = serrno; | ||
| 128 | return (-1); | ||
| 129 | } | ||
| 130 | pd->maxaliases *= 2; | ||
| 131 | q = (char **)p + (q - pe->p_aliases); | ||
| 132 | pe->p_aliases = pd->aliases = (char **)p; | ||
| 133 | } | ||
| 134 | *q++ = cp; | ||
| 118 | cp = strpbrk(cp, " \t"); | 135 | cp = strpbrk(cp, " \t"); |
| 119 | if (cp != NULL) | 136 | if (cp != NULL) |
| 120 | *cp++ = '\0'; | 137 | *cp++ = '\0'; |
| 121 | } | 138 | } |
| 122 | } | 139 | } |
| 123 | *q = NULL; | 140 | *q = NULL; |
| 141 | return (0); | ||
| 142 | } | ||
| 143 | |||
| 144 | struct protoent_data _protoent_data; /* shared with getproto{,name}.c */ | ||
| 145 | |||
| 146 | void | ||
| 147 | setprotoent(int f) | ||
| 148 | { | ||
| 149 | setprotoent_r(f, &_protoent_data); | ||
| 150 | } | ||
| 151 | |||
| 152 | void | ||
| 153 | endprotoent(void) | ||
| 154 | { | ||
| 155 | endprotoent_r(&_protoent_data); | ||
| 156 | } | ||
| 157 | |||
| 158 | struct protoent * | ||
| 159 | getprotoent(void) | ||
| 160 | { | ||
| 161 | static struct protoent proto; | ||
| 162 | |||
| 163 | if (getprotoent_r(&proto, &_protoent_data) != 0) | ||
| 164 | return (NULL); | ||
| 124 | return (&proto); | 165 | return (&proto); |
| 125 | } | 166 | } |
diff --git a/src/lib/libc/net/getprotoname.c b/src/lib/libc/net/getprotoname.c index 4f8cf21c3f..749b6b3f13 100644 --- a/src/lib/libc/net/getprotoname.c +++ b/src/lib/libc/net/getprotoname.c | |||
| @@ -1,5 +1,4 @@ | |||
| 1 | /* $NetBSD: getprotoname.c,v 1.4 1995/02/25 06:20:36 cgd Exp $ */ | 1 | /* $OpenBSD: getprotoname.c,v 1.7 2005/08/06 20:30:03 espie Exp $ */ |
| 2 | |||
| 3 | /* | 2 | /* |
| 4 | * Copyright (c) 1983, 1993 | 3 | * Copyright (c) 1983, 1993 |
| 5 | * The Regents of the University of California. All rights reserved. | 4 | * The Regents of the University of California. All rights reserved. |
| @@ -12,11 +11,7 @@ | |||
| 12 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
| 13 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the |
| 14 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. |
| 15 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. Neither the name of the University nor the names of its contributors |
| 16 | * must display the following acknowledgement: | ||
| 17 | * This product includes software developed by the University of | ||
| 18 | * California, Berkeley and its contributors. | ||
| 19 | * 4. Neither the name of the University nor the names of its contributors | ||
| 20 | * may be used to endorse or promote products derived from this software | 15 | * may be used to endorse or promote products derived from this software |
| 21 | * without specific prior written permission. | 16 | * without specific prior written permission. |
| 22 | * | 17 | * |
| @@ -33,36 +28,40 @@ | |||
| 33 | * SUCH DAMAGE. | 28 | * SUCH DAMAGE. |
| 34 | */ | 29 | */ |
| 35 | 30 | ||
| 36 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 37 | #if 0 | ||
| 38 | static char sccsid[] = "@(#)getprotoname.c 8.1 (Berkeley) 6/4/93"; | ||
| 39 | #else | ||
| 40 | static char rcsid[] = "$NetBSD: getprotoname.c,v 1.4 1995/02/25 06:20:36 cgd Exp $"; | ||
| 41 | #endif | ||
| 42 | #endif /* LIBC_SCCS and not lint */ | ||
| 43 | |||
| 44 | #include <netdb.h> | 31 | #include <netdb.h> |
| 32 | #include <stdio.h> | ||
| 45 | #include <string.h> | 33 | #include <string.h> |
| 46 | 34 | ||
| 47 | extern int _proto_stayopen; | 35 | int |
| 48 | 36 | getprotobyname_r(const char *name, struct protoent *pe, | |
| 49 | struct protoent * | 37 | struct protoent_data *pd) |
| 50 | getprotobyname(name) | ||
| 51 | register const char *name; | ||
| 52 | { | 38 | { |
| 53 | register struct protoent *p; | 39 | char **cp; |
| 54 | register char **cp; | 40 | int error; |
| 55 | 41 | ||
| 56 | setprotoent(_proto_stayopen); | 42 | setprotoent_r(pd->stayopen, pd); |
| 57 | while (p = getprotoent()) { | 43 | while ((error = getprotoent_r(pe, pd)) == 0) { |
| 58 | if (strcmp(p->p_name, name) == 0) | 44 | if (strcmp(pe->p_name, name) == 0) |
| 59 | break; | 45 | break; |
| 60 | for (cp = p->p_aliases; *cp != 0; cp++) | 46 | for (cp = pe->p_aliases; *cp != 0; cp++) |
| 61 | if (strcmp(*cp, name) == 0) | 47 | if (strcmp(*cp, name) == 0) |
| 62 | goto found; | 48 | goto found; |
| 63 | } | 49 | } |
| 64 | found: | 50 | found: |
| 65 | if (!_proto_stayopen) | 51 | if (!pd->stayopen && pd->fp != NULL) { |
| 66 | endprotoent(); | 52 | fclose(pd->fp); |
| 67 | return (p); | 53 | pd->fp = NULL; |
| 54 | } | ||
| 55 | return (error); | ||
| 56 | } | ||
| 57 | |||
| 58 | struct protoent * | ||
| 59 | getprotobyname(const char *name) | ||
| 60 | { | ||
| 61 | extern struct protoent_data _protoent_data; | ||
| 62 | static struct protoent proto; | ||
| 63 | |||
| 64 | if (getprotobyname_r(name, &proto, &_protoent_data) != 0) | ||
| 65 | return (NULL); | ||
| 66 | return (&proto); | ||
| 68 | } | 67 | } |
diff --git a/src/lib/libc/net/getrrsetbyname.3 b/src/lib/libc/net/getrrsetbyname.3 new file mode 100644 index 0000000000..677b2a4c2e --- /dev/null +++ b/src/lib/libc/net/getrrsetbyname.3 | |||
| @@ -0,0 +1,165 @@ | |||
| 1 | .\" $OpenBSD: getrrsetbyname.3,v 1.18 2013/07/16 15:21:11 schwarze Exp $ | ||
| 2 | .\" | ||
| 3 | .\" Copyright (C) 2000, 2001 Internet Software Consortium. | ||
| 4 | .\" | ||
| 5 | .\" Permission to use, copy, modify, and distribute this software for any | ||
| 6 | .\" purpose with or without fee is hereby granted, provided that the above | ||
| 7 | .\" copyright notice and this permission notice appear in all copies. | ||
| 8 | .\" | ||
| 9 | .\" THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM | ||
| 10 | .\" DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL | ||
| 11 | .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL | ||
| 12 | .\" INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, | ||
| 13 | .\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING | ||
| 14 | .\" FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, | ||
| 15 | .\" NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION | ||
| 16 | .\" WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 17 | .\" | ||
| 18 | .Dd $Mdocdate: July 16 2013 $ | ||
| 19 | .Dt GETRRSETBYNAME 3 | ||
| 20 | .Os | ||
| 21 | .Sh NAME | ||
| 22 | .Nm freerrset , | ||
| 23 | .Nm getrrsetbyname | ||
| 24 | .Nd retrieve DNS records | ||
| 25 | .Sh SYNOPSIS | ||
| 26 | .In netdb.h | ||
| 27 | .Ft int | ||
| 28 | .Fn getrrsetbyname "const char *hostname" "unsigned int rdclass" \ | ||
| 29 | "unsigned int rdtype" "unsigned int flags" "struct rrsetinfo **res" | ||
| 30 | .Ft void | ||
| 31 | .Fn freerrset "struct rrsetinfo *rrset" | ||
| 32 | .Sh DESCRIPTION | ||
| 33 | .Fn getrrsetbyname | ||
| 34 | gets a set of resource records associated with a | ||
| 35 | .Fa hostname , | ||
| 36 | .Fa rdclass , | ||
| 37 | and | ||
| 38 | .Fa rdtype . | ||
| 39 | .Fa hostname | ||
| 40 | is a pointer to a NUL-terminated string. | ||
| 41 | The | ||
| 42 | .Fa flags | ||
| 43 | field is currently unused and must be zero. | ||
| 44 | .Pp | ||
| 45 | After a successful call to | ||
| 46 | .Fn getrrsetbyname , | ||
| 47 | .Fa *res | ||
| 48 | is a pointer to an | ||
| 49 | .Li rrsetinfo | ||
| 50 | structure, containing a list of one or more | ||
| 51 | .Li rdatainfo | ||
| 52 | structures containing resource records and potentially another list of | ||
| 53 | .Li rdatainfo | ||
| 54 | structures containing SIG resource records associated with those records. | ||
| 55 | The members | ||
| 56 | .Li rri_rdclass | ||
| 57 | and | ||
| 58 | .Li rri_rdtype | ||
| 59 | are copied from the parameters. | ||
| 60 | .Li rri_ttl | ||
| 61 | and | ||
| 62 | .Li rri_name | ||
| 63 | are properties of the obtained rrset. | ||
| 64 | The resource records contained in | ||
| 65 | .Li rri_rdatas | ||
| 66 | and | ||
| 67 | .Li rri_sigs | ||
| 68 | are in uncompressed DNS wire format. | ||
| 69 | Properties of the rdataset are represented in the | ||
| 70 | .Li rri_flags | ||
| 71 | bitfield. | ||
| 72 | If the | ||
| 73 | .Dv RRSET_VALIDATED | ||
| 74 | bit is set, the data has been DNSSEC | ||
| 75 | validated and the signatures verified. | ||
| 76 | .Pp | ||
| 77 | The following structures are used: | ||
| 78 | .Bd -literal -offset indent | ||
| 79 | struct rdatainfo { | ||
| 80 | unsigned int rdi_length; /* length of data */ | ||
| 81 | unsigned char *rdi_data; /* record data */ | ||
| 82 | }; | ||
| 83 | |||
| 84 | struct rrsetinfo { | ||
| 85 | unsigned int rri_flags; /* RRSET_VALIDATED ... */ | ||
| 86 | unsigned int rri_rdclass; /* class number */ | ||
| 87 | unsigned int rri_rdtype; /* RR type number */ | ||
| 88 | unsigned int rri_ttl; /* time to live */ | ||
| 89 | unsigned int rri_nrdatas; /* size of rdatas array */ | ||
| 90 | unsigned int rri_nsigs; /* size of sigs array */ | ||
| 91 | char *rri_name; /* canonical name */ | ||
| 92 | struct rdatainfo *rri_rdatas; /* individual records */ | ||
| 93 | struct rdatainfo *rri_sigs; /* individual signatures */ | ||
| 94 | }; | ||
| 95 | .Ed | ||
| 96 | .Pp | ||
| 97 | All of the information returned by | ||
| 98 | .Fn getrrsetbyname | ||
| 99 | is dynamically allocated: the | ||
| 100 | .Li rrsetinfo | ||
| 101 | and | ||
| 102 | .Li rdatainfo | ||
| 103 | structures, | ||
| 104 | and the canonical host name strings pointed to by the | ||
| 105 | .Li rrsetinfo | ||
| 106 | structure. | ||
| 107 | Memory allocated for the dynamically allocated structures created by | ||
| 108 | a successful call to | ||
| 109 | .Fn getrrsetbyname | ||
| 110 | is released by | ||
| 111 | .Fn freerrset . | ||
| 112 | .Li rrset | ||
| 113 | is a pointer to a | ||
| 114 | .Li struct rrsetinfo | ||
| 115 | created by a call to | ||
| 116 | .Fn getrrsetbyname . | ||
| 117 | .Pp | ||
| 118 | If the EDNS0 option is activated in | ||
| 119 | .Xr resolv.conf 5 , | ||
| 120 | .Fn getrrsetbyname | ||
| 121 | will request DNSSEC authentication using the EDNS0 DNSSEC OK (DO) bit. | ||
| 122 | .Sh RETURN VALUES | ||
| 123 | .Fn getrrsetbyname | ||
| 124 | returns zero on success, and one of the following error | ||
| 125 | codes if an error occurred: | ||
| 126 | .Bl -tag -width ERRSET_NOMEMORY | ||
| 127 | .It Bq Er ERRSET_NONAME | ||
| 128 | The name does not exist. | ||
| 129 | .It Bq Er ERRSET_NODATA | ||
| 130 | The name exists, but does not have data of the desired type. | ||
| 131 | .It Bq Er ERRSET_NOMEMORY | ||
| 132 | Memory could not be allocated. | ||
| 133 | .It Bq Er ERRSET_INVAL | ||
| 134 | A parameter is invalid. | ||
| 135 | .It Bq Er ERRSET_FAIL | ||
| 136 | Other failure. | ||
| 137 | .El | ||
| 138 | .Sh SEE ALSO | ||
| 139 | .Xr resolver 3 , | ||
| 140 | .Xr resolv.conf 5 , | ||
| 141 | .Xr named 8 | ||
| 142 | .Sh HISTORY | ||
| 143 | .Fn getrrsetbyname | ||
| 144 | first appeared in | ||
| 145 | .Ox 3.0 . | ||
| 146 | The API first appeared in ISC BIND version 9. | ||
| 147 | .Sh AUTHORS | ||
| 148 | .An Jakob Schlyter Aq Mt jakob@openbsd.org | ||
| 149 | .Sh CAVEATS | ||
| 150 | The | ||
| 151 | .Dv RRSET_VALIDATED | ||
| 152 | flag in | ||
| 153 | .Li rri_flags | ||
| 154 | is set if the AD (authenticated data) bit in the DNS answer is | ||
| 155 | set. | ||
| 156 | This flag | ||
| 157 | .Em should not | ||
| 158 | be trusted unless the transport between the nameserver and the resolver | ||
| 159 | is secure (e.g. IPsec, trusted network, loopback communication). | ||
| 160 | .Sh BUGS | ||
| 161 | The data in | ||
| 162 | .Li *rdi_data | ||
| 163 | should be returned in uncompressed wire format. | ||
| 164 | Currently, the data is in compressed format and the caller can't | ||
| 165 | uncompress since it doesn't have the full message. | ||
diff --git a/src/lib/libc/net/getservbyname.c b/src/lib/libc/net/getservbyname.c index b4a6311966..beb8943af6 100644 --- a/src/lib/libc/net/getservbyname.c +++ b/src/lib/libc/net/getservbyname.c | |||
| @@ -1,5 +1,4 @@ | |||
| 1 | /* $NetBSD: getservbyname.c,v 1.4 1995/02/25 06:20:36 cgd Exp $ */ | 1 | /* $OpenBSD: getservbyname.c,v 1.10 2005/08/06 20:30:03 espie Exp $ */ |
| 2 | |||
| 3 | /* | 2 | /* |
| 4 | * Copyright (c) 1983, 1993 | 3 | * Copyright (c) 1983, 1993 |
| 5 | * The Regents of the University of California. All rights reserved. | 4 | * The Regents of the University of California. All rights reserved. |
| @@ -12,11 +11,7 @@ | |||
| 12 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
| 13 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the |
| 14 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. |
| 15 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. Neither the name of the University nor the names of its contributors |
| 16 | * must display the following acknowledgement: | ||
| 17 | * This product includes software developed by the University of | ||
| 18 | * California, Berkeley and its contributors. | ||
| 19 | * 4. Neither the name of the University nor the names of its contributors | ||
| 20 | * may be used to endorse or promote products derived from this software | 15 | * may be used to endorse or promote products derived from this software |
| 21 | * without specific prior written permission. | 16 | * without specific prior written permission. |
| 22 | * | 17 | * |
| @@ -33,39 +28,43 @@ | |||
| 33 | * SUCH DAMAGE. | 28 | * SUCH DAMAGE. |
| 34 | */ | 29 | */ |
| 35 | 30 | ||
| 36 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 37 | #if 0 | ||
| 38 | static char sccsid[] = "@(#)getservbyname.c 8.1 (Berkeley) 6/4/93"; | ||
| 39 | #else | ||
| 40 | static char rcsid[] = "$NetBSD: getservbyname.c,v 1.4 1995/02/25 06:20:36 cgd Exp $"; | ||
| 41 | #endif | ||
| 42 | #endif /* LIBC_SCCS and not lint */ | ||
| 43 | |||
| 44 | #include <netdb.h> | 31 | #include <netdb.h> |
| 32 | #include <stdio.h> | ||
| 45 | #include <string.h> | 33 | #include <string.h> |
| 46 | 34 | ||
| 47 | extern int _serv_stayopen; | 35 | int |
| 48 | 36 | getservbyname_r(const char *name, const char *proto, struct servent *se, | |
| 49 | struct servent * | 37 | struct servent_data *sd) |
| 50 | getservbyname(name, proto) | ||
| 51 | const char *name, *proto; | ||
| 52 | { | 38 | { |
| 53 | register struct servent *p; | 39 | char **cp; |
| 54 | register char **cp; | 40 | int error; |
| 55 | 41 | ||
| 56 | setservent(_serv_stayopen); | 42 | setservent_r(sd->stayopen, sd); |
| 57 | while (p = getservent()) { | 43 | while ((error = getservent_r(se, sd)) == 0) { |
| 58 | if (strcmp(name, p->s_name) == 0) | 44 | if (strcmp(name, se->s_name) == 0) |
| 59 | goto gotname; | 45 | goto gotname; |
| 60 | for (cp = p->s_aliases; *cp; cp++) | 46 | for (cp = se->s_aliases; *cp; cp++) |
| 61 | if (strcmp(name, *cp) == 0) | 47 | if (strcmp(name, *cp) == 0) |
| 62 | goto gotname; | 48 | goto gotname; |
| 63 | continue; | 49 | continue; |
| 64 | gotname: | 50 | gotname: |
| 65 | if (proto == 0 || strcmp(p->s_proto, proto) == 0) | 51 | if (proto == 0 || strcmp(se->s_proto, proto) == 0) |
| 66 | break; | 52 | break; |
| 67 | } | 53 | } |
| 68 | if (!_serv_stayopen) | 54 | if (!sd->stayopen && sd->fp != NULL) { |
| 69 | endservent(); | 55 | fclose(sd->fp); |
| 70 | return (p); | 56 | sd->fp = NULL; |
| 57 | } | ||
| 58 | return (error); | ||
| 59 | } | ||
| 60 | |||
| 61 | struct servent * | ||
| 62 | getservbyname(const char *name, const char *proto) | ||
| 63 | { | ||
| 64 | extern struct servent_data _servent_data; | ||
| 65 | static struct servent serv; | ||
| 66 | |||
| 67 | if (getservbyname_r(name, proto, &serv, &_servent_data) != 0) | ||
| 68 | return (NULL); | ||
| 69 | return (&serv); | ||
| 71 | } | 70 | } |
diff --git a/src/lib/libc/net/getservbyport.c b/src/lib/libc/net/getservbyport.c index c34790737b..46679ba366 100644 --- a/src/lib/libc/net/getservbyport.c +++ b/src/lib/libc/net/getservbyport.c | |||
| @@ -1,5 +1,4 @@ | |||
| 1 | /* $NetBSD: getservbyport.c,v 1.4 1995/02/25 06:20:37 cgd Exp $ */ | 1 | /* $OpenBSD: getservbyport.c,v 1.7 2005/08/06 20:30:03 espie Exp $ */ |
| 2 | |||
| 3 | /* | 2 | /* |
| 4 | * Copyright (c) 1983, 1993 | 3 | * Copyright (c) 1983, 1993 |
| 5 | * The Regents of the University of California. All rights reserved. | 4 | * The Regents of the University of California. All rights reserved. |
| @@ -12,11 +11,7 @@ | |||
| 12 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
| 13 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the |
| 14 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. |
| 15 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. Neither the name of the University nor the names of its contributors |
| 16 | * must display the following acknowledgement: | ||
| 17 | * This product includes software developed by the University of | ||
| 18 | * California, Berkeley and its contributors. | ||
| 19 | * 4. Neither the name of the University nor the names of its contributors | ||
| 20 | * may be used to endorse or promote products derived from this software | 15 | * may be used to endorse or promote products derived from this software |
| 21 | * without specific prior written permission. | 16 | * without specific prior written permission. |
| 22 | * | 17 | * |
| @@ -33,34 +28,37 @@ | |||
| 33 | * SUCH DAMAGE. | 28 | * SUCH DAMAGE. |
| 34 | */ | 29 | */ |
| 35 | 30 | ||
| 36 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 37 | #if 0 | ||
| 38 | static char sccsid[] = "@(#)getservbyport.c 8.1 (Berkeley) 6/4/93"; | ||
| 39 | #else | ||
| 40 | static char rcsid[] = "$NetBSD: getservbyport.c,v 1.4 1995/02/25 06:20:37 cgd Exp $"; | ||
| 41 | #endif | ||
| 42 | #endif /* LIBC_SCCS and not lint */ | ||
| 43 | |||
| 44 | #include <netdb.h> | 31 | #include <netdb.h> |
| 32 | #include <stdio.h> | ||
| 45 | #include <string.h> | 33 | #include <string.h> |
| 46 | 34 | ||
| 47 | extern int _serv_stayopen; | 35 | int |
| 48 | 36 | getservbyport_r(int port, const char *proto, struct servent *se, | |
| 49 | struct servent * | 37 | struct servent_data *sd) |
| 50 | getservbyport(port, proto) | ||
| 51 | int port; | ||
| 52 | const char *proto; | ||
| 53 | { | 38 | { |
| 54 | register struct servent *p; | 39 | int error; |
| 55 | 40 | ||
| 56 | setservent(_serv_stayopen); | 41 | setservent_r(sd->stayopen, sd); |
| 57 | while (p = getservent()) { | 42 | while ((error = getservent_r(se, sd)) == 0) { |
| 58 | if (p->s_port != port) | 43 | if (se->s_port != port) |
| 59 | continue; | 44 | continue; |
| 60 | if (proto == 0 || strcmp(p->s_proto, proto) == 0) | 45 | if (proto == 0 || strcmp(se->s_proto, proto) == 0) |
| 61 | break; | 46 | break; |
| 62 | } | 47 | } |
| 63 | if (!_serv_stayopen) | 48 | if (!sd->stayopen && sd->fp != NULL) { |
| 64 | endservent(); | 49 | fclose(sd->fp); |
| 65 | return (p); | 50 | sd->fp = NULL; |
| 51 | } | ||
| 52 | return (error); | ||
| 53 | } | ||
| 54 | |||
| 55 | struct servent * | ||
| 56 | getservbyport(int port, const char *proto) | ||
| 57 | { | ||
| 58 | extern struct servent_data _servent_data; | ||
| 59 | static struct servent serv; | ||
| 60 | |||
| 61 | if (getservbyport_r(port, proto, &serv, &_servent_data) != 0) | ||
| 62 | return (NULL); | ||
| 63 | return (&serv); | ||
| 66 | } | 64 | } |
diff --git a/src/lib/libc/net/getservent.3 b/src/lib/libc/net/getservent.3 index 9e0656be00..29dd3eb5f4 100644 --- a/src/lib/libc/net/getservent.3 +++ b/src/lib/libc/net/getservent.3 | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | .\" $NetBSD: getservent.3,v 1.3 1995/02/25 06:20:38 cgd Exp $ | 1 | .\" $OpenBSD: getservent.3,v 1.21 2013/06/05 03:39:23 tedu Exp $ |
| 2 | .\" | 2 | .\" |
| 3 | .\" Copyright (c) 1983, 1991, 1993 | 3 | .\" Copyright (c) 1983, 1991, 1993 |
| 4 | .\" The Regents of the University of California. All rights reserved. | 4 | .\" The Regents of the University of California. All rights reserved. |
| @@ -11,11 +11,7 @@ | |||
| 11 | .\" 2. Redistributions in binary form must reproduce the above copyright | 11 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 12 | .\" notice, this list of conditions and the following disclaimer in the | 12 | .\" notice, this list of conditions and the following disclaimer in the |
| 13 | .\" documentation and/or other materials provided with the distribution. | 13 | .\" documentation and/or other materials provided with the distribution. |
| 14 | .\" 3. All advertising materials mentioning features or use of this software | 14 | .\" 3. Neither the name of the University nor the names of its contributors |
| 15 | .\" must display the following acknowledgement: | ||
| 16 | .\" This product includes software developed by the University of | ||
| 17 | .\" California, Berkeley and its contributors. | ||
| 18 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 19 | .\" may be used to endorse or promote products derived from this software | 15 | .\" may be used to endorse or promote products derived from this software |
| 20 | .\" without specific prior written permission. | 16 | .\" without specific prior written permission. |
| 21 | .\" | 17 | .\" |
| @@ -31,41 +27,51 @@ | |||
| 31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 27 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 32 | .\" SUCH DAMAGE. | 28 | .\" SUCH DAMAGE. |
| 33 | .\" | 29 | .\" |
| 34 | .\" @(#)getservent.3 8.3 (Berkeley) 1/12/94 | 30 | .Dd $Mdocdate: June 5 2013 $ |
| 35 | .\" | ||
| 36 | .Dd January 12, 1994 | ||
| 37 | .Dt GETSERVENT 3 | 31 | .Dt GETSERVENT 3 |
| 38 | .Os BSD 4.2 | 32 | .Os |
| 39 | .Sh NAME | 33 | .Sh NAME |
| 40 | .Nm getservent , | 34 | .Nm getservent , |
| 35 | .Nm getservent_r , | ||
| 41 | .Nm getservbyport , | 36 | .Nm getservbyport , |
| 37 | .Nm getservbyport_r , | ||
| 42 | .Nm getservbyname , | 38 | .Nm getservbyname , |
| 39 | .Nm getservbyname_r , | ||
| 43 | .Nm setservent , | 40 | .Nm setservent , |
| 44 | .Nm endservent | 41 | .Nm setservent_r , |
| 42 | .Nm endservent , | ||
| 43 | .Nm endservent_r | ||
| 45 | .Nd get service entry | 44 | .Nd get service entry |
| 46 | .Sh SYNOPSIS | 45 | .Sh SYNOPSIS |
| 47 | .Fd #include <netdb.h> | 46 | .In netdb.h |
| 48 | .Ft struct servent * | 47 | .Ft struct servent * |
| 49 | .Fn getservent | 48 | .Fn getservent "void" |
| 49 | .Ft int | ||
| 50 | .Fn getservent_r "struct servent *servent" "struct servent_data *servent_data" | ||
| 50 | .Ft struct servent * | 51 | .Ft struct servent * |
| 51 | .Fn getservbyname "char *name" "char *proto" | 52 | .Fn getservbyname "const char *name" "const char *proto" |
| 53 | .Ft int | ||
| 54 | .Fn getservbyname_r "const char *name" "const char *proto" "struct servent *servent" "struct servent_data *servent_data" | ||
| 52 | .Ft struct servent * | 55 | .Ft struct servent * |
| 53 | .Fn getservbyport "int port" proto | 56 | .Fn getservbyport "int port" "const char *proto" |
| 57 | .Ft int | ||
| 58 | .Fn getservbyport_r "int port" "const char *proto" "struct servent *servent" "struct servent_data *servent_data" | ||
| 54 | .Ft void | 59 | .Ft void |
| 55 | .Fn setservent "int stayopen" | 60 | .Fn setservent "int stayopen" |
| 56 | .Ft void | 61 | .Ft void |
| 57 | .Fn endservent void | 62 | .Fn setservent_r "int stayopen" "struct servent_data *servent_data" |
| 63 | .Ft void | ||
| 64 | .Fn endservent "void" | ||
| 65 | .Ft void | ||
| 66 | .Fn endservent_r "struct servent_data *servent_data" | ||
| 58 | .Sh DESCRIPTION | 67 | .Sh DESCRIPTION |
| 59 | The | 68 | The |
| 60 | .Fn getservent , | 69 | .Fn getservent , |
| 61 | .Fn getservbyname , | 70 | .Fn getservbyname , |
| 62 | and | 71 | and |
| 63 | .Fn getservbyport | 72 | .Fn getservbyport |
| 64 | functions | 73 | functions each return a pointer to an object with the following structure |
| 65 | each return a pointer to an object with the | 74 | containing the broken-out fields of a line in the network services database, |
| 66 | following structure | ||
| 67 | containing the broken-out | ||
| 68 | fields of a line in the network services data base, | ||
| 69 | .Pa /etc/services . | 75 | .Pa /etc/services . |
| 70 | .Bd -literal -offset indent | 76 | .Bd -literal -offset indent |
| 71 | struct servent { | 77 | struct servent { |
| @@ -81,64 +87,113 @@ The members of this structure are: | |||
| 81 | .It Fa s_name | 87 | .It Fa s_name |
| 82 | The official name of the service. | 88 | The official name of the service. |
| 83 | .It Fa s_aliases | 89 | .It Fa s_aliases |
| 84 | A zero terminated list of alternate names for the service. | 90 | A null-terminated list of alternate names for the service. |
| 85 | .It Fa s_port | 91 | .It Fa s_port |
| 86 | The port number at which the service resides. | 92 | The port number at which the service resides. |
| 87 | Port numbers are returned in network byte order. | 93 | Port numbers are returned in network byte order. |
| 88 | .It Fa s_proto | 94 | .It Fa s_proto |
| 89 | The name of the protocol to use when contacting the | 95 | The name of the protocol to use when contacting the service. |
| 90 | service. | ||
| 91 | .El | 96 | .El |
| 92 | .Pp | 97 | .Pp |
| 93 | The | 98 | The |
| 94 | .Fn getservent | 99 | .Fn getservent |
| 95 | function | 100 | function reads the next line of the file, opening the file if necessary. |
| 96 | reads the next line of the file, opening the file if necessary. | ||
| 97 | .Pp | 101 | .Pp |
| 98 | The | 102 | The |
| 99 | .Fn setservent | 103 | .Fn setservent |
| 100 | function | 104 | function opens and rewinds the file. |
| 101 | opens and rewinds the file. If the | 105 | If the |
| 102 | .Fa stayopen | 106 | .Fa stayopen |
| 103 | flag is non-zero, | 107 | flag is non-zero, |
| 104 | the net data base will not be closed after each call to | 108 | the services database will not be closed after each call to |
| 105 | .Fn getservbyname | 109 | .Fn getservbyname |
| 106 | or | 110 | or |
| 107 | .Fn getservbyport . | 111 | .Fn getservbyport . |
| 108 | .Pp | 112 | .Pp |
| 109 | The | 113 | The |
| 110 | .Fn endservent | 114 | .Fn endservent |
| 111 | function | 115 | function closes the file. |
| 112 | closes the file. | ||
| 113 | .Pp | 116 | .Pp |
| 114 | The | 117 | The |
| 115 | .Fn getservbyname | 118 | .Fn getservbyname |
| 116 | and | 119 | and |
| 117 | .Fn getservbyport | 120 | .Fn getservbyport |
| 118 | functions | 121 | functions sequentially search from the beginning of the file until a |
| 119 | sequentially search from the beginning | 122 | matching protocol name or port number (specified in network byte order) |
| 120 | of the file until a matching | 123 | is found, or until |
| 121 | protocol name or | ||
| 122 | port number is found, | ||
| 123 | or until | ||
| 124 | .Dv EOF | 124 | .Dv EOF |
| 125 | is encountered. | 125 | is encountered. |
| 126 | If a protocol name is also supplied (non- | 126 | If a protocol name is also supplied (non-null), |
| 127 | .Dv NULL ) , | ||
| 128 | searches must also match the protocol. | 127 | searches must also match the protocol. |
| 129 | .ne 1i | 128 | .Pp |
| 129 | The | ||
| 130 | .Fn getservent_r , | ||
| 131 | .Fn getservbyport_r , | ||
| 132 | .Fn getservbyname_r , | ||
| 133 | .Fn setservent_r , | ||
| 134 | and | ||
| 135 | .Fn endservent_r | ||
| 136 | functions are reentrant versions of the above functions that take a | ||
| 137 | pointer to a | ||
| 138 | .Fa servent_data | ||
| 139 | structure which is used to store state information. | ||
| 140 | The structure must be zero-filled before it is used | ||
| 141 | and should be considered opaque for the sake of portability. | ||
| 142 | .Pp | ||
| 143 | The | ||
| 144 | .Fn getservent_r , | ||
| 145 | .Fn getservbyport_r , | ||
| 146 | and | ||
| 147 | .Fn getservbyname_r | ||
| 148 | functions | ||
| 149 | also take a pointer to a | ||
| 150 | .Fa servent | ||
| 151 | structure which is used to store the results of the database lookup. | ||
| 152 | .Sh RETURN VALUES | ||
| 153 | The | ||
| 154 | .Fn getservent , | ||
| 155 | .Fn getservbyport , | ||
| 156 | and | ||
| 157 | .Fn getservbyname | ||
| 158 | functions return a pointer to a | ||
| 159 | .Fa servent | ||
| 160 | structure on success or a null pointer if end-of-file | ||
| 161 | is reached or an error occurs. | ||
| 162 | .Pp | ||
| 163 | The | ||
| 164 | .Fn getservent_r , | ||
| 165 | .Fn getservbyport_r , | ||
| 166 | and | ||
| 167 | .Fn getservbyname_r | ||
| 168 | functions return 0 on success or \-1 if end-of-file | ||
| 169 | is reached or an error occurs. | ||
| 130 | .Sh FILES | 170 | .Sh FILES |
| 131 | .Bl -tag -width /etc/services -compact | 171 | .Bl -tag -width /etc/services -compact |
| 132 | .It Pa /etc/services | 172 | .It Pa /etc/services |
| 133 | .El | 173 | .El |
| 134 | .Sh DIAGNOSTICS | ||
| 135 | Null pointer | ||
| 136 | (0) returned on | ||
| 137 | .Dv EOF | ||
| 138 | or error. | ||
| 139 | .Sh SEE ALSO | 174 | .Sh SEE ALSO |
| 140 | .Xr getprotoent 3 , | 175 | .Xr getprotoent 3 , |
| 141 | .Xr services 5 | 176 | .Xr services 5 |
| 177 | .Sh STANDARDS | ||
| 178 | The | ||
| 179 | .Fn getservent , | ||
| 180 | .Fn getservbynumber , | ||
| 181 | .Fn getservbyname , | ||
| 182 | .Fn setservent , | ||
| 183 | and | ||
| 184 | .Fn endservent | ||
| 185 | functions conform to | ||
| 186 | .St -p1003.1-2004 . | ||
| 187 | .Pp | ||
| 188 | The | ||
| 189 | .Fn getservent_r , | ||
| 190 | .Fn getservbyport_r , | ||
| 191 | .Fn getservbyname_r , | ||
| 192 | .Fn setservent_r , | ||
| 193 | and | ||
| 194 | .Fn endservent_r | ||
| 195 | functions are not currently standardized. | ||
| 196 | This implementation follows the API used by HP, IBM, and Digital. | ||
| 142 | .Sh HISTORY | 197 | .Sh HISTORY |
| 143 | The | 198 | The |
| 144 | .Fn getservent , | 199 | .Fn getservent , |
| @@ -147,11 +202,19 @@ The | |||
| 147 | .Fn setservent , | 202 | .Fn setservent , |
| 148 | and | 203 | and |
| 149 | .Fn endservent | 204 | .Fn endservent |
| 150 | functions appeared in | 205 | functions appeared in |
| 151 | .Bx 4.2 . | 206 | .Bx 4.2 . |
| 207 | .Pp | ||
| 208 | The | ||
| 209 | .Fn getservent_r , | ||
| 210 | .Fn getservbyport_r , | ||
| 211 | .Fn getservbyname_r , | ||
| 212 | .Fn setservent_r , | ||
| 213 | and | ||
| 214 | .Fn endservent_r | ||
| 215 | functions appeared in | ||
| 216 | .Ox 3.7 . | ||
| 152 | .Sh BUGS | 217 | .Sh BUGS |
| 153 | These functions use static data storage; | 218 | The non-reentrant functions use static data storage; if the data is needed |
| 154 | if the data is needed for future use, it should be | 219 | for future use, it should be copied before any subsequent calls overwrite it. |
| 155 | copied before any subsequent calls overwrite it. | 220 | Expecting port numbers to fit in a 32-bit quantity is probably naive. |
| 156 | Expecting port numbers to fit in a 32 bit | ||
| 157 | quantity is probably naive. | ||
diff --git a/src/lib/libc/net/getservent.c b/src/lib/libc/net/getservent.c index 316891450e..c81a4cf3e2 100644 --- a/src/lib/libc/net/getservent.c +++ b/src/lib/libc/net/getservent.c | |||
| @@ -1,5 +1,4 @@ | |||
| 1 | /* $NetBSD: getservent.c,v 1.4 1995/02/25 06:20:38 cgd Exp $ */ | 1 | /* $OpenBSD: getservent.c,v 1.12 2007/09/02 15:19:17 deraadt Exp $ */ |
| 2 | |||
| 3 | /* | 2 | /* |
| 4 | * Copyright (c) 1983, 1993 | 3 | * Copyright (c) 1983, 1993 |
| 5 | * The Regents of the University of California. All rights reserved. | 4 | * The Regents of the University of California. All rights reserved. |
| @@ -12,11 +11,7 @@ | |||
| 12 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
| 13 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the |
| 14 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. |
| 15 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. Neither the name of the University nor the names of its contributors |
| 16 | * must display the following acknowledgement: | ||
| 17 | * This product includes software developed by the University of | ||
| 18 | * California, Berkeley and its contributors. | ||
| 19 | * 4. Neither the name of the University nor the names of its contributors | ||
| 20 | * may be used to endorse or promote products derived from this software | 15 | * may be used to endorse or promote products derived from this software |
| 21 | * without specific prior written permission. | 16 | * without specific prior written permission. |
| 22 | * | 17 | * |
| @@ -33,69 +28,66 @@ | |||
| 33 | * SUCH DAMAGE. | 28 | * SUCH DAMAGE. |
| 34 | */ | 29 | */ |
| 35 | 30 | ||
| 36 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 37 | #if 0 | ||
| 38 | static char sccsid[] = "@(#)getservent.c 8.1 (Berkeley) 6/4/93"; | ||
| 39 | #else | ||
| 40 | static char rcsid[] = "$NetBSD: getservent.c,v 1.4 1995/02/25 06:20:38 cgd Exp $"; | ||
| 41 | #endif | ||
| 42 | #endif /* LIBC_SCCS and not lint */ | ||
| 43 | |||
| 44 | #include <sys/types.h> | 31 | #include <sys/types.h> |
| 45 | #include <sys/socket.h> | 32 | #include <sys/socket.h> |
| 33 | |||
| 34 | #include <errno.h> | ||
| 35 | #include <limits.h> | ||
| 46 | #include <netdb.h> | 36 | #include <netdb.h> |
| 47 | #include <stdio.h> | 37 | #include <stdio.h> |
| 48 | #include <string.h> | 38 | #include <string.h> |
| 49 | #include <stdlib.h> | 39 | #include <stdlib.h> |
| 50 | 40 | ||
| 51 | #define MAXALIASES 35 | ||
| 52 | |||
| 53 | static FILE *servf = NULL; | ||
| 54 | static char line[BUFSIZ+1]; | ||
| 55 | static struct servent serv; | ||
| 56 | static char *serv_aliases[MAXALIASES]; | ||
| 57 | int _serv_stayopen; | ||
| 58 | |||
| 59 | void | 41 | void |
| 60 | setservent(f) | 42 | setservent_r(int f, struct servent_data *sd) |
| 61 | int f; | ||
| 62 | { | 43 | { |
| 63 | if (servf == NULL) | 44 | if (sd->fp == NULL) |
| 64 | servf = fopen(_PATH_SERVICES, "r" ); | 45 | sd->fp = fopen(_PATH_SERVICES, "r" ); |
| 65 | else | 46 | else |
| 66 | rewind(servf); | 47 | rewind(sd->fp); |
| 67 | _serv_stayopen |= f; | 48 | sd->stayopen |= f; |
| 68 | } | 49 | } |
| 69 | 50 | ||
| 70 | void | 51 | void |
| 71 | endservent() | 52 | endservent_r(struct servent_data *sd) |
| 72 | { | 53 | { |
| 73 | if (servf) { | 54 | if (sd->fp) { |
| 74 | fclose(servf); | 55 | fclose(sd->fp); |
| 75 | servf = NULL; | 56 | sd->fp = NULL; |
| 76 | } | 57 | } |
| 77 | _serv_stayopen = 0; | 58 | free(sd->aliases); |
| 59 | sd->aliases = NULL; | ||
| 60 | sd->maxaliases = 0; | ||
| 61 | free(sd->line); | ||
| 62 | sd->line = NULL; | ||
| 63 | sd->stayopen = 0; | ||
| 78 | } | 64 | } |
| 79 | 65 | ||
| 80 | struct servent * | 66 | int |
| 81 | getservent() | 67 | getservent_r(struct servent *se, struct servent_data *sd) |
| 82 | { | 68 | { |
| 83 | char *p; | 69 | char *p, *cp, **q, *endp; |
| 84 | register char *cp, **q; | 70 | size_t len; |
| 71 | long l; | ||
| 72 | int serrno; | ||
| 85 | 73 | ||
| 86 | if (servf == NULL && (servf = fopen(_PATH_SERVICES, "r" )) == NULL) | 74 | if (sd->fp == NULL && (sd->fp = fopen(_PATH_SERVICES, "r" )) == NULL) |
| 87 | return (NULL); | 75 | return (-1); |
| 88 | again: | 76 | again: |
| 89 | if ((p = fgets(line, BUFSIZ, servf)) == NULL) | 77 | if ((p = fgetln(sd->fp, &len)) == NULL) |
| 90 | return (NULL); | 78 | return (-1); |
| 91 | if (*p == '#') | 79 | if (len == 0 || *p == '#' || *p == '\n') |
| 92 | goto again; | 80 | goto again; |
| 93 | cp = strpbrk(p, "#\n"); | 81 | if (p[len-1] == '\n') |
| 82 | len--; | ||
| 83 | if ((cp = memchr(p, '#', len)) != NULL) | ||
| 84 | len = cp - p; | ||
| 85 | cp = realloc(sd->line, len + 1); | ||
| 94 | if (cp == NULL) | 86 | if (cp == NULL) |
| 95 | goto again; | 87 | return (-1); |
| 96 | *cp = '\0'; | 88 | sd->line = se->s_name = memcpy(cp, p, len); |
| 97 | serv.s_name = p; | 89 | cp[len] = '\0'; |
| 98 | p = strpbrk(p, " \t"); | 90 | p = strpbrk(cp, " \t"); |
| 99 | if (p == NULL) | 91 | if (p == NULL) |
| 100 | goto again; | 92 | goto again; |
| 101 | *p++ = '\0'; | 93 | *p++ = '\0'; |
| @@ -105,9 +97,22 @@ again: | |||
| 105 | if (cp == NULL) | 97 | if (cp == NULL) |
| 106 | goto again; | 98 | goto again; |
| 107 | *cp++ = '\0'; | 99 | *cp++ = '\0'; |
| 108 | serv.s_port = htons((u_short)atoi(p)); | 100 | l = strtol(p, &endp, 10); |
| 109 | serv.s_proto = cp; | 101 | if (endp == p || *endp != '\0' || l < 0 || l > USHRT_MAX) |
| 110 | q = serv.s_aliases = serv_aliases; | 102 | goto again; |
| 103 | se->s_port = htons((in_port_t)l); | ||
| 104 | se->s_proto = cp; | ||
| 105 | if (sd->aliases == NULL) { | ||
| 106 | sd->maxaliases = 10; | ||
| 107 | sd->aliases = calloc(sd->maxaliases, sizeof(char *)); | ||
| 108 | if (sd->aliases == NULL) { | ||
| 109 | serrno = errno; | ||
| 110 | endservent_r(sd); | ||
| 111 | errno = serrno; | ||
| 112 | return (-1); | ||
| 113 | } | ||
| 114 | } | ||
| 115 | q = se->s_aliases = sd->aliases; | ||
| 111 | cp = strpbrk(cp, " \t"); | 116 | cp = strpbrk(cp, " \t"); |
| 112 | if (cp != NULL) | 117 | if (cp != NULL) |
| 113 | *cp++ = '\0'; | 118 | *cp++ = '\0'; |
| @@ -116,12 +121,48 @@ again: | |||
| 116 | cp++; | 121 | cp++; |
| 117 | continue; | 122 | continue; |
| 118 | } | 123 | } |
| 119 | if (q < &serv_aliases[MAXALIASES - 1]) | 124 | if (q == &se->s_aliases[sd->maxaliases - 1]) { |
| 120 | *q++ = cp; | 125 | p = realloc(se->s_aliases, |
| 126 | 2 * sd->maxaliases * sizeof(char *)); | ||
| 127 | if (p == NULL) { | ||
| 128 | serrno = errno; | ||
| 129 | endservent_r(sd); | ||
| 130 | errno = serrno; | ||
| 131 | return (-1); | ||
| 132 | } | ||
| 133 | sd->maxaliases *= 2; | ||
| 134 | q = (char **)p + (q - se->s_aliases); | ||
| 135 | se->s_aliases = sd->aliases = (char **)p; | ||
| 136 | } | ||
| 137 | *q++ = cp; | ||
| 121 | cp = strpbrk(cp, " \t"); | 138 | cp = strpbrk(cp, " \t"); |
| 122 | if (cp != NULL) | 139 | if (cp != NULL) |
| 123 | *cp++ = '\0'; | 140 | *cp++ = '\0'; |
| 124 | } | 141 | } |
| 125 | *q = NULL; | 142 | *q = NULL; |
| 143 | return (0); | ||
| 144 | } | ||
| 145 | |||
| 146 | struct servent_data _servent_data; /* shared with getservby{name,port}.c */ | ||
| 147 | |||
| 148 | void | ||
| 149 | setservent(int f) | ||
| 150 | { | ||
| 151 | setservent_r(f, &_servent_data); | ||
| 152 | } | ||
| 153 | |||
| 154 | void | ||
| 155 | endservent(void) | ||
| 156 | { | ||
| 157 | endservent_r(&_servent_data); | ||
| 158 | } | ||
| 159 | |||
| 160 | struct servent * | ||
| 161 | getservent(void) | ||
| 162 | { | ||
| 163 | static struct servent serv; | ||
| 164 | |||
| 165 | if (getservent_r(&serv, &_servent_data) != 0) | ||
| 166 | return (NULL); | ||
| 126 | return (&serv); | 167 | return (&serv); |
| 127 | } | 168 | } |
diff --git a/src/lib/libc/net/herror.c b/src/lib/libc/net/herror.c index 41adbf1055..7787115a9d 100644 --- a/src/lib/libc/net/herror.c +++ b/src/lib/libc/net/herror.c | |||
| @@ -1,9 +1,11 @@ | |||
| 1 | /* $NetBSD: herror.c,v 1.5 1995/02/25 06:20:39 cgd Exp $ */ | 1 | /* $OpenBSD: herror.c,v 1.8 2005/08/06 20:30:03 espie Exp $ */ |
| 2 | 2 | ||
| 3 | /*- | 3 | /* |
| 4 | * ++Copyright++ 1987, 1993 | ||
| 5 | * - | ||
| 4 | * Copyright (c) 1987, 1993 | 6 | * Copyright (c) 1987, 1993 |
| 5 | * The Regents of the University of California. All rights reserved. | 7 | * The Regents of the University of California. All rights reserved. |
| 6 | * | 8 | * |
| 7 | * Redistribution and use in source and binary forms, with or without | 9 | * Redistribution and use in source and binary forms, with or without |
| 8 | * modification, are permitted provided that the following conditions | 10 | * modification, are permitted provided that the following conditions |
| 9 | * are met: | 11 | * are met: |
| @@ -12,14 +14,10 @@ | |||
| 12 | * 2. Redistributions in binary form must reproduce the above copyright | 14 | * 2. Redistributions in binary form must reproduce the above copyright |
| 13 | * notice, this list of conditions and the following disclaimer in the | 15 | * notice, this list of conditions and the following disclaimer in the |
| 14 | * documentation and/or other materials provided with the distribution. | 16 | * documentation and/or other materials provided with the distribution. |
| 15 | * 3. All advertising materials mentioning features or use of this software | 17 | * 3. Neither the name of the University nor the names of its contributors |
| 16 | * must display the following acknowledgement: | ||
| 17 | * This product includes software developed by the University of | ||
| 18 | * California, Berkeley and its contributors. | ||
| 19 | * 4. Neither the name of the University nor the names of its contributors | ||
| 20 | * may be used to endorse or promote products derived from this software | 18 | * may be used to endorse or promote products derived from this software |
| 21 | * without specific prior written permission. | 19 | * without specific prior written permission. |
| 22 | * | 20 | * |
| 23 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | 21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
| 24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| @@ -53,29 +51,21 @@ | |||
| 53 | * --Copyright-- | 51 | * --Copyright-- |
| 54 | */ | 52 | */ |
| 55 | 53 | ||
| 56 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 57 | #if 0 | ||
| 58 | static char sccsid[] = "@(#)herror.c 8.1 (Berkeley) 6/4/93"; | ||
| 59 | static char rcsid[] = "$Id: herror.c,v 4.9.1.1 1993/05/02 23:14:35 vixie Rel "; | ||
| 60 | #else | ||
| 61 | static char rcsid[] = "$NetBSD: herror.c,v 1.5 1995/02/25 06:20:39 cgd Exp $"; | ||
| 62 | #endif | ||
| 63 | #endif /* LIBC_SCCS and not lint */ | ||
| 64 | |||
| 65 | #include <sys/types.h> | 54 | #include <sys/types.h> |
| 55 | #include <sys/param.h> | ||
| 66 | #include <sys/uio.h> | 56 | #include <sys/uio.h> |
| 67 | #include <netdb.h> | 57 | #include <netdb.h> |
| 68 | #include <unistd.h> | 58 | #include <unistd.h> |
| 69 | #include <string.h> | 59 | #include <string.h> |
| 70 | 60 | ||
| 71 | char *h_errlist[] = { | 61 | const char * const h_errlist[] = { |
| 72 | "Error 0", | 62 | "Resolver Error 0 (no error)", |
| 73 | "Unknown host", /* 1 HOST_NOT_FOUND */ | 63 | "Unknown host", /* 1 HOST_NOT_FOUND */ |
| 74 | "Host name lookup failure", /* 2 TRY_AGAIN */ | 64 | "Host name lookup failure", /* 2 TRY_AGAIN */ |
| 75 | "Unknown server error", /* 3 NO_RECOVERY */ | 65 | "Unknown server error", /* 3 NO_RECOVERY */ |
| 76 | "No address associated with name", /* 4 NO_ADDRESS */ | 66 | "No address associated with name", /* 4 NO_ADDRESS */ |
| 77 | }; | 67 | }; |
| 78 | int h_nerr = { sizeof(h_errlist)/sizeof(h_errlist[0]) }; | 68 | const int h_nerr = { sizeof h_errlist / sizeof h_errlist[0] }; |
| 79 | 69 | ||
| 80 | extern int h_errno; | 70 | extern int h_errno; |
| 81 | 71 | ||
| @@ -84,11 +74,10 @@ extern int h_errno; | |||
| 84 | * print the error indicated by the h_errno value. | 74 | * print the error indicated by the h_errno value. |
| 85 | */ | 75 | */ |
| 86 | void | 76 | void |
| 87 | herror(s) | 77 | herror(const char *s) |
| 88 | const char *s; | ||
| 89 | { | 78 | { |
| 90 | struct iovec iov[4]; | 79 | struct iovec iov[4]; |
| 91 | register struct iovec *v = iov; | 80 | struct iovec *v = iov; |
| 92 | 81 | ||
| 93 | if (s && *s) { | 82 | if (s && *s) { |
| 94 | v->iov_base = (char *)s; | 83 | v->iov_base = (char *)s; |
| @@ -98,8 +87,7 @@ herror(s) | |||
| 98 | v->iov_len = 2; | 87 | v->iov_len = 2; |
| 99 | v++; | 88 | v++; |
| 100 | } | 89 | } |
| 101 | v->iov_base = (u_int)h_errno < h_nerr ? | 90 | v->iov_base = (char *)hstrerror(h_errno); |
| 102 | h_errlist[h_errno] : "Unknown error"; | ||
| 103 | v->iov_len = strlen(v->iov_base); | 91 | v->iov_len = strlen(v->iov_base); |
| 104 | v++; | 92 | v++; |
| 105 | v->iov_base = "\n"; | 93 | v->iov_base = "\n"; |
| @@ -107,9 +95,12 @@ herror(s) | |||
| 107 | writev(STDERR_FILENO, iov, (v - iov) + 1); | 95 | writev(STDERR_FILENO, iov, (v - iov) + 1); |
| 108 | } | 96 | } |
| 109 | 97 | ||
| 110 | char * | 98 | const char * |
| 111 | hstrerror(err) | 99 | hstrerror(int err) |
| 112 | int err; | ||
| 113 | { | 100 | { |
| 114 | return (u_int)err < h_nerr ? h_errlist[err] : "Unknown resolver error"; | 101 | if (err < 0) |
| 102 | return ("Resolver internal error"); | ||
| 103 | else if (err < h_nerr) | ||
| 104 | return (h_errlist[err]); | ||
| 105 | return ("Unknown resolver error"); | ||
| 115 | } | 106 | } |
diff --git a/src/lib/libc/net/htonl.c b/src/lib/libc/net/htonl.c index ac85cb0fd7..5ab4189597 100644 --- a/src/lib/libc/net/htonl.c +++ b/src/lib/libc/net/htonl.c | |||
| @@ -1,29 +1,21 @@ | |||
| 1 | /* $NetBSD: htonl.c,v 1.5 1995/04/28 23:25:14 jtc Exp $ */ | 1 | /* $OpenBSD: htonl.c,v 1.6 2005/08/06 20:30:03 espie Exp $ */ |
| 2 | |||
| 3 | /* | 2 | /* |
| 4 | * Written by J.T. Conklin <jtc@netbsd.org>. | 3 | * Written by J.T. Conklin <jtc@netbsd.org>. |
| 5 | * Public domain. | 4 | * Public domain. |
| 6 | */ | 5 | */ |
| 7 | 6 | ||
| 8 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 9 | static char *rcsid = "$NetBSD: htonl.c,v 1.5 1995/04/28 23:25:14 jtc Exp $"; | ||
| 10 | #endif | ||
| 11 | |||
| 12 | #include <sys/types.h> | 7 | #include <sys/types.h> |
| 13 | #include <machine/endian.h> | 8 | #include <machine/endian.h> |
| 14 | 9 | ||
| 15 | #undef htonl | 10 | #undef htonl |
| 16 | 11 | ||
| 17 | unsigned long | 12 | u_int32_t |
| 18 | htonl(x) | 13 | htonl(u_int32_t x) |
| 19 | unsigned long x; | ||
| 20 | { | 14 | { |
| 21 | u_int32_t y = x; | ||
| 22 | |||
| 23 | #if BYTE_ORDER == LITTLE_ENDIAN | 15 | #if BYTE_ORDER == LITTLE_ENDIAN |
| 24 | u_char *s = (u_char *)&y; | 16 | u_char *s = (u_char *)&x; |
| 25 | return s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]; | 17 | return (u_int32_t)(s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]); |
| 26 | #else | 18 | #else |
| 27 | return y; | 19 | return x; |
| 28 | #endif | 20 | #endif |
| 29 | } | 21 | } |
diff --git a/src/lib/libc/net/htons.c b/src/lib/libc/net/htons.c index b2500a51d1..c8b73fdbb7 100644 --- a/src/lib/libc/net/htons.c +++ b/src/lib/libc/net/htons.c | |||
| @@ -1,26 +1,20 @@ | |||
| 1 | /* $NetBSD: htons.c,v 1.5 1995/04/28 23:25:19 jtc Exp $ */ | 1 | /* $OpenBSD: htons.c,v 1.8 2005/08/06 20:30:03 espie Exp $ */ |
| 2 | |||
| 3 | /* | 2 | /* |
| 4 | * Written by J.T. Conklin <jtc@netbsd.org>. | 3 | * Written by J.T. Conklin <jtc@netbsd.org>. |
| 5 | * Public domain. | 4 | * Public domain. |
| 6 | */ | 5 | */ |
| 7 | 6 | ||
| 8 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 9 | static char *rcsid = "$NetBSD: htons.c,v 1.5 1995/04/28 23:25:19 jtc Exp $"; | ||
| 10 | #endif | ||
| 11 | |||
| 12 | #include <sys/types.h> | 7 | #include <sys/types.h> |
| 13 | #include <machine/endian.h> | 8 | #include <machine/endian.h> |
| 14 | 9 | ||
| 15 | #undef htons | 10 | #undef htons |
| 16 | 11 | ||
| 17 | unsigned short | 12 | u_int16_t |
| 18 | htons(x) | 13 | htons(u_int16_t x) |
| 19 | unsigned short x; | ||
| 20 | { | 14 | { |
| 21 | #if BYTE_ORDER == LITTLE_ENDIAN | 15 | #if BYTE_ORDER == LITTLE_ENDIAN |
| 22 | u_char *s = (u_char *) &x; | 16 | u_char *s = (u_char *) &x; |
| 23 | return s[0] << 8 | s[1]; | 17 | return (u_int16_t)(s[0] << 8 | s[1]); |
| 24 | #else | 18 | #else |
| 25 | return x; | 19 | return x; |
| 26 | #endif | 20 | #endif |
diff --git a/src/lib/libc/net/if_indextoname.3 b/src/lib/libc/net/if_indextoname.3 new file mode 100644 index 0000000000..5e6e7f2fdb --- /dev/null +++ b/src/lib/libc/net/if_indextoname.3 | |||
| @@ -0,0 +1,143 @@ | |||
| 1 | .\" $OpenBSD: if_indextoname.3,v 1.15 2014/01/21 03:15:45 schwarze Exp $ | ||
| 2 | .\" Copyright (c) 1983, 1991, 1993 | ||
| 3 | .\" The Regents of the University of California. All rights reserved. | ||
| 4 | .\" | ||
| 5 | .\" Redistribution and use in source and binary forms, with or without | ||
| 6 | .\" modification, are permitted provided that the following conditions | ||
| 7 | .\" are met: | ||
| 8 | .\" 1. Redistributions of source code must retain the above copyright | ||
| 9 | .\" notice, this list of conditions and the following disclaimer. | ||
| 10 | .\" 2. Redistributions in binary form must reproduce the above copyright | ||
| 11 | .\" notice, this list of conditions and the following disclaimer in the | ||
| 12 | .\" documentation and/or other materials provided with the distribution. | ||
| 13 | .\" 3. Neither the name of the University nor the names of its contributors | ||
| 14 | .\" may be used to endorse or promote products derived from this software | ||
| 15 | .\" without specific prior written permission. | ||
| 16 | .\" | ||
| 17 | .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
| 18 | .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 19 | .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 20 | .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
| 21 | .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 22 | .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 23 | .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 24 | .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 25 | .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 26 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 27 | .\" SUCH DAMAGE. | ||
| 28 | .\" | ||
| 29 | .\" From: @(#)rcmd.3 8.1 (Berkeley) 6/4/93 | ||
| 30 | .\" | ||
| 31 | .Dd $Mdocdate: January 21 2014 $ | ||
| 32 | .Dt IF_NAMETOINDEX 3 | ||
| 33 | .Os | ||
| 34 | .Sh NAME | ||
| 35 | .Nm if_nametoindex , | ||
| 36 | .Nm if_indextoname , | ||
| 37 | .Nm if_nameindex , | ||
| 38 | .Nm if_freenameindex | ||
| 39 | .Nd convert interface index to name, and vice versa | ||
| 40 | .Sh SYNOPSIS | ||
| 41 | .In sys/types.h | ||
| 42 | .In sys/socket.h | ||
| 43 | .In net/if.h | ||
| 44 | .Ft "unsigned int" | ||
| 45 | .Fn if_nametoindex "const char *ifname" | ||
| 46 | .Ft "char *" | ||
| 47 | .Fn if_indextoname "unsigned int ifindex" "char *ifname" | ||
| 48 | .Ft "struct if_nameindex *" | ||
| 49 | .Fn if_nameindex "void" | ||
| 50 | .Ft "void" | ||
| 51 | .Fn if_freenameindex "struct if_nameindex *ptr" | ||
| 52 | .Sh DESCRIPTION | ||
| 53 | These functions map interface indexes to interface names (such as | ||
| 54 | .Dq lo0 ) , | ||
| 55 | and vice versa. | ||
| 56 | .Pp | ||
| 57 | The | ||
| 58 | .Fn if_nametoindex | ||
| 59 | function converts an interface name specified by the | ||
| 60 | .Fa ifname | ||
| 61 | argument to an interface index (positive integer value). | ||
| 62 | If the specified interface does not exist, 0 will be returned. | ||
| 63 | .Pp | ||
| 64 | .Fn if_indextoname | ||
| 65 | converts an interface index specified by the | ||
| 66 | .Fa ifindex | ||
| 67 | argument to an interface name. | ||
| 68 | The | ||
| 69 | .Fa ifname | ||
| 70 | argument must point to a buffer of at least | ||
| 71 | .Dv IF_NAMESIZE | ||
| 72 | bytes into which the interface name corresponding to the specified index is | ||
| 73 | returned. | ||
| 74 | .Pf ( Dv IF_NAMESIZE | ||
| 75 | is also defined in | ||
| 76 | .In net/if.h | ||
| 77 | and its value includes a terminating NUL byte at the end of the | ||
| 78 | interface name.) | ||
| 79 | This pointer is also the return value of the function. | ||
| 80 | If there is no interface corresponding to the specified index, | ||
| 81 | .Dv NULL | ||
| 82 | is returned. | ||
| 83 | .Pp | ||
| 84 | .Fn if_nameindex | ||
| 85 | returns an array of | ||
| 86 | .Vt if_nameindex | ||
| 87 | structures. | ||
| 88 | .Vt if_nameindex | ||
| 89 | is also defined in | ||
| 90 | .In net/if.h , | ||
| 91 | and is as follows: | ||
| 92 | .Bd -literal -offset indent | ||
| 93 | struct if_nameindex { | ||
| 94 | unsigned int if_index; /* 1, 2, ... */ | ||
| 95 | char *if_name; /* NUL-terminated name */ | ||
| 96 | }; | ||
| 97 | .Ed | ||
| 98 | .Pp | ||
| 99 | The end of the array of structures is indicated by a structure with | ||
| 100 | an | ||
| 101 | .Fa if_index | ||
| 102 | of 0 and an | ||
| 103 | .Fa if_name | ||
| 104 | of | ||
| 105 | .Dv NULL . | ||
| 106 | The function returns a null pointer on error. | ||
| 107 | The memory used for this array of structures along with the interface | ||
| 108 | names pointed to by the | ||
| 109 | .Fa if_name | ||
| 110 | members is obtained dynamically. | ||
| 111 | This memory is freed by the | ||
| 112 | .Fn if_freenameindex | ||
| 113 | function. | ||
| 114 | .Pp | ||
| 115 | .Fn if_freenameindex | ||
| 116 | takes a pointer that was returned by | ||
| 117 | .Fn if_nameindex | ||
| 118 | as argument | ||
| 119 | .Pq Fa ptr , | ||
| 120 | and it reclaims the region allocated. | ||
| 121 | .Sh DIAGNOSTICS | ||
| 122 | .Fn if_nametoindex | ||
| 123 | returns 0 on error, positive integer on success. | ||
| 124 | .Fn if_indextoname | ||
| 125 | and | ||
| 126 | .Fn if_nameindex | ||
| 127 | return | ||
| 128 | .Dv NULL | ||
| 129 | on errors. | ||
| 130 | .Sh SEE ALSO | ||
| 131 | .Xr getifaddrs 3 , | ||
| 132 | .Xr networking 4 | ||
| 133 | .Sh STANDARDS | ||
| 134 | .Rs | ||
| 135 | .%A R. Gilligan | ||
| 136 | .%A S. Thomson | ||
| 137 | .%A J. Bound | ||
| 138 | .%A J. McCann | ||
| 139 | .%A W. Stevens | ||
| 140 | .%D February 2003 | ||
| 141 | .%R RFC 3493 | ||
| 142 | .%T Basic Socket Interface Extensions for IPv6 | ||
| 143 | .Re | ||
diff --git a/src/lib/libc/net/if_indextoname.c b/src/lib/libc/net/if_indextoname.c new file mode 100644 index 0000000000..f99e52e387 --- /dev/null +++ b/src/lib/libc/net/if_indextoname.c | |||
| @@ -0,0 +1,86 @@ | |||
| 1 | /* $OpenBSD: if_indextoname.c,v 1.9 2002/03/07 22:40:23 millert Exp $ */ | ||
| 2 | /* $KAME: if_indextoname.c,v 1.6 2000/11/07 22:33:25 jinmei Exp $ */ | ||
| 3 | |||
| 4 | /*- | ||
| 5 | * Copyright (c) 1997, 2000 | ||
| 6 | * Berkeley Software Design, Inc. All rights reserved. | ||
| 7 | * | ||
| 8 | * Redistribution and use in source and binary forms, with or without | ||
| 9 | * modification, are permitted provided that the following conditions | ||
| 10 | * are met: | ||
| 11 | * 1. Redistributions of source code must retain the above copyright | ||
| 12 | * notice, this list of conditions and the following disclaimer. | ||
| 13 | * | ||
| 14 | * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND | ||
| 15 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 17 | * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE | ||
| 18 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 19 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 20 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 21 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 22 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 23 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 24 | * SUCH DAMAGE. | ||
| 25 | * | ||
| 26 | * BSDI Id: if_indextoname.c,v 2.3 2000/04/17 22:38:05 dab Exp | ||
| 27 | */ | ||
| 28 | |||
| 29 | #include <sys/types.h> | ||
| 30 | #include <sys/socket.h> | ||
| 31 | #include <net/if_dl.h> | ||
| 32 | #include <net/if.h> | ||
| 33 | #include <ifaddrs.h> | ||
| 34 | #include <stdlib.h> | ||
| 35 | #include <string.h> | ||
| 36 | #include <errno.h> | ||
| 37 | |||
| 38 | /* | ||
| 39 | * From RFC 2533: | ||
| 40 | * | ||
| 41 | * The second function maps an interface index into its corresponding | ||
| 42 | * name. | ||
| 43 | * | ||
| 44 | * #include <net/if.h> | ||
| 45 | * | ||
| 46 | * char *if_indextoname(unsigned int ifindex, char *ifname); | ||
| 47 | * | ||
| 48 | * The ifname argument must point to a buffer of at least IF_NAMESIZE | ||
| 49 | * bytes into which the interface name corresponding to the specified | ||
| 50 | * index is returned. (IF_NAMESIZE is also defined in <net/if.h> and | ||
| 51 | * its value includes a terminating null byte at the end of the | ||
| 52 | * interface name.) This pointer is also the return value of the | ||
| 53 | * function. If there is no interface corresponding to the specified | ||
| 54 | * index, NULL is returned, and errno is set to ENXIO, if there was a | ||
| 55 | * system error (such as running out of memory), if_indextoname returns | ||
| 56 | * NULL and errno would be set to the proper value (e.g., ENOMEM). | ||
| 57 | */ | ||
| 58 | |||
| 59 | char * | ||
| 60 | if_indextoname(unsigned int ifindex, char *ifname) | ||
| 61 | { | ||
| 62 | struct ifaddrs *ifaddrs, *ifa; | ||
| 63 | int error = 0; | ||
| 64 | |||
| 65 | if (getifaddrs(&ifaddrs) < 0) | ||
| 66 | return(NULL); /* getifaddrs properly set errno */ | ||
| 67 | |||
| 68 | for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) { | ||
| 69 | if (ifa->ifa_addr && | ||
| 70 | ifa->ifa_addr->sa_family == AF_LINK && | ||
| 71 | ifindex == ((struct sockaddr_dl*)ifa->ifa_addr)->sdl_index) | ||
| 72 | break; | ||
| 73 | } | ||
| 74 | |||
| 75 | if (ifa == NULL) { | ||
| 76 | error = ENXIO; | ||
| 77 | ifname = NULL; | ||
| 78 | } | ||
| 79 | else | ||
| 80 | strlcpy(ifname, ifa->ifa_name, IFNAMSIZ); | ||
| 81 | |||
| 82 | freeifaddrs(ifaddrs); | ||
| 83 | |||
| 84 | errno = error; | ||
| 85 | return(ifname); | ||
| 86 | } | ||
diff --git a/src/lib/libc/net/if_nameindex.c b/src/lib/libc/net/if_nameindex.c new file mode 100644 index 0000000000..c5a771869b --- /dev/null +++ b/src/lib/libc/net/if_nameindex.c | |||
| @@ -0,0 +1,146 @@ | |||
| 1 | /* $OpenBSD: if_nameindex.c,v 1.10 2010/09/24 13:29:29 claudio Exp $ */ | ||
| 2 | /* $KAME: if_nameindex.c,v 1.7 2000/11/24 08:17:20 itojun Exp $ */ | ||
| 3 | |||
| 4 | /*- | ||
| 5 | * Copyright (c) 1997, 2000 | ||
| 6 | * Berkeley Software Design, Inc. All rights reserved. | ||
| 7 | * | ||
| 8 | * Redistribution and use in source and binary forms, with or without | ||
| 9 | * modification, are permitted provided that the following conditions | ||
| 10 | * are met: | ||
| 11 | * 1. Redistributions of source code must retain the above copyright | ||
| 12 | * notice, this list of conditions and the following disclaimer. | ||
| 13 | * | ||
| 14 | * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND | ||
| 15 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 17 | * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE | ||
| 18 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 19 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 20 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 21 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 22 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 23 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 24 | * SUCH DAMAGE. | ||
| 25 | * | ||
| 26 | * BSDI Id: if_nameindex.c,v 2.3 2000/04/17 22:38:05 dab Exp | ||
| 27 | */ | ||
| 28 | |||
| 29 | #include <sys/types.h> | ||
| 30 | #include <sys/socket.h> | ||
| 31 | #include <net/if_dl.h> | ||
| 32 | #include <net/if.h> | ||
| 33 | #include <ifaddrs.h> | ||
| 34 | #include <stdlib.h> | ||
| 35 | #include <string.h> | ||
| 36 | |||
| 37 | /* | ||
| 38 | * From RFC 2553: | ||
| 39 | * | ||
| 40 | * 4.3 Return All Interface Names and Indexes | ||
| 41 | * | ||
| 42 | * The if_nameindex structure holds the information about a single | ||
| 43 | * interface and is defined as a result of including the <net/if.h> | ||
| 44 | * header. | ||
| 45 | * | ||
| 46 | * struct if_nameindex { | ||
| 47 | * unsigned int if_index; | ||
| 48 | * char *if_name; | ||
| 49 | * }; | ||
| 50 | * | ||
| 51 | * The final function returns an array of if_nameindex structures, one | ||
| 52 | * structure per interface. | ||
| 53 | * | ||
| 54 | * struct if_nameindex *if_nameindex(void); | ||
| 55 | * | ||
| 56 | * The end of the array of structures is indicated by a structure with | ||
| 57 | * an if_index of 0 and an if_name of NULL. The function returns a NULL | ||
| 58 | * pointer upon an error, and would set errno to the appropriate value. | ||
| 59 | * | ||
| 60 | * The memory used for this array of structures along with the interface | ||
| 61 | * names pointed to by the if_name members is obtained dynamically. | ||
| 62 | * This memory is freed by the next function. | ||
| 63 | * | ||
| 64 | * 4.4. Free Memory | ||
| 65 | * | ||
| 66 | * The following function frees the dynamic memory that was allocated by | ||
| 67 | * if_nameindex(). | ||
| 68 | * | ||
| 69 | * #include <net/if.h> | ||
| 70 | * | ||
| 71 | * void if_freenameindex(struct if_nameindex *ptr); | ||
| 72 | * | ||
| 73 | * The argument to this function must be a pointer that was returned by | ||
| 74 | * if_nameindex(). | ||
| 75 | */ | ||
| 76 | |||
| 77 | struct if_nameindex * | ||
| 78 | if_nameindex(void) | ||
| 79 | { | ||
| 80 | struct ifaddrs *ifaddrs, *ifa; | ||
| 81 | unsigned int ni; | ||
| 82 | size_t nbytes; | ||
| 83 | struct if_nameindex *ifni, *ifni2; | ||
| 84 | char *cp; | ||
| 85 | |||
| 86 | if (getifaddrs(&ifaddrs) < 0) | ||
| 87 | return(NULL); | ||
| 88 | |||
| 89 | /* | ||
| 90 | * First, find out how many interfaces there are, and how | ||
| 91 | * much space we need for the string names. | ||
| 92 | */ | ||
| 93 | ni = 0; | ||
| 94 | nbytes = 0; | ||
| 95 | for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) { | ||
| 96 | if (ifa->ifa_addr && | ||
| 97 | ifa->ifa_addr->sa_family == AF_LINK) { | ||
| 98 | nbytes += strlen(ifa->ifa_name) + 1; | ||
| 99 | ni++; | ||
| 100 | } | ||
| 101 | } | ||
| 102 | |||
| 103 | /* | ||
| 104 | * Next, allocate a chunk of memory, use the first part | ||
| 105 | * for the array of structures, and the last part for | ||
| 106 | * the strings. | ||
| 107 | */ | ||
| 108 | cp = malloc((ni + 1) * sizeof(struct if_nameindex) + nbytes); | ||
| 109 | ifni = (struct if_nameindex *)cp; | ||
| 110 | if (ifni == NULL) | ||
| 111 | goto out; | ||
| 112 | cp += (ni + 1) * sizeof(struct if_nameindex); | ||
| 113 | |||
| 114 | /* | ||
| 115 | * Now just loop through the list of interfaces again, | ||
| 116 | * filling in the if_nameindex array and making copies | ||
| 117 | * of all the strings. | ||
| 118 | */ | ||
| 119 | ifni2 = ifni; | ||
| 120 | for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) { | ||
| 121 | if (ifa->ifa_addr && | ||
| 122 | ifa->ifa_addr->sa_family == AF_LINK) { | ||
| 123 | ifni2->if_index = | ||
| 124 | ((struct sockaddr_dl*)ifa->ifa_addr)->sdl_index; | ||
| 125 | ifni2->if_name = cp; | ||
| 126 | nbytes = strlen(ifa->ifa_name) + 1; | ||
| 127 | memcpy(cp, ifa->ifa_name, nbytes); | ||
| 128 | ifni2++; | ||
| 129 | cp += nbytes; | ||
| 130 | } | ||
| 131 | } | ||
| 132 | /* | ||
| 133 | * Finally, don't forget to terminate the array. | ||
| 134 | */ | ||
| 135 | ifni2->if_index = 0; | ||
| 136 | ifni2->if_name = NULL; | ||
| 137 | out: | ||
| 138 | freeifaddrs(ifaddrs); | ||
| 139 | return(ifni); | ||
| 140 | } | ||
| 141 | |||
| 142 | void | ||
| 143 | if_freenameindex(struct if_nameindex *ptr) | ||
| 144 | { | ||
| 145 | free(ptr); | ||
| 146 | } | ||
diff --git a/src/lib/libc/net/if_nametoindex.c b/src/lib/libc/net/if_nametoindex.c new file mode 100644 index 0000000000..8bd792b949 --- /dev/null +++ b/src/lib/libc/net/if_nametoindex.c | |||
| @@ -0,0 +1,81 @@ | |||
| 1 | /* $OpenBSD: if_nametoindex.c,v 1.8 2002/03/07 22:40:23 millert Exp $ */ | ||
| 2 | /* $KAME: if_nametoindex.c,v 1.5 2000/11/24 08:04:40 itojun Exp $ */ | ||
| 3 | |||
| 4 | /*- | ||
| 5 | * Copyright (c) 1997, 2000 | ||
| 6 | * Berkeley Software Design, Inc. All rights reserved. | ||
| 7 | * | ||
| 8 | * Redistribution and use in source and binary forms, with or without | ||
| 9 | * modification, are permitted provided that the following conditions | ||
| 10 | * are met: | ||
| 11 | * 1. Redistributions of source code must retain the above copyright | ||
| 12 | * notice, this list of conditions and the following disclaimer. | ||
| 13 | * | ||
| 14 | * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND | ||
| 15 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 17 | * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE | ||
| 18 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 19 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 20 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 21 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 22 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 23 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 24 | * SUCH DAMAGE. | ||
| 25 | * | ||
| 26 | * BSDI Id: if_nametoindex.c,v 2.3 2000/04/17 22:38:05 dab Exp | ||
| 27 | */ | ||
| 28 | |||
| 29 | #include <sys/types.h> | ||
| 30 | #include <sys/socket.h> | ||
| 31 | #include <net/if.h> | ||
| 32 | #include <net/if_dl.h> | ||
| 33 | #include <ifaddrs.h> | ||
| 34 | #include <stdlib.h> | ||
| 35 | #include <string.h> | ||
| 36 | #include <errno.h> | ||
| 37 | |||
| 38 | /* | ||
| 39 | * From RFC 2553: | ||
| 40 | * | ||
| 41 | * 4.1 Name-to-Index | ||
| 42 | * | ||
| 43 | * | ||
| 44 | * The first function maps an interface name into its corresponding | ||
| 45 | * index. | ||
| 46 | * | ||
| 47 | * #include <net/if.h> | ||
| 48 | * | ||
| 49 | * unsigned int if_nametoindex(const char *ifname); | ||
| 50 | * | ||
| 51 | * If the specified interface name does not exist, the return value is | ||
| 52 | * 0, and errno is set to ENXIO. If there was a system error (such as | ||
| 53 | * running out of memory), the return value is 0 and errno is set to the | ||
| 54 | * proper value (e.g., ENOMEM). | ||
| 55 | */ | ||
| 56 | |||
| 57 | unsigned int | ||
| 58 | if_nametoindex(const char *ifname) | ||
| 59 | { | ||
| 60 | struct ifaddrs *ifaddrs, *ifa; | ||
| 61 | unsigned int ni; | ||
| 62 | |||
| 63 | if (getifaddrs(&ifaddrs) < 0) | ||
| 64 | return(0); | ||
| 65 | |||
| 66 | ni = 0; | ||
| 67 | |||
| 68 | for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) { | ||
| 69 | if (ifa->ifa_addr && | ||
| 70 | ifa->ifa_addr->sa_family == AF_LINK && | ||
| 71 | strcmp(ifa->ifa_name, ifname) == 0) { | ||
| 72 | ni = ((struct sockaddr_dl*)ifa->ifa_addr)->sdl_index; | ||
| 73 | break; | ||
| 74 | } | ||
| 75 | } | ||
| 76 | |||
| 77 | freeifaddrs(ifaddrs); | ||
| 78 | if (!ni) | ||
| 79 | errno = ENXIO; | ||
| 80 | return(ni); | ||
| 81 | } | ||
diff --git a/src/lib/libc/net/inet.3 b/src/lib/libc/net/inet.3 index 49bac97e96..e56ca0a59a 100644 --- a/src/lib/libc/net/inet.3 +++ b/src/lib/libc/net/inet.3 | |||
| @@ -1,4 +1,5 @@ | |||
| 1 | .\" $NetBSD: inet.3,v 1.4 1995/02/27 09:45:26 chopps Exp $ | 1 | .\" $OpenBSD: inet.3,v 1.26 2013/06/05 03:39:23 tedu Exp $ |
| 2 | .\" $NetBSD: inet.3,v 1.7 1997/06/18 02:25:24 lukem Exp $ | ||
| 2 | .\" | 3 | .\" |
| 3 | .\" Copyright (c) 1983, 1990, 1991, 1993 | 4 | .\" Copyright (c) 1983, 1990, 1991, 1993 |
| 4 | .\" The Regents of the University of California. All rights reserved. | 5 | .\" The Regents of the University of California. All rights reserved. |
| @@ -11,11 +12,7 @@ | |||
| 11 | .\" 2. Redistributions in binary form must reproduce the above copyright | 12 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 12 | .\" notice, this list of conditions and the following disclaimer in the | 13 | .\" notice, this list of conditions and the following disclaimer in the |
| 13 | .\" documentation and/or other materials provided with the distribution. | 14 | .\" documentation and/or other materials provided with the distribution. |
| 14 | .\" 3. All advertising materials mentioning features or use of this software | 15 | .\" 3. Neither the name of the University nor the names of its contributors |
| 15 | .\" must display the following acknowledgement: | ||
| 16 | .\" This product includes software developed by the University of | ||
| 17 | .\" California, Berkeley and its contributors. | ||
| 18 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 19 | .\" may be used to endorse or promote products derived from this software | 16 | .\" may be used to endorse or promote products derived from this software |
| 20 | .\" without specific prior written permission. | 17 | .\" without specific prior written permission. |
| 21 | .\" | 18 | .\" |
| @@ -33,52 +30,61 @@ | |||
| 33 | .\" | 30 | .\" |
| 34 | .\" @(#)inet.3 8.1 (Berkeley) 6/4/93 | 31 | .\" @(#)inet.3 8.1 (Berkeley) 6/4/93 |
| 35 | .\" | 32 | .\" |
| 36 | .Dd June 4, 1993 | 33 | .Dd $Mdocdate: June 5 2013 $ |
| 37 | .Dt INET 3 | 34 | .Dt INET 3 |
| 38 | .Os BSD 4.2 | 35 | .Os |
| 39 | .Sh NAME | 36 | .Sh NAME |
| 40 | .Nm inet_aton , | 37 | .Nm inet_aton , |
| 41 | .Nm inet_addr , | 38 | .Nm inet_addr , |
| 42 | .Nm inet_network , | 39 | .Nm inet_network , |
| 40 | .Nm inet_pton , | ||
| 41 | .Nm inet_ntop , | ||
| 43 | .Nm inet_ntoa , | 42 | .Nm inet_ntoa , |
| 44 | .Nm inet_makeaddr , | 43 | .Nm inet_makeaddr , |
| 45 | .Nm inet_lnaof , | 44 | .Nm inet_netof , |
| 46 | .Nm inet_netof | 45 | .Nm inet_lnaof |
| 47 | .Nd Internet address manipulation routines | 46 | .Nd Internet address manipulation routines |
| 48 | .Sh SYNOPSIS | 47 | .Sh SYNOPSIS |
| 49 | .Fd #include <sys/socket.h> | 48 | .In sys/types.h |
| 50 | .Fd #include <netinet/in.h> | 49 | .In sys/socket.h |
| 51 | .Fd #include <arpa/inet.h> | 50 | .In netinet/in.h |
| 52 | .Ft int | 51 | .In arpa/inet.h |
| 53 | .Fn inet_aton "const char *cp" "struct in_addr *pin" | 52 | .Ft int |
| 54 | .Ft unsigned long | 53 | .Fn inet_aton "const char *cp" "struct in_addr *addr" |
| 54 | .Ft in_addr_t | ||
| 55 | .Fn inet_addr "const char *cp" | 55 | .Fn inet_addr "const char *cp" |
| 56 | .Ft unsigned long | 56 | .Ft in_addr_t |
| 57 | .Fn inet_network "const char *cp" | 57 | .Fn inet_network "const char *cp" |
| 58 | .Ft int | ||
| 59 | .Fn inet_pton "int af" "const char *src" "void *dst" | ||
| 60 | .Ft const char * | ||
| 61 | .Fn inet_ntop "int af" "const void *src" "char *dst" "socklen_t size" | ||
| 58 | .Ft char * | 62 | .Ft char * |
| 59 | .Fn inet_ntoa "struct in_addr in" | 63 | .Fn inet_ntoa "struct in_addr in" |
| 60 | .Ft struct in_addr | 64 | .Ft struct in_addr |
| 61 | .Fn inet_makeaddr "int net" "int lna" | 65 | .Fn inet_makeaddr "in_addr_t net" "in_addr_t lna" |
| 62 | .Ft unsigned long | 66 | .Ft in_addr_t |
| 63 | .Fn inet_lnaof "struct in_addr in" | ||
| 64 | .Ft unsigned long | ||
| 65 | .Fn inet_netof "struct in_addr in" | 67 | .Fn inet_netof "struct in_addr in" |
| 68 | .Ft in_addr_t | ||
| 69 | .Fn inet_lnaof "struct in_addr in" | ||
| 66 | .Sh DESCRIPTION | 70 | .Sh DESCRIPTION |
| 67 | The routines | 71 | The routines |
| 68 | .Fn inet_aton , | 72 | .Fn inet_aton , |
| 69 | .Fn inet_addr | 73 | .Fn inet_addr , |
| 70 | and | 74 | and |
| 71 | .Fn inet_network | 75 | .Fn inet_network |
| 72 | interpret character strings representing | 76 | interpret character strings representing |
| 73 | numbers expressed in the Internet standard | 77 | numbers expressed in the Internet standard |
| 74 | .Ql \&. | 78 | .Dq dot |
| 75 | notation. | 79 | notation. |
| 80 | .Pp | ||
| 76 | The | 81 | The |
| 77 | .Fn inet_aton | 82 | .Fn inet_aton |
| 78 | routine interprets the specified character string as an Internet address, | 83 | routine interprets the specified character string as an Internet address, |
| 79 | placing the address into the structure provided. | 84 | placing the address into the structure provided. |
| 80 | It returns 1 if the string was successfully interpreted, | 85 | It returns 1 if the string was successfully interpreted, |
| 81 | or 0 if the string is invalid. | 86 | or 0 if the string was invalid. |
| 87 | .Pp | ||
| 82 | The | 88 | The |
| 83 | .Fn inet_addr | 89 | .Fn inet_addr |
| 84 | and | 90 | and |
| @@ -86,17 +92,51 @@ and | |||
| 86 | functions return numbers suitable for use | 92 | functions return numbers suitable for use |
| 87 | as Internet addresses and Internet network | 93 | as Internet addresses and Internet network |
| 88 | numbers, respectively. | 94 | numbers, respectively. |
| 95 | Both functions return the constant | ||
| 96 | .Dv INADDR_NONE | ||
| 97 | if the specified character string is malformed. | ||
| 98 | .Pp | ||
| 99 | The | ||
| 100 | .Fn inet_pton | ||
| 101 | function converts a presentation format address (that is, printable form | ||
| 102 | as held in a character string) to network format (usually a | ||
| 103 | .Li struct in_addr | ||
| 104 | or some other internal binary representation, in network byte order). | ||
| 105 | It returns 1 if the address was valid for the specified address family; | ||
| 106 | 0 if the address wasn't parseable in the specified address family; or \-1 | ||
| 107 | if some system error occurred (in which case | ||
| 108 | .Va errno | ||
| 109 | will have been set). | ||
| 110 | This function is presently valid for | ||
| 111 | .Dv AF_INET | ||
| 112 | and | ||
| 113 | .Dv AF_INET6 . | ||
| 114 | .Pp | ||
| 115 | The function | ||
| 116 | .Fn inet_ntop | ||
| 117 | converts an address from network format (usually a | ||
| 118 | .Li struct in_addr | ||
| 119 | or some other binary form, in network byte order) to presentation format | ||
| 120 | (suitable for external display purposes). | ||
| 121 | It returns | ||
| 122 | .Dv NULL | ||
| 123 | if a system | ||
| 124 | error occurs (in which case, | ||
| 125 | .Va errno | ||
| 126 | will have been set), or it returns a pointer to the destination string. | ||
| 127 | .Pp | ||
| 89 | The routine | 128 | The routine |
| 90 | .Fn inet_ntoa | 129 | .Fn inet_ntoa |
| 91 | takes an Internet address and returns an | 130 | takes an Internet address and returns an |
| 92 | .Tn ASCII | 131 | ASCII string representing the address in dot notation. |
| 93 | string representing the address in | 132 | .Pp |
| 94 | .Ql \&. | 133 | The routine |
| 95 | notation. The routine | ||
| 96 | .Fn inet_makeaddr | 134 | .Fn inet_makeaddr |
| 97 | takes an Internet network number and a local | 135 | takes an Internet network number and a local |
| 98 | network address and constructs an Internet address | 136 | network address and constructs an Internet address |
| 99 | from it. The routines | 137 | from it. |
| 138 | .Pp | ||
| 139 | The routines | ||
| 100 | .Fn inet_netof | 140 | .Fn inet_netof |
| 101 | and | 141 | and |
| 102 | .Fn inet_lnaof | 142 | .Fn inet_lnaof |
| @@ -108,11 +148,8 @@ All Internet addresses are returned in network | |||
| 108 | order (bytes ordered from left to right). | 148 | order (bytes ordered from left to right). |
| 109 | All network numbers and local address parts are | 149 | All network numbers and local address parts are |
| 110 | returned as machine format integer values. | 150 | returned as machine format integer values. |
| 111 | .Sh INTERNET ADDRESSES | 151 | .Sh INTERNET ADDRESSES (IP VERSION 4) |
| 112 | Values specified using the | 152 | Values specified using dot notation take one of the following forms: |
| 113 | .Ql \&. | ||
| 114 | notation take one | ||
| 115 | of the following forms: | ||
| 116 | .Bd -literal -offset indent | 153 | .Bd -literal -offset indent |
| 117 | a.b.c.d | 154 | a.b.c.d |
| 118 | a.b.c | 155 | a.b.c |
| @@ -122,28 +159,25 @@ a | |||
| 122 | .Pp | 159 | .Pp |
| 123 | When four parts are specified, each is interpreted | 160 | When four parts are specified, each is interpreted |
| 124 | as a byte of data and assigned, from left to right, | 161 | as a byte of data and assigned, from left to right, |
| 125 | to the four bytes of an Internet address. Note | 162 | to the four bytes of an Internet address. |
| 126 | that when an Internet address is viewed as a 32-bit | 163 | Note that when an Internet address is viewed as a 32-bit |
| 127 | integer quantity on the | 164 | integer quantity on a system that uses little-endian |
| 128 | .Tn VAX | 165 | byte order |
| 129 | the bytes referred to | 166 | (such as the Intel 386, 486 and Pentium processors) |
| 130 | above appear as | 167 | the bytes referred to above appear as |
| 131 | .Dq Li d.c.b.a . | 168 | .Dq Li d.c.b.a . |
| 132 | That is, | 169 | That is, little-endian bytes are ordered from right to left. |
| 133 | .Tn VAX | ||
| 134 | bytes are | ||
| 135 | ordered from right to left. | ||
| 136 | .Pp | 170 | .Pp |
| 137 | When a three part address is specified, the last | 171 | When a three part address is specified, the last |
| 138 | part is interpreted as a 16-bit quantity and placed | 172 | part is interpreted as a 16-bit quantity and placed |
| 139 | in the right-most two bytes of the network address. | 173 | in the rightmost two bytes of the network address. |
| 140 | This makes the three part address format convenient | 174 | This makes the three part address format convenient |
| 141 | for specifying Class B network addresses as | 175 | for specifying Class B network addresses as |
| 142 | .Dq Li 128.net.host . | 176 | .Dq Li 128.net.host . |
| 143 | .Pp | 177 | .Pp |
| 144 | When a two part address is supplied, the last part | 178 | When a two part address is supplied, the last part |
| 145 | is interpreted as a 24-bit quantity and placed in | 179 | is interpreted as a 24-bit quantity and placed in |
| 146 | the right most three bytes of the network address. | 180 | the rightmost three bytes of the network address. |
| 147 | This makes the two part address format convenient | 181 | This makes the two part address format convenient |
| 148 | for specifying Class A network addresses as | 182 | for specifying Class A network addresses as |
| 149 | .Dq Li net.host . | 183 | .Dq Li net.host . |
| @@ -154,44 +188,168 @@ rearrangement. | |||
| 154 | .Pp | 188 | .Pp |
| 155 | All numbers supplied as | 189 | All numbers supplied as |
| 156 | .Dq parts | 190 | .Dq parts |
| 157 | in a | 191 | in a dot notation |
| 158 | .Ql \&. | ||
| 159 | notation | ||
| 160 | may be decimal, octal, or hexadecimal, as specified | 192 | may be decimal, octal, or hexadecimal, as specified |
| 161 | in the C language (i.e., a leading 0x or 0X implies | 193 | in the C language (i.e., a leading 0x or 0X implies |
| 162 | hexadecimal; otherwise, a leading 0 implies octal; | 194 | hexadecimal; a leading 0 implies octal; |
| 163 | otherwise, the number is interpreted as decimal). | 195 | otherwise, the number is interpreted as decimal). |
| 164 | .Sh DIAGNOSTICS | 196 | .Sh INTERNET ADDRESSES (IP VERSION 6) |
| 165 | The constant | 197 | In order to support scoped IPv6 addresses, |
| 166 | .Dv INADDR_NONE | 198 | .Xr getaddrinfo 3 |
| 167 | is returned by | ||
| 168 | .Fn inet_addr | ||
| 169 | and | 199 | and |
| 170 | .Fn inet_network | 200 | .Xr getnameinfo 3 |
| 171 | for malformed requests. | 201 | are recommended rather than the functions presented here. |
| 202 | .Pp | ||
| 203 | The presentation format of an IPv6 address is given in RFC 4291: | ||
| 204 | .Pp | ||
| 205 | There are three conventional forms for representing IPv6 addresses as | ||
| 206 | text strings: | ||
| 207 | .Bl -enum | ||
| 208 | .It | ||
| 209 | The preferred form is x:x:x:x:x:x:x:x, where the 'x's are the | ||
| 210 | hexadecimal values of the eight 16-bit pieces of the address. | ||
| 211 | Examples: | ||
| 212 | .Bd -literal -offset indent | ||
| 213 | FEDC:BA98:7654:3210:FEDC:BA98:7654:3210 | ||
| 214 | 1080:0:0:0:8:800:200C:417A | ||
| 215 | .Ed | ||
| 216 | .Pp | ||
| 217 | Note that it is not necessary to write the leading zeros in an | ||
| 218 | individual field, but there must be at least one numeral in | ||
| 219 | every field (except for the case described in 2.). | ||
| 220 | .It | ||
| 221 | Due to the method of allocating certain styles of IPv6 | ||
| 222 | addresses, it will be common for addresses to contain long | ||
| 223 | strings of zero bits. | ||
| 224 | In order to make writing addresses | ||
| 225 | containing zero bits easier, a special syntax is available to | ||
| 226 | compress the zeros. | ||
| 227 | The use of | ||
| 228 | .Dq \&:\&: | ||
| 229 | indicates multiple groups | ||
| 230 | of 16 bits of zeros. | ||
| 231 | The | ||
| 232 | .Dq \&:\&: | ||
| 233 | can only appear once in an | ||
| 234 | address. | ||
| 235 | The | ||
| 236 | .Dq \&:\&: | ||
| 237 | can also be used to compress the leading and/or trailing zeros in an address. | ||
| 238 | .Pp | ||
| 239 | For example the following addresses: | ||
| 240 | .Bd -literal -offset indent | ||
| 241 | 1080:0:0:0:8:800:200C:417A a unicast address | ||
| 242 | FF01:0:0:0:0:0:0:43 a multicast address | ||
| 243 | 0:0:0:0:0:0:0:1 the loopback address | ||
| 244 | 0:0:0:0:0:0:0:0 the unspecified addresses | ||
| 245 | .Ed | ||
| 246 | .Pp | ||
| 247 | may be represented as: | ||
| 248 | .Bd -literal -offset indent | ||
| 249 | 1080::8:800:200C:417A a unicast address | ||
| 250 | FF01::43 a multicast address | ||
| 251 | ::1 the loopback address | ||
| 252 | :: the unspecified addresses | ||
| 253 | .Ed | ||
| 254 | .It | ||
| 255 | An alternative form that is sometimes more convenient when | ||
| 256 | dealing with a mixed environment of IPv4 and IPv6 nodes is | ||
| 257 | x:x:x:x:x:x:d.d.d.d, where the 'x's are the hexadecimal values | ||
| 258 | of the six high-order 16-bit pieces of the address, and the 'd's | ||
| 259 | are the decimal values of the four low-order 8-bit pieces of the | ||
| 260 | address (standard IPv4 representation). | ||
| 261 | Examples: | ||
| 262 | .Bd -literal -offset indent | ||
| 263 | 0:0:0:0:0:0:13.1.68.3 | ||
| 264 | 0:0:0:0:0:FFFF:129.144.52.38 | ||
| 265 | .Ed | ||
| 266 | .Pp | ||
| 267 | or in compressed form: | ||
| 268 | .Bd -literal -offset indent | ||
| 269 | ::13.1.68.3 | ||
| 270 | ::FFFF:129.144.52.38 | ||
| 271 | .Ed | ||
| 272 | .El | ||
| 172 | .Sh SEE ALSO | 273 | .Sh SEE ALSO |
| 274 | .Xr byteorder 3 , | ||
| 173 | .Xr gethostbyname 3 , | 275 | .Xr gethostbyname 3 , |
| 174 | .Xr getnetent 3 , | 276 | .Xr getnetent 3 , |
| 277 | .Xr inet_net 3 , | ||
| 175 | .Xr hosts 5 , | 278 | .Xr hosts 5 , |
| 176 | .Xr networks 5 , | 279 | .Xr networks 5 |
| 280 | .Sh STANDARDS | ||
| 281 | The | ||
| 282 | .Nm inet_ntop | ||
| 283 | and | ||
| 284 | .Nm inet_pton | ||
| 285 | functions conform to the IETF IPv6 BSD API and address formatting | ||
| 286 | specifications. | ||
| 287 | Note that | ||
| 288 | .Nm inet_pton | ||
| 289 | does not accept 1-, 2-, or 3-part dotted addresses; all four parts | ||
| 290 | must be specified. | ||
| 291 | This is a narrower input set than that accepted by | ||
| 292 | .Nm inet_aton . | ||
| 293 | .Pp | ||
| 294 | .Rs | ||
| 295 | .%A R. Gilligan | ||
| 296 | .%A S. Thomson | ||
| 297 | .%A J. Bound | ||
| 298 | .%A J. McCann | ||
| 299 | .%A W. Stevens | ||
| 300 | .%D February 2003 | ||
| 301 | .%R RFC 3493 | ||
| 302 | .%T Basic Socket Interface Extensions for IPv6 | ||
| 303 | .Re | ||
| 304 | .Pp | ||
| 305 | .Rs | ||
| 306 | .%A R. Hinden | ||
| 307 | .%A S. Deering | ||
| 308 | .%D February 2006 | ||
| 309 | .%R RFC 4291 | ||
| 310 | .%T IP Version 6 Addressing Architecture | ||
| 311 | .Re | ||
| 177 | .Sh HISTORY | 312 | .Sh HISTORY |
| 178 | These | 313 | The |
| 179 | functions appeared in | 314 | .Nm inet_addr , |
| 315 | .Nm inet_network , | ||
| 316 | .Nm inet_makeaddr , | ||
| 317 | .Nm inet_lnaof , | ||
| 318 | and | ||
| 319 | .Nm inet_netof | ||
| 320 | functions appeared in | ||
| 180 | .Bx 4.2 . | 321 | .Bx 4.2 . |
| 322 | The | ||
| 323 | .Nm inet_aton | ||
| 324 | and | ||
| 325 | .Nm inet_ntoa | ||
| 326 | functions appeared in | ||
| 327 | .Bx 4.3 . | ||
| 328 | The | ||
| 329 | .Nm inet_pton | ||
| 330 | and | ||
| 331 | .Nm inet_ntop | ||
| 332 | functions appeared in BIND 4.9.4. | ||
| 181 | .Sh BUGS | 333 | .Sh BUGS |
| 182 | The value | 334 | The value |
| 183 | .Dv INADDR_NONE | 335 | .Dv INADDR_NONE |
| 184 | (0xffffffff) is a valid broadcast address, but | 336 | (0xffffffff) is a valid broadcast address, but |
| 185 | .Fn inet_addr | 337 | .Fn inet_addr |
| 186 | cannot return that value without indicating failure. | 338 | cannot return that value without indicating failure. |
| 339 | Also, | ||
| 340 | .Fn inet_addr | ||
| 341 | should have been designed to return a | ||
| 342 | .Li struct in_addr . | ||
| 187 | The newer | 343 | The newer |
| 188 | .Fn inet_aton | 344 | .Fn inet_aton |
| 189 | function does not share this problem. | 345 | function does not share these problems, and almost all existing code |
| 346 | should be modified to use | ||
| 347 | .Fn inet_aton | ||
| 348 | instead. | ||
| 349 | .Pp | ||
| 190 | The problem of host byte ordering versus network byte ordering is | 350 | The problem of host byte ordering versus network byte ordering is |
| 191 | confusing. | 351 | confusing. |
| 352 | .Pp | ||
| 192 | The string returned by | 353 | The string returned by |
| 193 | .Fn inet_ntoa | 354 | .Fn inet_ntoa |
| 194 | resides in a static memory area. | 355 | resides in a static memory area. |
| 195 | .Pp | ||
| 196 | Inet_addr should return a | ||
| 197 | .Fa struct in_addr . | ||
diff --git a/src/lib/libc/net/inet6_opt_init.3 b/src/lib/libc/net/inet6_opt_init.3 new file mode 100644 index 0000000000..dd7ab53f6f --- /dev/null +++ b/src/lib/libc/net/inet6_opt_init.3 | |||
| @@ -0,0 +1,328 @@ | |||
| 1 | .\" $OpenBSD: inet6_opt_init.3,v 1.6 2014/01/21 03:15:45 schwarze Exp $ | ||
| 2 | .\" $KAME: inet6_opt_init.3,v 1.7 2004/12/27 05:08:23 itojun Exp $ | ||
| 3 | .\" | ||
| 4 | .\" Copyright (C) 2004 WIDE Project. | ||
| 5 | .\" All rights reserved. | ||
| 6 | .\" | ||
| 7 | .\" Redistribution and use in source and binary forms, with or without | ||
| 8 | .\" modification, are permitted provided that the following conditions | ||
| 9 | .\" are met: | ||
| 10 | .\" 1. Redistributions of source code must retain the above copyright | ||
| 11 | .\" notice, this list of conditions and the following disclaimer. | ||
| 12 | .\" 2. Redistributions in binary form must reproduce the above copyright | ||
| 13 | .\" notice, this list of conditions and the following disclaimer in the | ||
| 14 | .\" documentation and/or other materials provided with the distribution. | ||
| 15 | .\" 3. Neither the name of the project nor the names of its contributors | ||
| 16 | .\" may be used to endorse or promote products derived from this software | ||
| 17 | .\" without specific prior written permission. | ||
| 18 | .\" | ||
| 19 | .\" THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND | ||
| 20 | .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 21 | .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 22 | .\" ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE | ||
| 23 | .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 24 | .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 25 | .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 26 | .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 28 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 29 | .\" SUCH DAMAGE. | ||
| 30 | .\" | ||
| 31 | .Dd $Mdocdate: January 21 2014 $ | ||
| 32 | .Dt INET6_OPT_INIT 3 | ||
| 33 | .Os | ||
| 34 | .\" | ||
| 35 | .Sh NAME | ||
| 36 | .Nm inet6_opt_init , | ||
| 37 | .Nm inet6_opt_append , | ||
| 38 | .Nm inet6_opt_finish , | ||
| 39 | .Nm inet6_opt_set_val , | ||
| 40 | .Nm inet6_opt_next , | ||
| 41 | .Nm inet6_opt_find , | ||
| 42 | .Nm inet6_opt_get_val | ||
| 43 | .Nd IPv6 Hop-by-Hop and Destination Options manipulation | ||
| 44 | .\" | ||
| 45 | .Sh SYNOPSIS | ||
| 46 | .In netinet/in.h | ||
| 47 | .Ft "int" | ||
| 48 | .Fn inet6_opt_init "void *extbuf" "socklen_t extlen" | ||
| 49 | .Ft "int" | ||
| 50 | .Fn inet6_opt_append "void *extbuf" "socklen_t extlen" "int offset" "u_int8_t type" "socklen_t len" "u_int8_t align" "void **databufp" | ||
| 51 | .Ft "int" | ||
| 52 | .Fn inet6_opt_finish "void *extbuf" "socklen_t extlen" "int offset" | ||
| 53 | .Ft "int" | ||
| 54 | .Fn inet6_opt_set_val "void *databuf" "int offset" "void *val" "socklen_t vallen" | ||
| 55 | .Ft "int" | ||
| 56 | .Fn inet6_opt_next "void *extbuf" "socklen_t extlen" "int offset" "u_int8_t *typep" "socklen_t *lenp" "void **databufp" | ||
| 57 | .Ft "int" | ||
| 58 | .Fn inet6_opt_find "void *extbuf" "socklen_t extlen" "int offset" "u_int8_t type" "socklen_t *lenp" "void **databufp" | ||
| 59 | .Ft "int" | ||
| 60 | .Fn inet6_opt_get_val "void *databuf" "socklen_t offset" "void *val" "socklen_t vallen" | ||
| 61 | .\" | ||
| 62 | .Sh DESCRIPTION | ||
| 63 | Building and parsing the Hop-by-Hop and Destination options is | ||
| 64 | complicated. | ||
| 65 | The advanced sockets API defines a set of functions to | ||
| 66 | help applications create and manipulate Hop-by-Hop and Destination | ||
| 67 | options. | ||
| 68 | These functions use the | ||
| 69 | formatting rules specified in Appendix B in RFC 2460, i.e. that the | ||
| 70 | largest field is placed last in the option. | ||
| 71 | The function prototypes | ||
| 72 | for these functions are all contained in the header file | ||
| 73 | .In netinet/in.h . | ||
| 74 | .\" | ||
| 75 | .Ss inet6_opt_init | ||
| 76 | The | ||
| 77 | .Fn inet6_opt_init | ||
| 78 | function | ||
| 79 | returns the number of bytes needed for an empty | ||
| 80 | extension header, one without any options. | ||
| 81 | If the | ||
| 82 | .Va extbuf | ||
| 83 | argument points to a valid section of memory | ||
| 84 | then the | ||
| 85 | .Fn inet6_opt_init | ||
| 86 | function also initializes the extension header's length field. | ||
| 87 | When attempting to initialize an extension buffer passed in the | ||
| 88 | .Va extbuf | ||
| 89 | argument, | ||
| 90 | .Fa extlen | ||
| 91 | must be a positive multiple of 8 or else the function fails and | ||
| 92 | returns \-1 to the caller. | ||
| 93 | .\" | ||
| 94 | .Ss inet6_opt_append | ||
| 95 | The | ||
| 96 | .Fn inet6_opt_append | ||
| 97 | function can perform different jobs. | ||
| 98 | When a valid | ||
| 99 | .Fa extbuf | ||
| 100 | argument is supplied it appends an option to the extension buffer and | ||
| 101 | returns the updated total length as well as a pointer to the newly | ||
| 102 | created option in | ||
| 103 | .Fa databufp . | ||
| 104 | If the value | ||
| 105 | of | ||
| 106 | .Fa extbuf | ||
| 107 | is | ||
| 108 | .Dv NULL | ||
| 109 | then the | ||
| 110 | .Fn inet6_opt_append | ||
| 111 | function only reports what the total length would | ||
| 112 | be if the option were actually appended. | ||
| 113 | The | ||
| 114 | .Fa len | ||
| 115 | and | ||
| 116 | .Fa align | ||
| 117 | arguments specify the length of the option and the required data | ||
| 118 | alignment which must be used when appending the option. | ||
| 119 | The | ||
| 120 | .Fa offset | ||
| 121 | argument should be the length returned by the | ||
| 122 | .Fn inet6_opt_init | ||
| 123 | function or a previous call to | ||
| 124 | .Fn inet6_opt_append . | ||
| 125 | .Pp | ||
| 126 | The | ||
| 127 | .Fa type | ||
| 128 | argument is the 8-bit option type. | ||
| 129 | .Pp | ||
| 130 | After | ||
| 131 | .Fn inet6_opt_append | ||
| 132 | has been called, the application can use the buffer pointed to by | ||
| 133 | .Fa databufp | ||
| 134 | directly, or use | ||
| 135 | .Fn inet6_opt_set_val | ||
| 136 | to specify the data to be contained in the option. | ||
| 137 | .Pp | ||
| 138 | Option types of | ||
| 139 | .Li 0 | ||
| 140 | and | ||
| 141 | .Li 1 | ||
| 142 | are reserved for the | ||
| 143 | .Li Pad1 | ||
| 144 | and | ||
| 145 | .Li PadN | ||
| 146 | options. | ||
| 147 | All other values from 2 through 255 may be used by applications. | ||
| 148 | .Pp | ||
| 149 | The length of the option data is contained in an 8-bit value and so | ||
| 150 | may contain any value from 0 through 255. | ||
| 151 | .Pp | ||
| 152 | The | ||
| 153 | .Fa align | ||
| 154 | parameter must have a value of 1, 2, 4, or 8 and cannot exceed the | ||
| 155 | value of | ||
| 156 | .Fa len . | ||
| 157 | The alignment values represent no alignment, 16-bit, 32-bit and 64-bit | ||
| 158 | alignments respectively. | ||
| 159 | .\" | ||
| 160 | .Ss inet6_opt_finish | ||
| 161 | The | ||
| 162 | .Fn inet6_opt_finish | ||
| 163 | calculates the final padding necessary to make the extension header a | ||
| 164 | multiple of 8 bytes, as required by the IPv6 extension header | ||
| 165 | specification, and returns the extension header's updated total | ||
| 166 | length. | ||
| 167 | The | ||
| 168 | .Fa offset | ||
| 169 | argument should be the length returned by | ||
| 170 | .Fn inet6_opt_init | ||
| 171 | or | ||
| 172 | .Fn inet6_opt_append . | ||
| 173 | When | ||
| 174 | .Fa extbuf | ||
| 175 | is not | ||
| 176 | .Dv NULL | ||
| 177 | the function also sets up the appropriate padding bytes by inserting a | ||
| 178 | Pad1 or PadN option of the proper length. | ||
| 179 | .Pp | ||
| 180 | If the extension header is too small to contain the proper padding | ||
| 181 | then an error of \-1 is returned to the caller. | ||
| 182 | .\" | ||
| 183 | .Ss inet6_opt_set_val | ||
| 184 | The | ||
| 185 | .Fn inet6_opt_set_val | ||
| 186 | function inserts data items of various sizes into the data portion of | ||
| 187 | the option. | ||
| 188 | The | ||
| 189 | .Fa databuf | ||
| 190 | argument is a pointer to memory that was returned by the | ||
| 191 | .Fn inet6_opt_append | ||
| 192 | call and the | ||
| 193 | .Fa offset | ||
| 194 | argument specifies where the option should be placed in the | ||
| 195 | data buffer. | ||
| 196 | The | ||
| 197 | .Fa val | ||
| 198 | argument points to an area of memory containing the data to be | ||
| 199 | inserted into the extension header, and the | ||
| 200 | .Fa vallen | ||
| 201 | argument indicates how much data to copy. | ||
| 202 | .Pp | ||
| 203 | The caller should ensure that each field is aligned on its natural | ||
| 204 | boundaries as described in Appendix B of RFC 2460. | ||
| 205 | .Pp | ||
| 206 | The function returns the offset for the next field which is calculated as | ||
| 207 | .Fa offset | ||
| 208 | + | ||
| 209 | .Fa vallen | ||
| 210 | and is used when composing options with multiple fields. | ||
| 211 | .\" | ||
| 212 | .Ss inet6_opt_next | ||
| 213 | The | ||
| 214 | .Fn inet6_opt_next | ||
| 215 | function parses received extension headers. | ||
| 216 | The | ||
| 217 | .Fa extbuf | ||
| 218 | and | ||
| 219 | .Fa extlen | ||
| 220 | arguments specify the location and length of the extension header | ||
| 221 | being parsed. | ||
| 222 | The | ||
| 223 | .Fa offset | ||
| 224 | argument should either be zero, for the first option, or the length value | ||
| 225 | returned by a previous call to | ||
| 226 | .Fn inet6_opt_next | ||
| 227 | or | ||
| 228 | .Fn inet6_opt_find . | ||
| 229 | The return value specifies the position where to continue scanning the | ||
| 230 | extension buffer. | ||
| 231 | The option is returned in the arguments | ||
| 232 | .Fa typep , lenp , | ||
| 233 | and | ||
| 234 | .Fa databufp . | ||
| 235 | .Fa typep , lenp , | ||
| 236 | and | ||
| 237 | .Fa databufp | ||
| 238 | point to the 8-bit option type, the 8-bit option length and the option | ||
| 239 | data respectively. | ||
| 240 | This function does not return any PAD1 or PADN options. | ||
| 241 | When an error occurs or there are no more options the return | ||
| 242 | value is \-1. | ||
| 243 | .\" | ||
| 244 | .Ss inet6_opt_find | ||
| 245 | The | ||
| 246 | .Fn inet6_opt_find | ||
| 247 | function searches the extension buffer for a particular option type, | ||
| 248 | passed in through the | ||
| 249 | .Fa type | ||
| 250 | argument. | ||
| 251 | If the option is found then the | ||
| 252 | .Fa lenp | ||
| 253 | and | ||
| 254 | .Fa databufp | ||
| 255 | arguments are updated to point to the option's length and data | ||
| 256 | respectively. | ||
| 257 | .Fa extbuf | ||
| 258 | and | ||
| 259 | .Fa extlen | ||
| 260 | must point to a valid extension buffer and give its length. | ||
| 261 | The | ||
| 262 | .Fa offset | ||
| 263 | argument can be used to search from a location anywhere in the | ||
| 264 | extension header. | ||
| 265 | .Ss inet6_opt_get_val | ||
| 266 | The | ||
| 267 | .Fn inet6_opt_get_val | ||
| 268 | function extracts data items of various sizes in the data portion of | ||
| 269 | the option. | ||
| 270 | The | ||
| 271 | .Fa databuf | ||
| 272 | is a pointer returned by the | ||
| 273 | .Fn inet6_opt_next | ||
| 274 | or | ||
| 275 | .Fn inet6_opt_find | ||
| 276 | functions. | ||
| 277 | The | ||
| 278 | .Fa val | ||
| 279 | argument points to where the data will be extracted. | ||
| 280 | The | ||
| 281 | .Fa offset | ||
| 282 | argument specifies from where in the data portion of the option the | ||
| 283 | value should be extracted; the first byte of option data is specified | ||
| 284 | by an offset of zero. | ||
| 285 | .Pp | ||
| 286 | It is expected that each field is aligned on its natural boundaries as | ||
| 287 | described in Appendix B of RFC 2460. | ||
| 288 | .Pp | ||
| 289 | The function returns the offset for the next field | ||
| 290 | by calculating | ||
| 291 | .Fa offset | ||
| 292 | + | ||
| 293 | .Fa vallen | ||
| 294 | which can be used when extracting option content with multiple fields. | ||
| 295 | Robust receivers must verify alignment before calling this function. | ||
| 296 | .\" | ||
| 297 | .Sh EXAMPLES | ||
| 298 | RFC 3542 gives comprehensive examples in Section 23. | ||
| 299 | KAME also provides examples in the | ||
| 300 | .Pa advapitest | ||
| 301 | directory of its kit. | ||
| 302 | .\" | ||
| 303 | .Sh DIAGNOSTICS | ||
| 304 | All the functions return | ||
| 305 | \-1 | ||
| 306 | on an error. | ||
| 307 | .\" | ||
| 308 | .Sh STANDARDS | ||
| 309 | .Rs | ||
| 310 | .%A S. Deering | ||
| 311 | .%A R. Hinden | ||
| 312 | .%D December 1998 | ||
| 313 | .%R RFC 2460 | ||
| 314 | .%T Internet Protocol, Version 6 (IPv6) Specification | ||
| 315 | .Re | ||
| 316 | .Pp | ||
| 317 | .Rs | ||
| 318 | .%A W. Stevens | ||
| 319 | .%A M. Thomas | ||
| 320 | .%A E. Nordmark | ||
| 321 | .%A T. Jinmei | ||
| 322 | .%D May 2003 | ||
| 323 | .%R RFC 3542 | ||
| 324 | .%T Advanced Sockets Application Program Interface (API) for IPv6 | ||
| 325 | .Re | ||
| 326 | .Sh HISTORY | ||
| 327 | The implementation first appeared in KAME advanced networking kit. | ||
| 328 | .\" | ||
diff --git a/src/lib/libc/net/inet6_option_space.3 b/src/lib/libc/net/inet6_option_space.3 new file mode 100644 index 0000000000..4b156636f7 --- /dev/null +++ b/src/lib/libc/net/inet6_option_space.3 | |||
| @@ -0,0 +1,442 @@ | |||
| 1 | .\" $OpenBSD: inet6_option_space.3,v 1.24 2014/01/21 03:15:45 schwarze Exp $ | ||
| 2 | .\" $KAME: inet6_option_space.3,v 1.11 2005/01/05 03:00:44 itojun Exp $ | ||
| 3 | .\" | ||
| 4 | .\" Copyright (C) 2004 WIDE Project. | ||
| 5 | .\" All rights reserved. | ||
| 6 | .\" | ||
| 7 | .\" Redistribution and use in source and binary forms, with or without | ||
| 8 | .\" modification, are permitted provided that the following conditions | ||
| 9 | .\" are met: | ||
| 10 | .\" 1. Redistributions of source code must retain the above copyright | ||
| 11 | .\" notice, this list of conditions and the following disclaimer. | ||
| 12 | .\" 2. Redistributions in binary form must reproduce the above copyright | ||
| 13 | .\" notice, this list of conditions and the following disclaimer in the | ||
| 14 | .\" documentation and/or other materials provided with the distribution. | ||
| 15 | .\" 3. Neither the name of the project nor the names of its contributors | ||
| 16 | .\" may be used to endorse or promote products derived from this software | ||
| 17 | .\" without specific prior written permission. | ||
| 18 | .\" | ||
| 19 | .\" THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND | ||
| 20 | .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 21 | .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 22 | .\" ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE | ||
| 23 | .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 24 | .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 25 | .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 26 | .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 28 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 29 | .\" SUCH DAMAGE. | ||
| 30 | .\" | ||
| 31 | .Dd $Mdocdate: January 21 2014 $ | ||
| 32 | .Dt INET6_OPTION_SPACE 3 | ||
| 33 | .Os | ||
| 34 | .\" | ||
| 35 | .Sh NAME | ||
| 36 | .Nm inet6_option_space , | ||
| 37 | .Nm inet6_option_init , | ||
| 38 | .Nm inet6_option_append , | ||
| 39 | .Nm inet6_option_alloc , | ||
| 40 | .Nm inet6_option_next , | ||
| 41 | .Nm inet6_option_find | ||
| 42 | .Nd IPv6 Hop-by-Hop and Destination Option Manipulation | ||
| 43 | .\" | ||
| 44 | .Sh SYNOPSIS | ||
| 45 | .In sys/types.h | ||
| 46 | .In netinet/in.h | ||
| 47 | .Ft "int" | ||
| 48 | .Fn inet6_option_space "int nbytes" | ||
| 49 | .Ft "int" | ||
| 50 | .Fn inet6_option_init "void *bp" "struct cmsghdr **cmsgp" "int type" | ||
| 51 | .Ft "int" | ||
| 52 | .Fn inet6_option_append "struct cmsghdr *cmsg" "const u_int8_t *typep" "int multx" "int plusy" | ||
| 53 | .Ft "u_int8_t *" | ||
| 54 | .Fn inet6_option_alloc "struct cmsghdr *cmsg" "int datalen" "int multx" "int plusy" | ||
| 55 | .Ft "int" | ||
| 56 | .Fn inet6_option_next "const struct cmsghdr *cmsg" "u_int8_t **tptrp" | ||
| 57 | .Ft "int" | ||
| 58 | .Fn inet6_option_find "const struct cmsghdr *cmsg" "u_int8_t **tptrp" "int type" | ||
| 59 | .\" | ||
| 60 | .Sh DESCRIPTION | ||
| 61 | .\" | ||
| 62 | Note: | ||
| 63 | RFC 2292 has been superseded by RFC 3542. | ||
| 64 | The use of functions described in this page is deprecated. | ||
| 65 | See | ||
| 66 | .Xr inet6_opt_init 3 . | ||
| 67 | .Pp | ||
| 68 | Manipulating and parsing IPv6's Hop-by-Hop and Destination options is | ||
| 69 | complicated by the need to properly align and pad data as well as the | ||
| 70 | need to manipulate ancillary information that is not part of the data | ||
| 71 | stream. | ||
| 72 | RFC 2292 defines a set of functions, which are implemented as | ||
| 73 | part of the Kame libraries, to help developers create, change, | ||
| 74 | and parse Hop-by-Hop and Destination options. | ||
| 75 | All of the prototypes | ||
| 76 | for the option functions are defined in the | ||
| 77 | .In netinet/in.h | ||
| 78 | header file. | ||
| 79 | .\" | ||
| 80 | .Ss inet6_option_space | ||
| 81 | In order to determine the amount of space necessary to hold any option | ||
| 82 | the | ||
| 83 | .Fn inet6_option_space | ||
| 84 | function is called. | ||
| 85 | It returns the number of bytes required to hold | ||
| 86 | an option when it is stored as ancillary data, including the | ||
| 87 | .Li cmsghdr | ||
| 88 | structure at the beginning, and any necessary padding at the end. | ||
| 89 | The | ||
| 90 | .Fa nbytes | ||
| 91 | argument indicates the size of the structure defining the option, | ||
| 92 | and must include any pad bytes at the beginning (the value | ||
| 93 | .Li y | ||
| 94 | in the alignment term | ||
| 95 | .Dq Li "xn + y" ) , | ||
| 96 | the type byte, the length byte, and the option data. | ||
| 97 | .Pp | ||
| 98 | Note: If multiple options are stored in a single ancillary data | ||
| 99 | object, which is the recommended technique, the | ||
| 100 | .Fn inet6_option_space | ||
| 101 | function overestimates the amount of space required by the size of | ||
| 102 | .Li N-1 | ||
| 103 | .Li cmsghdr | ||
| 104 | structures, where | ||
| 105 | .Li N | ||
| 106 | is the number of options to be stored in the object. | ||
| 107 | Usually this has | ||
| 108 | no impact because it is assumed that most Hop-by-Hop and Destination | ||
| 109 | option headers carry only one option as indicated in appendix B of RFC 2460. | ||
| 110 | .\" | ||
| 111 | .Ss inet6_option_init | ||
| 112 | The | ||
| 113 | .Fn inet6_option_init | ||
| 114 | function is called to initialize any ancillary data object that will contain | ||
| 115 | a Hop-by-Hop or Destination option. | ||
| 116 | It returns | ||
| 117 | .Li 0 | ||
| 118 | on success and | ||
| 119 | .Li \-1 | ||
| 120 | when an error occurs. | ||
| 121 | .Pp | ||
| 122 | The | ||
| 123 | .Fa bp | ||
| 124 | argument points to a previously allocated area of memory which must be | ||
| 125 | large enough to contain all the arguments that the application intends | ||
| 126 | to add later via the | ||
| 127 | .Fn inet6_option_append | ||
| 128 | and | ||
| 129 | .Fn inet6_option_alloc | ||
| 130 | routines. | ||
| 131 | .Pp | ||
| 132 | The | ||
| 133 | .Fa cmsgp | ||
| 134 | argument is a pointer to a pointer to a | ||
| 135 | .Li cmsghdr | ||
| 136 | structure. | ||
| 137 | The | ||
| 138 | .Fa *cmsgp | ||
| 139 | argument | ||
| 140 | points to a | ||
| 141 | .Li cmsghdr | ||
| 142 | structure which is constructed by this function and stored in the | ||
| 143 | area of memory pointed to by | ||
| 144 | .Fa bp . | ||
| 145 | .Pp | ||
| 146 | The | ||
| 147 | .Fa type | ||
| 148 | is either | ||
| 149 | .Dv IPV6_HOPOPTS | ||
| 150 | or | ||
| 151 | .Dv IPV6_DSTOPTS | ||
| 152 | and is stored in the | ||
| 153 | .Li cmsg_type | ||
| 154 | member of the | ||
| 155 | .Li cmsghdr | ||
| 156 | structure mentioned above. | ||
| 157 | .\" | ||
| 158 | .Ss inet6_option_append | ||
| 159 | This function appends a Hop-by-Hop option or a Destination option into | ||
| 160 | an ancillary data object previously initialized by a call to | ||
| 161 | .Fn inet6_option_init . | ||
| 162 | The | ||
| 163 | .Fn inet6_option_append | ||
| 164 | function returns | ||
| 165 | .Li 0 | ||
| 166 | if it succeeds or | ||
| 167 | .Li \-1 | ||
| 168 | when an error occurs. | ||
| 169 | .Pp | ||
| 170 | The | ||
| 171 | .Fa cmsg | ||
| 172 | argument is a pointer to the | ||
| 173 | .Li cmsghdr | ||
| 174 | structure that was initialized by a call to | ||
| 175 | .Fn inet6_option_init . | ||
| 176 | .Pp | ||
| 177 | The | ||
| 178 | .Fa typep | ||
| 179 | argument is a pointer to the 8-bit option type. | ||
| 180 | All options are | ||
| 181 | encoded as type-length-value tuples and it is assumed that | ||
| 182 | the | ||
| 183 | .Fa typep | ||
| 184 | field is immediately followed by the 8-bit option data length field, | ||
| 185 | which is then followed by the option data. | ||
| 186 | .Pp | ||
| 187 | The option types of | ||
| 188 | .Li 0 | ||
| 189 | and | ||
| 190 | .Li 1 | ||
| 191 | are reserved for the | ||
| 192 | .Li Pad1 | ||
| 193 | and | ||
| 194 | .Li PadN | ||
| 195 | options respectively. | ||
| 196 | All other values from | ||
| 197 | .Li 2 | ||
| 198 | through | ||
| 199 | .Li 255 | ||
| 200 | are available for applications to use. | ||
| 201 | .Pp | ||
| 202 | The option data length, since it is stored in 8 bites, must have a | ||
| 203 | value between | ||
| 204 | .Li 0 | ||
| 205 | and | ||
| 206 | .Li 255 , | ||
| 207 | inclusive. | ||
| 208 | .Pp | ||
| 209 | The | ||
| 210 | .Fa multx | ||
| 211 | argument | ||
| 212 | is the value | ||
| 213 | .Li x | ||
| 214 | in the alignment term | ||
| 215 | .Dq Li xn + y | ||
| 216 | and indicates the byte alignment necessary for the data. | ||
| 217 | Alignments may be specified as | ||
| 218 | .Li 1 , | ||
| 219 | .Li 2 , | ||
| 220 | .Li 4 , | ||
| 221 | or | ||
| 222 | .Li 8 | ||
| 223 | bytes, which is no alignment, 16-bit, 32-bit and 64-bit alignments | ||
| 224 | respectively. | ||
| 225 | .Pp | ||
| 226 | The | ||
| 227 | .Fa plusy | ||
| 228 | argument | ||
| 229 | is the value | ||
| 230 | .Li y | ||
| 231 | in the alignment term | ||
| 232 | .Dq Li xn + y | ||
| 233 | and must have a value between | ||
| 234 | .Li 0 | ||
| 235 | and | ||
| 236 | .Li 7 , | ||
| 237 | inclusive, indicating the amount of padding that is necessary for an | ||
| 238 | option. | ||
| 239 | .\" | ||
| 240 | .Ss inet6_option_alloc | ||
| 241 | The | ||
| 242 | .Fn inet6_option_alloc | ||
| 243 | function appends a Hop-by-Hop option or a Destination option into an | ||
| 244 | ancillary data object that has previously been initialized by a call to | ||
| 245 | .Fn inet6_option_init . | ||
| 246 | A successful call to the | ||
| 247 | .Fn inet6_option_alloc | ||
| 248 | function returns a pointer to the 8-bit option type field, | ||
| 249 | which is at the beginning of the allocated region. | ||
| 250 | .Fn inet6_option_alloc | ||
| 251 | returns | ||
| 252 | .Dv NULL | ||
| 253 | when an error has occurred. | ||
| 254 | .Pp | ||
| 255 | The difference between the | ||
| 256 | .Fn inet6_option_alloc | ||
| 257 | and | ||
| 258 | .Fn inet6_option_append | ||
| 259 | functions is that the latter copies the contents of a previously built | ||
| 260 | option into the ancillary data object while the former returns a | ||
| 261 | pointer to the place in the data object where the option's TLV must | ||
| 262 | then be built by the application. | ||
| 263 | .Pp | ||
| 264 | The | ||
| 265 | .Fa cmsg | ||
| 266 | argument is a pointer to a | ||
| 267 | .Li cmsghdr | ||
| 268 | structure that was initialized by | ||
| 269 | .Fn inet6_option_init . | ||
| 270 | .Pp | ||
| 271 | The | ||
| 272 | .Fa datalen | ||
| 273 | argument is the value of the option data length byte for this option. | ||
| 274 | This value is required as an argument to allow the function to | ||
| 275 | determine if padding must be appended at the end of the option. | ||
| 276 | (The | ||
| 277 | .Fn inet6_option_append | ||
| 278 | function does not need a data length argument | ||
| 279 | since the option data length must already be stored by the caller.) | ||
| 280 | .Pp | ||
| 281 | The | ||
| 282 | .Fa multx | ||
| 283 | and | ||
| 284 | .Fa plusy | ||
| 285 | arguments | ||
| 286 | are identical to the arguments of the same name described in the | ||
| 287 | .Fn inet6_option_init | ||
| 288 | function above. | ||
| 289 | .\" | ||
| 290 | .Ss inet6_option_next | ||
| 291 | The | ||
| 292 | .Fn inet6_option_next | ||
| 293 | function is used to process Hop-by-Hop and Destination options that | ||
| 294 | are present in an ancillary data object. | ||
| 295 | When an option remains to | ||
| 296 | be processed, the return value of the | ||
| 297 | .Fn inet6_option_next | ||
| 298 | function is | ||
| 299 | .Li 0 | ||
| 300 | and the | ||
| 301 | .Fa *tptrp | ||
| 302 | argument points to the 8-bit option type field, which is followed by | ||
| 303 | the 8-bit option data length, and then the option data. | ||
| 304 | When no more | ||
| 305 | options remain to be processed, the return value is | ||
| 306 | .Li \-1 | ||
| 307 | and | ||
| 308 | .Fa *tptrp | ||
| 309 | is | ||
| 310 | .Dv NULL . | ||
| 311 | When an error occurs, the return value is | ||
| 312 | .Li \-1 , | ||
| 313 | but the | ||
| 314 | .Fa *tptrp | ||
| 315 | argument is not | ||
| 316 | .Dv NULL . | ||
| 317 | This set of return values allows a program to easily loop through all | ||
| 318 | the options in an ancillary data object, checking for the error and | ||
| 319 | end of stream conditions along the way. | ||
| 320 | .Pp | ||
| 321 | When a valid option is returned, the | ||
| 322 | .Fa cmsg | ||
| 323 | argument points to a | ||
| 324 | .Li cmsghdr | ||
| 325 | where the | ||
| 326 | .Li cmsg_level | ||
| 327 | element equals | ||
| 328 | .Dv IPPROTO_IPV6 | ||
| 329 | and the | ||
| 330 | .Li cmsg_type | ||
| 331 | element is either | ||
| 332 | .Dv IPV6_HOPOPTS | ||
| 333 | or | ||
| 334 | .Dv IPV6_DSTOPTS . | ||
| 335 | .Pp | ||
| 336 | The | ||
| 337 | .Fa tptrp | ||
| 338 | argument is a pointer to a pointer to an 8-bit byte and | ||
| 339 | .Fa *tptrp | ||
| 340 | is used by the function to remember its place in the ancillary data | ||
| 341 | object each time the function is called. | ||
| 342 | When the | ||
| 343 | .Fn inet6_option_next | ||
| 344 | function is called for the first time on a given ancillary data object, | ||
| 345 | .Fa *tptrp | ||
| 346 | must be set to | ||
| 347 | .Dv NULL . | ||
| 348 | .Pp | ||
| 349 | Each time the function returns success, | ||
| 350 | the | ||
| 351 | .Fa *tptrp | ||
| 352 | argument points to the 8-bit option type field for the next option to | ||
| 353 | be processed. | ||
| 354 | .\" | ||
| 355 | .Ss inet6_option_find | ||
| 356 | The | ||
| 357 | .Fn inet6_option_find | ||
| 358 | function allows an application to search for a particular option type | ||
| 359 | in an ancillary data object. | ||
| 360 | The | ||
| 361 | .Fa cmsg | ||
| 362 | argument is a pointer to a | ||
| 363 | .Li cmsghdr | ||
| 364 | structure in which the | ||
| 365 | .Li cmsg_level | ||
| 366 | element equals | ||
| 367 | .Dv IPPROTO_IPV6 | ||
| 368 | and the | ||
| 369 | .Li cmsg_type | ||
| 370 | element is either | ||
| 371 | .Dv IPV6_HOPOPTS | ||
| 372 | or | ||
| 373 | .Dv IPV6_DSTOPTS . | ||
| 374 | .Pp | ||
| 375 | The | ||
| 376 | .Fa tptrp | ||
| 377 | argument is handled exactly as in the | ||
| 378 | .Fn inet6_option_next | ||
| 379 | function described above. | ||
| 380 | .Pp | ||
| 381 | The | ||
| 382 | .Fn inet6_option_find | ||
| 383 | function starts searching for an option of the specified type | ||
| 384 | beginning after the value of | ||
| 385 | .Fa *tptrp . | ||
| 386 | .\" | ||
| 387 | .Sh EXAMPLES | ||
| 388 | RFC 2292 gives comprehensive examples in chapter 6. | ||
| 389 | .\" | ||
| 390 | .Sh DIAGNOSTICS | ||
| 391 | The | ||
| 392 | .Fn inet6_option_init | ||
| 393 | and | ||
| 394 | .Fn inet6_option_append | ||
| 395 | functions return | ||
| 396 | .Li 0 | ||
| 397 | on success or | ||
| 398 | .Li \-1 | ||
| 399 | on an error. | ||
| 400 | .Pp | ||
| 401 | The | ||
| 402 | .Fn inet6_option_alloc | ||
| 403 | function returns | ||
| 404 | .Dv NULL | ||
| 405 | on an error. | ||
| 406 | .Pp | ||
| 407 | When | ||
| 408 | .Fn inet6_option_next | ||
| 409 | or | ||
| 410 | .Fn inet6_option_find | ||
| 411 | detect an error they return | ||
| 412 | .Li \-1 , | ||
| 413 | setting | ||
| 414 | .Fa *tptrp | ||
| 415 | to a non | ||
| 416 | .Dv NULL | ||
| 417 | value. | ||
| 418 | .\" | ||
| 419 | .Sh SEE ALSO | ||
| 420 | .Xr inet6 4 , | ||
| 421 | .Xr ip6 4 | ||
| 422 | .\" | ||
| 423 | .Sh STANDARDS | ||
| 424 | .Rs | ||
| 425 | .%A W. Stevens | ||
| 426 | .%A M. Thomas | ||
| 427 | .%D February 1998 | ||
| 428 | .%R RFC 2292 | ||
| 429 | .%T Advanced Sockets API for IPv6 | ||
| 430 | .Re | ||
| 431 | .Pp | ||
| 432 | .Rs | ||
| 433 | .%A S. Deering | ||
| 434 | .%A R. Hinden | ||
| 435 | .%D December 1998 | ||
| 436 | .%R RFC 2460 | ||
| 437 | .%T Internet Protocol, Version 6 (IPv6) Specification | ||
| 438 | .Re | ||
| 439 | .\" | ||
| 440 | .Sh HISTORY | ||
| 441 | This implementation first appeared in the KAME advanced networking kit. | ||
| 442 | .\" | ||
diff --git a/src/lib/libc/net/inet6_rth_space.3 b/src/lib/libc/net/inet6_rth_space.3 new file mode 100644 index 0000000000..fcd023481f --- /dev/null +++ b/src/lib/libc/net/inet6_rth_space.3 | |||
| @@ -0,0 +1,220 @@ | |||
| 1 | .\" $OpenBSD: inet6_rth_space.3,v 1.6 2014/01/21 03:15:45 schwarze Exp $ | ||
| 2 | .\" $KAME: inet6_rth_space.3,v 1.7 2005/01/05 03:00:44 itojun Exp $ | ||
| 3 | .\" | ||
| 4 | .\" Copyright (C) 2004 WIDE Project. | ||
| 5 | .\" All rights reserved. | ||
| 6 | .\" | ||
| 7 | .\" Redistribution and use in source and binary forms, with or without | ||
| 8 | .\" modification, are permitted provided that the following conditions | ||
| 9 | .\" are met: | ||
| 10 | .\" 1. Redistributions of source code must retain the above copyright | ||
| 11 | .\" notice, this list of conditions and the following disclaimer. | ||
| 12 | .\" 2. Redistributions in binary form must reproduce the above copyright | ||
| 13 | .\" notice, this list of conditions and the following disclaimer in the | ||
| 14 | .\" documentation and/or other materials provided with the distribution. | ||
| 15 | .\" 3. Neither the name of the project nor the names of its contributors | ||
| 16 | .\" may be used to endorse or promote products derived from this software | ||
| 17 | .\" without specific prior written permission. | ||
| 18 | .\" | ||
| 19 | .\" THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND | ||
| 20 | .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 21 | .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 22 | .\" ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE | ||
| 23 | .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 24 | .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 25 | .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 26 | .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 28 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 29 | .\" SUCH DAMAGE. | ||
| 30 | .\" | ||
| 31 | .Dd $Mdocdate: January 21 2014 $ | ||
| 32 | .Dt INET6_RTH_SPACE 3 | ||
| 33 | .Os | ||
| 34 | .\" | ||
| 35 | .Sh NAME | ||
| 36 | .Nm inet6_rth_space , | ||
| 37 | .Nm inet6_rth_init , | ||
| 38 | .Nm inet6_rth_add , | ||
| 39 | .Nm inet6_rth_reverse , | ||
| 40 | .Nm inet6_rth_segments , | ||
| 41 | .Nm inet6_rth_getaddr | ||
| 42 | .Nd IPv6 Routing Header Options manipulation | ||
| 43 | .\" | ||
| 44 | .Sh SYNOPSIS | ||
| 45 | .In netinet/in.h | ||
| 46 | .Ft socklen_t | ||
| 47 | .Fn inet6_rth_space "int" "int" | ||
| 48 | .Ft "void *" | ||
| 49 | .Fn inet6_rth_init "void *" "socklen_t" "int" "int" | ||
| 50 | .Ft int | ||
| 51 | .Fn inet6_rth_add "void *" "const struct in6_addr *" | ||
| 52 | .Ft int | ||
| 53 | .Fn inet6_rth_reverse "const void *" "void *" | ||
| 54 | .Ft int | ||
| 55 | .Fn inet6_rth_segments "const void *" | ||
| 56 | .Ft "struct in6_addr *" | ||
| 57 | .Fn inet6_rth_getaddr "const void *" "int" | ||
| 58 | .\" | ||
| 59 | .Sh DESCRIPTION | ||
| 60 | The IPv6 Advanced API, RFC 3542, defines the functions that an | ||
| 61 | application calls to build and examine IPv6 Routing headers. | ||
| 62 | Routing headers are used to perform source routing in IPv6 networks. | ||
| 63 | The RFC uses the word | ||
| 64 | .Dq segments | ||
| 65 | to describe addresses and that is the term used here as well. | ||
| 66 | All of the functions are defined in the header file | ||
| 67 | .In netinet/in.h . | ||
| 68 | The functions described in this manual page all operate | ||
| 69 | on routing header structures which are defined in | ||
| 70 | .In netinet/ip6.h | ||
| 71 | but which should not need to be modified outside the use of this API. | ||
| 72 | The size and shape of the route header structures may change, so using | ||
| 73 | the APIs is a more portable, long term, solution. | ||
| 74 | .Pp | ||
| 75 | The functions in the API are split into two groups, those that build a | ||
| 76 | routing header and those that parse a received routing header. | ||
| 77 | The builder functions are described first, followed by the parser functions. | ||
| 78 | .Ss inet6_rth_space | ||
| 79 | The | ||
| 80 | .Fn inet6_rth_space | ||
| 81 | function returns the number of bytes required to hold a Routing Header | ||
| 82 | of the type, specified in the | ||
| 83 | .Fa type | ||
| 84 | argument and containing the number of addresses specified in the | ||
| 85 | .Fa segments | ||
| 86 | argument. | ||
| 87 | When the type is | ||
| 88 | .Dv IPV6_RTHDR_TYPE_0 | ||
| 89 | the number of segments must be from 0 through 127. | ||
| 90 | The return value from this function is the number of bytes required to | ||
| 91 | store the routing header. | ||
| 92 | If the value 0 is returned then either the | ||
| 93 | route header type was not recognized or another error occurred. | ||
| 94 | .Ss inet6_rth_init | ||
| 95 | The | ||
| 96 | .Fn inet6_rth_init | ||
| 97 | function initializes the pre-allocated buffer pointed to by | ||
| 98 | .Fa bp | ||
| 99 | to contain a routing header of the specified type. | ||
| 100 | The | ||
| 101 | .Fa bp_len | ||
| 102 | argument is used to verify that the buffer is large enough. | ||
| 103 | The caller must allocate the buffer pointed to by bp. | ||
| 104 | The necessary buffer size should be determined by calling | ||
| 105 | .Fn inet6_rth_space | ||
| 106 | described in the previous sections. | ||
| 107 | .Pp | ||
| 108 | The | ||
| 109 | .Fn inet6_rth_init | ||
| 110 | function returns a pointer to | ||
| 111 | .Fa bp | ||
| 112 | on success and | ||
| 113 | .Dv NULL | ||
| 114 | when there is an error. | ||
| 115 | .Ss inet6_rth_add | ||
| 116 | The | ||
| 117 | .Fn inet6_rth_add | ||
| 118 | function adds the IPv6 address pointed to by | ||
| 119 | .Fa addr | ||
| 120 | to the end of the routing header being constructed. | ||
| 121 | .Pp | ||
| 122 | A successful addition results in the function returning 0, otherwise | ||
| 123 | \-1 is returned. | ||
| 124 | .Ss inet6_rth_reverse | ||
| 125 | The | ||
| 126 | .Fn inet6_rth_reverse | ||
| 127 | function takes a routing header, pointed to by the | ||
| 128 | argument | ||
| 129 | .Fa in , | ||
| 130 | and writes a new routing header into the argument pointed to by | ||
| 131 | .Fa out . | ||
| 132 | The routing header at that sends datagrams along the reverse of that | ||
| 133 | route. | ||
| 134 | Both arguments are allowed to point to the same buffer meaning | ||
| 135 | that the reversal can occur in place. | ||
| 136 | .Pp | ||
| 137 | The return value of the function is 0 on success, or \-1 when | ||
| 138 | there is an error. | ||
| 139 | .\" | ||
| 140 | .Pp | ||
| 141 | The next set of functions operate on a routing header that the | ||
| 142 | application wants to parse. | ||
| 143 | In the usual case such a routing header | ||
| 144 | is received from the network, although these functions can also be | ||
| 145 | used with routing headers that the application itself created. | ||
| 146 | .Ss inet6_rth_segments | ||
| 147 | The | ||
| 148 | .Fn inet6_rth_segments | ||
| 149 | function returns the number of segments contained in the | ||
| 150 | routing header pointed to by | ||
| 151 | .Fa bp . | ||
| 152 | The return value is the number of segments contained in the routing | ||
| 153 | header, or \-1 if an error occurred. | ||
| 154 | It is not an error for 0 to be | ||
| 155 | returned as a routing header may contain 0 segments. | ||
| 156 | .\" | ||
| 157 | .Ss inet6_rth_getaddr | ||
| 158 | The | ||
| 159 | .Fn inet6_rth_getaddr | ||
| 160 | function is used to retrieve a single address from a routing header. | ||
| 161 | The | ||
| 162 | .Fa index | ||
| 163 | is the location in the routing header from which the application wants | ||
| 164 | to retrieve an address. | ||
| 165 | The | ||
| 166 | .Fa index | ||
| 167 | parameter must have a value between 0 and one less than the number of | ||
| 168 | segments present in the routing header. | ||
| 169 | The | ||
| 170 | .Fn inet6_rth_segments | ||
| 171 | function, described in the last section, should be used to determine | ||
| 172 | the total number of segments in the routing header. | ||
| 173 | The | ||
| 174 | .Fn inet6_rth_getaddr | ||
| 175 | function returns a pointer to an IPv6 address on success or | ||
| 176 | .Dv NULL | ||
| 177 | when an error has occurred. | ||
| 178 | .\" | ||
| 179 | .Sh EXAMPLES | ||
| 180 | RFC 3542 gives extensive examples in Section 21, Appendix B. | ||
| 181 | KAME also provides examples in the advapitest directory of its kit. | ||
| 182 | .\" | ||
| 183 | .Sh DIAGNOSTICS | ||
| 184 | The | ||
| 185 | .Fn inet6_rth_space | ||
| 186 | and | ||
| 187 | .Fn inet6_rth_getaddr | ||
| 188 | functions return 0 on errors. | ||
| 189 | .Pp | ||
| 190 | The | ||
| 191 | .Fn inet6_rthdr_init | ||
| 192 | function returns | ||
| 193 | .Dv NULL | ||
| 194 | on error. | ||
| 195 | The | ||
| 196 | .Fn inet6_rth_add | ||
| 197 | and | ||
| 198 | .Fn inet6_rth_reverse | ||
| 199 | functions return 0 on success, or \-1 upon an error. | ||
| 200 | .\" | ||
| 201 | .Sh STANDARDS | ||
| 202 | .Rs | ||
| 203 | .%A S. Deering | ||
| 204 | .%A R. Hinden | ||
| 205 | .%D December 1998 | ||
| 206 | .%R RFC 2460 | ||
| 207 | .%T Internet Protocol, Version 6 (IPv6) Specification | ||
| 208 | .Re | ||
| 209 | .Pp | ||
| 210 | .Rs | ||
| 211 | .%A W. Stevens | ||
| 212 | .%A M. Thomas | ||
| 213 | .%A E. Nordmark | ||
| 214 | .%A T. Jinmei | ||
| 215 | .%D May 2003 | ||
| 216 | .%R RFC 3542 | ||
| 217 | .%T Advanced Sockets Application Programming Interface (API) for IPv6 | ||
| 218 | .Re | ||
| 219 | .Sh HISTORY | ||
| 220 | The implementation first appeared in KAME advanced networking kit. | ||
diff --git a/src/lib/libc/net/inet6_rthdr_space.3 b/src/lib/libc/net/inet6_rthdr_space.3 new file mode 100644 index 0000000000..c72e84ff1a --- /dev/null +++ b/src/lib/libc/net/inet6_rthdr_space.3 | |||
| @@ -0,0 +1,310 @@ | |||
| 1 | .\" $OpenBSD: inet6_rthdr_space.3,v 1.23 2014/01/21 03:15:45 schwarze Exp $ | ||
| 2 | .\" $KAME: inet6_rthdr_space.3,v 1.11 2005/01/05 03:00:44 itojun Exp $ | ||
| 3 | .\" | ||
| 4 | .\" Copyright (C) 2004 WIDE Project. | ||
| 5 | .\" All rights reserved. | ||
| 6 | .\" | ||
| 7 | .\" Redistribution and use in source and binary forms, with or without | ||
| 8 | .\" modification, are permitted provided that the following conditions | ||
| 9 | .\" are met: | ||
| 10 | .\" 1. Redistributions of source code must retain the above copyright | ||
| 11 | .\" notice, this list of conditions and the following disclaimer. | ||
| 12 | .\" 2. Redistributions in binary form must reproduce the above copyright | ||
| 13 | .\" notice, this list of conditions and the following disclaimer in the | ||
| 14 | .\" documentation and/or other materials provided with the distribution. | ||
| 15 | .\" 3. Neither the name of the project nor the names of its contributors | ||
| 16 | .\" may be used to endorse or promote products derived from this software | ||
| 17 | .\" without specific prior written permission. | ||
| 18 | .\" | ||
| 19 | .\" THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND | ||
| 20 | .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 21 | .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 22 | .\" ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE | ||
| 23 | .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 24 | .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 25 | .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 26 | .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 28 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 29 | .\" SUCH DAMAGE. | ||
| 30 | .\" | ||
| 31 | .Dd $Mdocdate: January 21 2014 $ | ||
| 32 | .Dt INET6_RTHDR_SPACE 3 | ||
| 33 | .Os | ||
| 34 | .\" | ||
| 35 | .Sh NAME | ||
| 36 | .Nm inet6_rthdr_space , | ||
| 37 | .Nm inet6_rthdr_init , | ||
| 38 | .Nm inet6_rthdr_add , | ||
| 39 | .Nm inet6_rthdr_lasthop , | ||
| 40 | .Nm inet6_rthdr_reverse , | ||
| 41 | .Nm inet6_rthdr_segments , | ||
| 42 | .Nm inet6_rthdr_getaddr , | ||
| 43 | .Nm inet6_rthdr_getflags | ||
| 44 | .Nd IPv6 Routing Header Options Manipulation | ||
| 45 | .\" | ||
| 46 | .Sh SYNOPSIS | ||
| 47 | .In sys/types.h | ||
| 48 | .In netinet/in.h | ||
| 49 | .Ft size_t | ||
| 50 | .Fn inet6_rthdr_space "int type" "int segments" | ||
| 51 | .Ft "struct cmsghdr *" | ||
| 52 | .Fn inet6_rthdr_init "void *bp" "int type" | ||
| 53 | .Ft int | ||
| 54 | .Fn inet6_rthdr_add "struct cmsghdr *cmsg" "const struct in6_addr *addr" "unsigned int flags" | ||
| 55 | .Ft int | ||
| 56 | .Fn inet6_rthdr_lasthop "struct cmsghdr *cmsg" "unsigned int flags" | ||
| 57 | .Ft int | ||
| 58 | .Fn inet6_rthdr_reverse "const struct cmsghdr *in" "struct cmsghdr *out" | ||
| 59 | .Ft int | ||
| 60 | .Fn inet6_rthdr_segments "const struct cmsghdr *cmsg" | ||
| 61 | .Ft "struct in6_addr *" | ||
| 62 | .Fn inet6_rthdr_getaddr "struct cmsghdr *cmsg" "int index" | ||
| 63 | .Ft int | ||
| 64 | .Fn inet6_rthdr_getflags "const struct cmsghdr *cmsg" "int index" | ||
| 65 | .\" | ||
| 66 | .Sh DESCRIPTION | ||
| 67 | Note: | ||
| 68 | RFC 2292 has been superseded by RFC 3542. | ||
| 69 | The use of functions described in this page is deprecated. | ||
| 70 | See | ||
| 71 | .Xr inet6_rth_space 3 . | ||
| 72 | .Pp | ||
| 73 | The RFC 2292 IPv6 Advanced API defined eight functions for | ||
| 74 | applications to use for building and parsing routing headers. | ||
| 75 | The | ||
| 76 | eight functions are split into two groups, the first of which builds | ||
| 77 | the header and the second of which can parse it. | ||
| 78 | The function prototypes for these functions are all in the | ||
| 79 | .In netinet/in.h | ||
| 80 | header. | ||
| 81 | Although direct manipulation of a routing header is possible, | ||
| 82 | this set of APIs make it unnecessary and such direct manipulation | ||
| 83 | should be avoided so that changes to the underlying structures do not | ||
| 84 | break applications. | ||
| 85 | .Pp | ||
| 86 | Please note that RFC 2292 uses the term | ||
| 87 | .Dq segments | ||
| 88 | instead of the term | ||
| 89 | .Dq addresses | ||
| 90 | but they are considered equivalent for this manual page. | ||
| 91 | .\" | ||
| 92 | .Ss inet6_rthdr_space | ||
| 93 | The | ||
| 94 | .Fn inet6_rthdr_space | ||
| 95 | function returns the number of bytes required to hold a routing header | ||
| 96 | of the specified | ||
| 97 | .Fa type | ||
| 98 | and containing the specified number of | ||
| 99 | .Fa segments . | ||
| 100 | Only one | ||
| 101 | .Fa type | ||
| 102 | is supported, | ||
| 103 | .Dv IPV6_RTHDR_TYPE_0 , | ||
| 104 | and it can hold from 1 to 23 segments. | ||
| 105 | The return value includes the | ||
| 106 | size of the | ||
| 107 | .Vt cmsghdr | ||
| 108 | structure that precedes the routing header and | ||
| 109 | any required padding. | ||
| 110 | .Pp | ||
| 111 | A return value of 0 indicates an error. | ||
| 112 | Either the type was specified | ||
| 113 | incorrectly, or the number of segments was less than one or greater | ||
| 114 | than 23. | ||
| 115 | .Pp | ||
| 116 | Note: The | ||
| 117 | .Fn inet6_rthdr_space | ||
| 118 | function only returns the size required by the routing header and does | ||
| 119 | not allocate memory for the caller. | ||
| 120 | .\" | ||
| 121 | .Ss inet6_rthdr_init | ||
| 122 | The | ||
| 123 | .Fn inet6_rthdr_init | ||
| 124 | function initializes a buffer, pointed to by | ||
| 125 | .Fa bp | ||
| 126 | with an appropriate | ||
| 127 | .Li cmsghdr | ||
| 128 | structure followed by a routing header of the specified | ||
| 129 | .Fa type . | ||
| 130 | .Pp | ||
| 131 | The caller must use the | ||
| 132 | .Fn inet6_rthdr_space | ||
| 133 | function to determine the size of the buffer, and then allocate that | ||
| 134 | buffer before calling | ||
| 135 | .Fn inet6_rthdr_init . | ||
| 136 | .Pp | ||
| 137 | The return value is a pointer to a | ||
| 138 | .Li cmsghdr | ||
| 139 | structure, which is used as the first argument to the | ||
| 140 | .Fn inet6_rthdr_add | ||
| 141 | and | ||
| 142 | .Fn inet6_rthdr_lasthop | ||
| 143 | functions in order to construct the routing header. | ||
| 144 | When an error occurs the return value is | ||
| 145 | .Dv NULL . | ||
| 146 | .\" | ||
| 147 | .Ss inet6_rthdr_add | ||
| 148 | The | ||
| 149 | .Fn inet6_rthdr_add | ||
| 150 | function adds the IPv6 address pointed to by | ||
| 151 | .Fa addr | ||
| 152 | to the end of the | ||
| 153 | routing header being constructed and sets the type of this address to the | ||
| 154 | value of | ||
| 155 | .Fa flags . | ||
| 156 | The | ||
| 157 | .Fa flags | ||
| 158 | must be either | ||
| 159 | .Dv IPV6_RTHDR_LOOSE | ||
| 160 | or | ||
| 161 | .Dv IPV6_RTHDR_STRICT | ||
| 162 | indicating whether loose or strict source routing is required. | ||
| 163 | .Pp | ||
| 164 | When the function succeeds it returns 0, otherwise \-1 is returned. | ||
| 165 | .\" | ||
| 166 | .Ss inet6_rthdr_lasthop | ||
| 167 | The | ||
| 168 | .Fn inet6_rthdr_lasthop | ||
| 169 | function specifies the strict or loose flag for the final hop of a | ||
| 170 | routing header. | ||
| 171 | The | ||
| 172 | .Fa flags | ||
| 173 | argument must be either | ||
| 174 | .Dv IPV6_RTHDR_LOOSE | ||
| 175 | or | ||
| 176 | .Dv IPV6_RTHDR_STRICT . | ||
| 177 | .Pp | ||
| 178 | The return value of the function is 0 upon success, and \-1 when an | ||
| 179 | error has occurred. | ||
| 180 | .Pp | ||
| 181 | Please note that a routing header specifying | ||
| 182 | .Li N | ||
| 183 | intermediate nodes requires | ||
| 184 | .Li N+1 | ||
| 185 | strict or loose flags meaning that | ||
| 186 | .Fn inet6_rthdr_add | ||
| 187 | must be called | ||
| 188 | .Li N | ||
| 189 | times and then | ||
| 190 | .Fn inet6_rthdr_lasthop | ||
| 191 | must be called once. | ||
| 192 | .\" | ||
| 193 | .Ss inet6_rthdr_reverse | ||
| 194 | This function was never implemented. | ||
| 195 | .Pp | ||
| 196 | The following three functions provide an API for parsing a received | ||
| 197 | routing header: | ||
| 198 | .\" | ||
| 199 | .Ss inet6_rthdr_segments | ||
| 200 | The | ||
| 201 | .Fn inet6_rthdr_segments | ||
| 202 | function returns the number of segments contained in the routing | ||
| 203 | header pointed to by the | ||
| 204 | .Fa cmsg | ||
| 205 | argument. | ||
| 206 | On success the return value is from 1 to 23. | ||
| 207 | When an error occurs, \-1 is returned. | ||
| 208 | .\" | ||
| 209 | .Ss inet6_rthdr_getaddr | ||
| 210 | The | ||
| 211 | .Fn inet6_rthdr_getaddr | ||
| 212 | function returns a pointer to the IPv6 address specified by the | ||
| 213 | .Fa index | ||
| 214 | argument from the routing header pointed to by | ||
| 215 | .Fa cmsg . | ||
| 216 | The index must be between 1 and the number returned by | ||
| 217 | .Fn inet6_rthdr_segments , | ||
| 218 | described above. | ||
| 219 | An application must call | ||
| 220 | .Fn inet6_rthdr_segments | ||
| 221 | to obtain the number of segments in the routing header. | ||
| 222 | .Pp | ||
| 223 | If an error occurs, | ||
| 224 | .Dv NULL | ||
| 225 | is returned. | ||
| 226 | .\" | ||
| 227 | .Ss inet6_rthdr_getflags | ||
| 228 | The | ||
| 229 | .Fn inet6_rthdr_getflags | ||
| 230 | function returns the flags value of the segment specified by | ||
| 231 | .Fa index | ||
| 232 | of the routing header pointed to by | ||
| 233 | .Fa cmsg . | ||
| 234 | The | ||
| 235 | .Fa index | ||
| 236 | argument must be between 0 and the value returned by | ||
| 237 | .Fn inet6_rthdr_segments . | ||
| 238 | The return value will be either | ||
| 239 | .Dv IPV6_RTHDR_LOOSE | ||
| 240 | or | ||
| 241 | .Dv IPV6_RTHDR_STRICT | ||
| 242 | indicating whether loose or strict source routing was requested for | ||
| 243 | that segment. | ||
| 244 | .Pp | ||
| 245 | When an error occurs, \-1 is returned. | ||
| 246 | .Pp | ||
| 247 | Note: Flags begin at index 0 while segments begin at index 1, to | ||
| 248 | maintain consistency with the terminology and figures in RFC 2460. | ||
| 249 | .\" | ||
| 250 | .Sh EXAMPLES | ||
| 251 | RFC 2292 gives comprehensive examples in chapter 8. | ||
| 252 | .\" | ||
| 253 | .Sh DIAGNOSTICS | ||
| 254 | The | ||
| 255 | .Fn inet6_rthdr_space | ||
| 256 | function returns 0 when an error occurs. | ||
| 257 | .Pp | ||
| 258 | The | ||
| 259 | .Fn inet6_rthdr_add | ||
| 260 | and | ||
| 261 | .Fn inet6_rthdr_lasthop | ||
| 262 | functions return 0 on success, and \-1 on error. | ||
| 263 | .Pp | ||
| 264 | The | ||
| 265 | .Fn inet6_rthdr_init | ||
| 266 | and | ||
| 267 | .Fn inet6_rthdr_getaddr | ||
| 268 | functions | ||
| 269 | return | ||
| 270 | .Dv NULL | ||
| 271 | on error. | ||
| 272 | .Pp | ||
| 273 | The | ||
| 274 | .Fn inet6_rthdr_segments | ||
| 275 | and | ||
| 276 | .Fn inet6_rthdr_getflags | ||
| 277 | functions return \-1 on error. | ||
| 278 | .\" | ||
| 279 | .Sh SEE ALSO | ||
| 280 | .Xr inet6 4 , | ||
| 281 | .Xr ip6 4 | ||
| 282 | .Sh STANDARDS | ||
| 283 | .Rs | ||
| 284 | .%A W. Stevens | ||
| 285 | .%A M. Thomas | ||
| 286 | .%D February 1998 | ||
| 287 | .%R RFC 2292 | ||
| 288 | .%T Advanced Sockets API for IPv6 | ||
| 289 | .Re | ||
| 290 | .Pp | ||
| 291 | .Rs | ||
| 292 | .%A S. Deering | ||
| 293 | .%A R. Hinden | ||
| 294 | .%D December 1998 | ||
| 295 | .%R RFC 2460 | ||
| 296 | .%T Internet Protocol, Version 6 (IPv6) Specification | ||
| 297 | .Re | ||
| 298 | .\" | ||
| 299 | .Sh HISTORY | ||
| 300 | This implementation first appeared in the KAME advanced networking kit. | ||
| 301 | .\" | ||
| 302 | .Sh BUGS | ||
| 303 | The | ||
| 304 | .Fn inet6_rthdr_reverse | ||
| 305 | function was never implemented. | ||
| 306 | .\".Pp | ||
| 307 | .\"This API is deprecated in favor of | ||
| 308 | .\".Xr inet6_rth_space 3 | ||
| 309 | .\".Sh SEE ALSO | ||
| 310 | .\".Xr inet6_rth_space 3 | ||
diff --git a/src/lib/libc/net/inet_addr.c b/src/lib/libc/net/inet_addr.c index b5b9d8302f..18762ab522 100644 --- a/src/lib/libc/net/inet_addr.c +++ b/src/lib/libc/net/inet_addr.c | |||
| @@ -1,9 +1,11 @@ | |||
| 1 | /* $NetBSD: inet_addr.c,v 1.5 1995/02/25 06:20:41 cgd Exp $ */ | 1 | /* $OpenBSD: inet_addr.c,v 1.10 2013/11/24 23:51:28 deraadt Exp $ */ |
| 2 | 2 | ||
| 3 | /* | 3 | /* |
| 4 | * ++Copyright++ 1983, 1990, 1993 | ||
| 5 | * - | ||
| 4 | * Copyright (c) 1983, 1990, 1993 | 6 | * Copyright (c) 1983, 1990, 1993 |
| 5 | * The Regents of the University of California. All rights reserved. | 7 | * The Regents of the University of California. All rights reserved. |
| 6 | * | 8 | * |
| 7 | * Redistribution and use in source and binary forms, with or without | 9 | * Redistribution and use in source and binary forms, with or without |
| 8 | * modification, are permitted provided that the following conditions | 10 | * modification, are permitted provided that the following conditions |
| 9 | * are met: | 11 | * are met: |
| @@ -12,14 +14,10 @@ | |||
| 12 | * 2. Redistributions in binary form must reproduce the above copyright | 14 | * 2. Redistributions in binary form must reproduce the above copyright |
| 13 | * notice, this list of conditions and the following disclaimer in the | 15 | * notice, this list of conditions and the following disclaimer in the |
| 14 | * documentation and/or other materials provided with the distribution. | 16 | * documentation and/or other materials provided with the distribution. |
| 15 | * 3. All advertising materials mentioning features or use of this software | 17 | * 3. Neither the name of the University nor the names of its contributors |
| 16 | * must display the following acknowledgement: | ||
| 17 | * This product includes software developed by the University of | ||
| 18 | * California, Berkeley and its contributors. | ||
| 19 | * 4. Neither the name of the University nor the names of its contributors | ||
| 20 | * may be used to endorse or promote products derived from this software | 18 | * may be used to endorse or promote products derived from this software |
| 21 | * without specific prior written permission. | 19 | * without specific prior written permission. |
| 22 | * | 20 | * |
| 23 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | 21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
| 24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| @@ -31,16 +29,29 @@ | |||
| 31 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| 32 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 33 | * SUCH DAMAGE. | 31 | * SUCH DAMAGE. |
| 32 | * - | ||
| 33 | * Portions Copyright (c) 1993 by Digital Equipment Corporation. | ||
| 34 | * | ||
| 35 | * Permission to use, copy, modify, and distribute this software for any | ||
| 36 | * purpose with or without fee is hereby granted, provided that the above | ||
| 37 | * copyright notice and this permission notice appear in all copies, and that | ||
| 38 | * the name of Digital Equipment Corporation not be used in advertising or | ||
| 39 | * publicity pertaining to distribution of the document or software without | ||
| 40 | * specific, written prior permission. | ||
| 41 | * | ||
| 42 | * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL | ||
| 43 | * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES | ||
| 44 | * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT | ||
| 45 | * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | ||
| 46 | * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR | ||
| 47 | * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS | ||
| 48 | * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | ||
| 49 | * SOFTWARE. | ||
| 50 | * - | ||
| 51 | * --Copyright-- | ||
| 34 | */ | 52 | */ |
| 35 | 53 | ||
| 36 | #if defined(LIBC_SCCS) && !defined(lint) | 54 | #include <sys/types.h> |
| 37 | #if 0 | ||
| 38 | static char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93"; | ||
| 39 | #else | ||
| 40 | static char rcsid[] = "$NetBSD: inet_addr.c,v 1.5 1995/02/25 06:20:41 cgd Exp $"; | ||
| 41 | #endif | ||
| 42 | #endif /* LIBC_SCCS and not lint */ | ||
| 43 | |||
| 44 | #include <sys/param.h> | 55 | #include <sys/param.h> |
| 45 | #include <netinet/in.h> | 56 | #include <netinet/in.h> |
| 46 | #include <arpa/inet.h> | 57 | #include <arpa/inet.h> |
| @@ -50,9 +61,8 @@ static char rcsid[] = "$NetBSD: inet_addr.c,v 1.5 1995/02/25 06:20:41 cgd Exp $" | |||
| 50 | * Ascii internet address interpretation routine. | 61 | * Ascii internet address interpretation routine. |
| 51 | * The value returned is in network order. | 62 | * The value returned is in network order. |
| 52 | */ | 63 | */ |
| 53 | u_long | 64 | in_addr_t |
| 54 | inet_addr(cp) | 65 | inet_addr(const char *cp) |
| 55 | register const char *cp; | ||
| 56 | { | 66 | { |
| 57 | struct in_addr val; | 67 | struct in_addr val; |
| 58 | 68 | ||
| @@ -69,60 +79,64 @@ inet_addr(cp) | |||
| 69 | * cannot distinguish between failure and a local broadcast address. | 79 | * cannot distinguish between failure and a local broadcast address. |
| 70 | */ | 80 | */ |
| 71 | int | 81 | int |
| 72 | inet_aton(cp, addr) | 82 | inet_aton(const char *cp, struct in_addr *addr) |
| 73 | register const char *cp; | ||
| 74 | struct in_addr *addr; | ||
| 75 | { | 83 | { |
| 76 | register u_long val; | 84 | in_addr_t val; |
| 77 | register int base, n; | 85 | int base, n; |
| 78 | register char c; | 86 | char c; |
| 79 | u_int parts[4]; | 87 | u_int parts[4]; |
| 80 | register u_int *pp = parts; | 88 | u_int *pp = parts; |
| 81 | 89 | ||
| 90 | c = *cp; | ||
| 82 | for (;;) { | 91 | for (;;) { |
| 83 | /* | 92 | /* |
| 84 | * Collect number up to ``.''. | 93 | * Collect number up to ``.''. |
| 85 | * Values are specified as for C: | 94 | * Values are specified as for C: |
| 86 | * 0x=hex, 0=octal, other=decimal. | 95 | * 0x=hex, 0=octal, isdigit=decimal. |
| 87 | */ | 96 | */ |
| 97 | if (!isdigit((unsigned char)c)) | ||
| 98 | return (0); | ||
| 88 | val = 0; base = 10; | 99 | val = 0; base = 10; |
| 89 | if (*cp == '0') { | 100 | if (c == '0') { |
| 90 | if (*++cp == 'x' || *cp == 'X') | 101 | c = *++cp; |
| 91 | base = 16, cp++; | 102 | if (c == 'x' || c == 'X') |
| 103 | base = 16, c = *++cp; | ||
| 92 | else | 104 | else |
| 93 | base = 8; | 105 | base = 8; |
| 94 | } | 106 | } |
| 95 | while ((c = *cp) != '\0') { | 107 | for (;;) { |
| 96 | if (isascii(c) && isdigit(c)) { | 108 | if (isascii((unsigned char)c) && |
| 109 | isdigit((unsigned char)c)) { | ||
| 97 | val = (val * base) + (c - '0'); | 110 | val = (val * base) + (c - '0'); |
| 98 | cp++; | 111 | c = *++cp; |
| 99 | continue; | 112 | } else if (base == 16 && |
| 100 | } | 113 | isascii((unsigned char)c) && |
| 101 | if (base == 16 && isascii(c) && isxdigit(c)) { | 114 | isxdigit((unsigned char)c)) { |
| 102 | val = (val << 4) + | 115 | val = (val << 4) | |
| 103 | (c + 10 - (islower(c) ? 'a' : 'A')); | 116 | (c + 10 - (islower((unsigned char)c) ? 'a' : 'A')); |
| 104 | cp++; | 117 | c = *++cp; |
| 105 | continue; | 118 | } else |
| 106 | } | 119 | break; |
| 107 | break; | ||
| 108 | } | 120 | } |
| 109 | if (*cp == '.') { | 121 | if (c == '.') { |
| 110 | /* | 122 | /* |
| 111 | * Internet format: | 123 | * Internet format: |
| 112 | * a.b.c.d | 124 | * a.b.c.d |
| 113 | * a.b.c (with c treated as 16-bits) | 125 | * a.b.c (with c treated as 16 bits) |
| 114 | * a.b (with b treated as 24 bits) | 126 | * a.b (with b treated as 24 bits) |
| 115 | */ | 127 | */ |
| 116 | if (pp >= parts + 3 || val > 0xff) | 128 | if (pp >= parts + 3) |
| 117 | return (0); | 129 | return (0); |
| 118 | *pp++ = val, cp++; | 130 | *pp++ = val; |
| 131 | c = *++cp; | ||
| 119 | } else | 132 | } else |
| 120 | break; | 133 | break; |
| 121 | } | 134 | } |
| 122 | /* | 135 | /* |
| 123 | * Check for trailing characters. | 136 | * Check for trailing characters. |
| 124 | */ | 137 | */ |
| 125 | if (*cp && (!isascii(*cp) || !isspace(*cp))) | 138 | if (c != '\0' && |
| 139 | (!isascii((unsigned char)c) || !isspace((unsigned char)c))) | ||
| 126 | return (0); | 140 | return (0); |
| 127 | /* | 141 | /* |
| 128 | * Concoct the address according to | 142 | * Concoct the address according to |
| @@ -131,23 +145,26 @@ inet_aton(cp, addr) | |||
| 131 | n = pp - parts + 1; | 145 | n = pp - parts + 1; |
| 132 | switch (n) { | 146 | switch (n) { |
| 133 | 147 | ||
| 148 | case 0: | ||
| 149 | return (0); /* initial nondigit */ | ||
| 150 | |||
| 134 | case 1: /* a -- 32 bits */ | 151 | case 1: /* a -- 32 bits */ |
| 135 | break; | 152 | break; |
| 136 | 153 | ||
| 137 | case 2: /* a.b -- 8.24 bits */ | 154 | case 2: /* a.b -- 8.24 bits */ |
| 138 | if (val > 0xffffff) | 155 | if ((val > 0xffffff) || (parts[0] > 0xff)) |
| 139 | return (0); | 156 | return (0); |
| 140 | val |= parts[0] << 24; | 157 | val |= parts[0] << 24; |
| 141 | break; | 158 | break; |
| 142 | 159 | ||
| 143 | case 3: /* a.b.c -- 8.8.16 bits */ | 160 | case 3: /* a.b.c -- 8.8.16 bits */ |
| 144 | if (val > 0xffff) | 161 | if ((val > 0xffff) || (parts[0] > 0xff) || (parts[1] > 0xff)) |
| 145 | return (0); | 162 | return (0); |
| 146 | val |= (parts[0] << 24) | (parts[1] << 16); | 163 | val |= (parts[0] << 24) | (parts[1] << 16); |
| 147 | break; | 164 | break; |
| 148 | 165 | ||
| 149 | case 4: /* a.b.c.d -- 8.8.8.8 bits */ | 166 | case 4: /* a.b.c.d -- 8.8.8.8 bits */ |
| 150 | if (val > 0xff) | 167 | if ((val > 0xff) || (parts[0] > 0xff) || (parts[1] > 0xff) || (parts[2] > 0xff)) |
| 151 | return (0); | 168 | return (0); |
| 152 | val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); | 169 | val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); |
| 153 | break; | 170 | break; |
diff --git a/src/lib/libc/net/inet_lnaof.c b/src/lib/libc/net/inet_lnaof.c index ce1257bf68..b1a58cd2c1 100644 --- a/src/lib/libc/net/inet_lnaof.c +++ b/src/lib/libc/net/inet_lnaof.c | |||
| @@ -1,5 +1,4 @@ | |||
| 1 | /* $NetBSD: inet_lnaof.c,v 1.4 1995/02/25 06:20:42 cgd Exp $ */ | 1 | /* $OpenBSD: inet_lnaof.c,v 1.6 2005/08/06 20:30:03 espie Exp $ */ |
| 2 | |||
| 3 | /* | 2 | /* |
| 4 | * Copyright (c) 1983, 1993 | 3 | * Copyright (c) 1983, 1993 |
| 5 | * The Regents of the University of California. All rights reserved. | 4 | * The Regents of the University of California. All rights reserved. |
| @@ -12,11 +11,7 @@ | |||
| 12 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
| 13 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the |
| 14 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. |
| 15 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. Neither the name of the University nor the names of its contributors |
| 16 | * must display the following acknowledgement: | ||
| 17 | * This product includes software developed by the University of | ||
| 18 | * California, Berkeley and its contributors. | ||
| 19 | * 4. Neither the name of the University nor the names of its contributors | ||
| 20 | * may be used to endorse or promote products derived from this software | 15 | * may be used to endorse or promote products derived from this software |
| 21 | * without specific prior written permission. | 16 | * without specific prior written permission. |
| 22 | * | 17 | * |
| @@ -33,14 +28,6 @@ | |||
| 33 | * SUCH DAMAGE. | 28 | * SUCH DAMAGE. |
| 34 | */ | 29 | */ |
| 35 | 30 | ||
| 36 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 37 | #if 0 | ||
| 38 | static char sccsid[] = "@(#)inet_lnaof.c 8.1 (Berkeley) 6/4/93"; | ||
| 39 | #else | ||
| 40 | static char rcsid[] = "$NetBSD: inet_lnaof.c,v 1.4 1995/02/25 06:20:42 cgd Exp $"; | ||
| 41 | #endif | ||
| 42 | #endif /* LIBC_SCCS and not lint */ | ||
| 43 | |||
| 44 | #include <sys/param.h> | 31 | #include <sys/param.h> |
| 45 | #include <netinet/in.h> | 32 | #include <netinet/in.h> |
| 46 | #include <arpa/inet.h> | 33 | #include <arpa/inet.h> |
| @@ -50,11 +37,10 @@ static char rcsid[] = "$NetBSD: inet_lnaof.c,v 1.4 1995/02/25 06:20:42 cgd Exp $ | |||
| 50 | * internet address; handles class a/b/c network | 37 | * internet address; handles class a/b/c network |
| 51 | * number formats. | 38 | * number formats. |
| 52 | */ | 39 | */ |
| 53 | u_long | 40 | in_addr_t |
| 54 | inet_lnaof(in) | 41 | inet_lnaof(struct in_addr in) |
| 55 | struct in_addr in; | ||
| 56 | { | 42 | { |
| 57 | register u_long i = ntohl(in.s_addr); | 43 | in_addr_t i = ntohl(in.s_addr); |
| 58 | 44 | ||
| 59 | if (IN_CLASSA(i)) | 45 | if (IN_CLASSA(i)) |
| 60 | return ((i)&IN_CLASSA_HOST); | 46 | return ((i)&IN_CLASSA_HOST); |
diff --git a/src/lib/libc/net/inet_makeaddr.c b/src/lib/libc/net/inet_makeaddr.c index 84d366e03a..87d9325231 100644 --- a/src/lib/libc/net/inet_makeaddr.c +++ b/src/lib/libc/net/inet_makeaddr.c | |||
| @@ -1,5 +1,4 @@ | |||
| 1 | /* $NetBSD: inet_makeaddr.c,v 1.4 1995/02/25 06:20:42 cgd Exp $ */ | 1 | /* $OpenBSD: inet_makeaddr.c,v 1.6 2005/08/06 20:30:03 espie Exp $ */ |
| 2 | |||
| 3 | /* | 2 | /* |
| 4 | * Copyright (c) 1983, 1993 | 3 | * Copyright (c) 1983, 1993 |
| 5 | * The Regents of the University of California. All rights reserved. | 4 | * The Regents of the University of California. All rights reserved. |
| @@ -12,11 +11,7 @@ | |||
| 12 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
| 13 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the |
| 14 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. |
| 15 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. Neither the name of the University nor the names of its contributors |
| 16 | * must display the following acknowledgement: | ||
| 17 | * This product includes software developed by the University of | ||
| 18 | * California, Berkeley and its contributors. | ||
| 19 | * 4. Neither the name of the University nor the names of its contributors | ||
| 20 | * may be used to endorse or promote products derived from this software | 15 | * may be used to endorse or promote products derived from this software |
| 21 | * without specific prior written permission. | 16 | * without specific prior written permission. |
| 22 | * | 17 | * |
| @@ -33,14 +28,6 @@ | |||
| 33 | * SUCH DAMAGE. | 28 | * SUCH DAMAGE. |
| 34 | */ | 29 | */ |
| 35 | 30 | ||
| 36 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 37 | #if 0 | ||
| 38 | static char sccsid[] = "@(#)inet_makeaddr.c 8.1 (Berkeley) 6/4/93"; | ||
| 39 | #else | ||
| 40 | static char rcsid[] = "$NetBSD: inet_makeaddr.c,v 1.4 1995/02/25 06:20:42 cgd Exp $"; | ||
| 41 | #endif | ||
| 42 | #endif /* LIBC_SCCS and not lint */ | ||
| 43 | |||
| 44 | #include <sys/param.h> | 31 | #include <sys/param.h> |
| 45 | #include <netinet/in.h> | 32 | #include <netinet/in.h> |
| 46 | #include <arpa/inet.h> | 33 | #include <arpa/inet.h> |
| @@ -50,10 +37,9 @@ static char rcsid[] = "$NetBSD: inet_makeaddr.c,v 1.4 1995/02/25 06:20:42 cgd Ex | |||
| 50 | * building addresses stored in the ifnet structure. | 37 | * building addresses stored in the ifnet structure. |
| 51 | */ | 38 | */ |
| 52 | struct in_addr | 39 | struct in_addr |
| 53 | inet_makeaddr(net, host) | 40 | inet_makeaddr(in_addr_t net, in_addr_t host) |
| 54 | u_long net, host; | ||
| 55 | { | 41 | { |
| 56 | u_long addr; | 42 | in_addr_t addr; |
| 57 | 43 | ||
| 58 | if (net < 128) | 44 | if (net < 128) |
| 59 | addr = (net << IN_CLASSA_NSHIFT) | (host & IN_CLASSA_HOST); | 45 | addr = (net << IN_CLASSA_NSHIFT) | (host & IN_CLASSA_HOST); |
diff --git a/src/lib/libc/net/inet_net.3 b/src/lib/libc/net/inet_net.3 new file mode 100644 index 0000000000..a0231b4537 --- /dev/null +++ b/src/lib/libc/net/inet_net.3 | |||
| @@ -0,0 +1,197 @@ | |||
| 1 | .\" $OpenBSD: inet_net.3,v 1.16 2013/06/05 03:39:23 tedu 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 | .\" | ||
| 19 | .\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | ||
| 20 | .\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | ||
| 21 | .\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
| 22 | .\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE | ||
| 23 | .\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
| 24 | .\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
| 25 | .\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
| 26 | .\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
| 27 | .\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
| 28 | .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 29 | .\" POSSIBILITY OF SUCH DAMAGE. | ||
| 30 | .\" | ||
| 31 | .Dd $Mdocdate: June 5 2013 $ | ||
| 32 | .Dt INET_NET 3 | ||
| 33 | .Os | ||
| 34 | .Sh NAME | ||
| 35 | .Nm inet_net_ntop , | ||
| 36 | .Nm inet_net_pton | ||
| 37 | .Nd Internet network number manipulation routines | ||
| 38 | .Sh SYNOPSIS | ||
| 39 | .In sys/types.h | ||
| 40 | .In sys/socket.h | ||
| 41 | .In netinet/in.h | ||
| 42 | .In arpa/inet.h | ||
| 43 | .Ft char * | ||
| 44 | .Fn inet_net_ntop "int af" "const void *src" "int bits" "char *dst" "size_t size" | ||
| 45 | .Ft int | ||
| 46 | .Fn inet_net_pton "int af" "const char *src" "void *dst" "size_t size" | ||
| 47 | .Sh DESCRIPTION | ||
| 48 | The | ||
| 49 | .Fn inet_net_ntop | ||
| 50 | function converts an Internet network number from network format (usually a | ||
| 51 | .Li struct in_addr | ||
| 52 | or some other binary form, in network byte order) to CIDR presentation format | ||
| 53 | (suitable for external display purposes). | ||
| 54 | .Fa bits | ||
| 55 | is the number of bits in | ||
| 56 | .Fa src | ||
| 57 | that are the network number. | ||
| 58 | It returns | ||
| 59 | .Dv NULL | ||
| 60 | if a system error occurs (in which case, | ||
| 61 | .Va errno | ||
| 62 | will have been set), or it returns a pointer to the destination string. | ||
| 63 | .Pp | ||
| 64 | The | ||
| 65 | .Fn inet_net_pton | ||
| 66 | function converts a presentation format Internet network number (that is, | ||
| 67 | printable form as held in a character string) to network format (usually a | ||
| 68 | .Li struct in_addr | ||
| 69 | or some other internal binary representation, in network byte order). | ||
| 70 | It returns the number of bits (either computed based on the class, or | ||
| 71 | specified with /CIDR), or \-1 if a failure occurred | ||
| 72 | (in which case | ||
| 73 | .Va errno | ||
| 74 | will have been set. | ||
| 75 | It will be set to | ||
| 76 | .Er ENOENT | ||
| 77 | if the Internet network number was not valid). | ||
| 78 | .Pp | ||
| 79 | Caution: | ||
| 80 | The | ||
| 81 | .Fa dst | ||
| 82 | field should be zeroed before calling | ||
| 83 | .Fn inet_net_pton | ||
| 84 | as the function will only fill the number of bytes necessary to | ||
| 85 | encode the network number in network byte order. | ||
| 86 | .Pp | ||
| 87 | The only values for | ||
| 88 | .Fa af | ||
| 89 | currently supported are | ||
| 90 | .Dv AF_INET | ||
| 91 | and | ||
| 92 | .Dv AF_INET6 . | ||
| 93 | .Fa size | ||
| 94 | is the size of the result buffer | ||
| 95 | .Fa dst . | ||
| 96 | .Sh NETWORK NUMBERS (IP VERSION 4) | ||
| 97 | The external representation of Internet network numbers may be specified in | ||
| 98 | one of the following forms: | ||
| 99 | .Bd -literal -offset indent | ||
| 100 | a | ||
| 101 | a.b | ||
| 102 | a.b.c | ||
| 103 | a.b.c.d | ||
| 104 | .Ed | ||
| 105 | .Pp | ||
| 106 | Any of the above four forms may have | ||
| 107 | .Dq Li /bits | ||
| 108 | appended where | ||
| 109 | .Dq Li bits | ||
| 110 | is in the range | ||
| 111 | .Li 0-32 | ||
| 112 | and is used to explicitly specify the number of bits in the network address. | ||
| 113 | When | ||
| 114 | .Dq Li /bits | ||
| 115 | is not specified the number of bits in the network address is calculated | ||
| 116 | as the larger of the number of bits in the class to which the address | ||
| 117 | belongs and the number of bits provided rounded up modulo 8. | ||
| 118 | Examples: | ||
| 119 | .Pp | ||
| 120 | .Bl -tag -width 10.1.2.3/24 -offset indent -compact | ||
| 121 | .It Li 10 | ||
| 122 | an 8-bit network number (class A), value | ||
| 123 | .Li 10.0.0.0 . | ||
| 124 | .It Li 192 | ||
| 125 | a 24-bit network number (class C), value | ||
| 126 | .Li 192.0.0.0 . | ||
| 127 | .It Li 10.10 | ||
| 128 | a 16-bit network number, value | ||
| 129 | .Li 10.10.0.0 . | ||
| 130 | .It Li 10.1.2 | ||
| 131 | a 24-bit network number, value | ||
| 132 | .Li 10.1.2.0 . | ||
| 133 | .It Li 10.1.2.3 | ||
| 134 | a 32-bit network number, value | ||
| 135 | .Li 10.1.2.3 . | ||
| 136 | .It Li 10.1.2.3/24 | ||
| 137 | a 24-bit network number (explicit), value | ||
| 138 | .Li 10.1.2.3 . | ||
| 139 | .El | ||
| 140 | .Pp | ||
| 141 | Note that when the number of bits is specified using | ||
| 142 | .Dq Li /bits | ||
| 143 | notation, the value of the address still includes all bits supplied | ||
| 144 | in the external representation, even those bits which are the host | ||
| 145 | part of an Internet address. | ||
| 146 | Also, unlike | ||
| 147 | .Xr inet_pton 3 | ||
| 148 | where the external representation is assumed to be a host address, the | ||
| 149 | external representation for | ||
| 150 | .Fn inet_net_pton | ||
| 151 | is assumed to be a network address. | ||
| 152 | Thus | ||
| 153 | .Dq Li 10.1 | ||
| 154 | is assumed to be | ||
| 155 | .Dq Li 10.1.0.0 | ||
| 156 | not | ||
| 157 | .Dq Li 10.0.0.1 | ||
| 158 | .Pp | ||
| 159 | All numbers supplied as | ||
| 160 | .Dq parts | ||
| 161 | in a | ||
| 162 | .Ql \&. | ||
| 163 | notation | ||
| 164 | may be decimal, octal, or hexadecimal, as specified | ||
| 165 | in the C language (i.e., a leading 0x or 0X implies | ||
| 166 | hexadecimal; otherwise, a leading 0 implies octal; | ||
| 167 | otherwise, the number is interpreted as decimal). | ||
| 168 | .Sh NETWORK NUMBERS (IP VERSION 6) | ||
| 169 | See | ||
| 170 | .Xr inet_pton 3 | ||
| 171 | for valid external representations of IP version 6 addresses. | ||
| 172 | A valid external representation may have | ||
| 173 | .Dq Li /bits | ||
| 174 | appended where | ||
| 175 | .Dq Li bits | ||
| 176 | is in the range | ||
| 177 | .Li 0-128 | ||
| 178 | and is used to explicitly specify the number of bits in the network address. | ||
| 179 | When | ||
| 180 | .Dq Li /bits | ||
| 181 | is not specified 128 is used. | ||
| 182 | Note that when the number of bits is specified using | ||
| 183 | .Dq Li /bits | ||
| 184 | notation, the value of the address still includes all bits supplied | ||
| 185 | in the external representation, even those bits which are the host | ||
| 186 | part of an Internet address. | ||
| 187 | .Sh SEE ALSO | ||
| 188 | .Xr byteorder 3 , | ||
| 189 | .Xr inet 3 , | ||
| 190 | .Xr inet_pton 3 , | ||
| 191 | .Xr networks 5 | ||
| 192 | .Sh HISTORY | ||
| 193 | The | ||
| 194 | .Nm inet_net_ntop | ||
| 195 | and | ||
| 196 | .Nm inet_net_pton | ||
| 197 | functions 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..35ae7909d3 --- /dev/null +++ b/src/lib/libc/net/inet_net_ntop.c | |||
| @@ -0,0 +1,162 @@ | |||
| 1 | /* $OpenBSD: inet_net_ntop.c,v 1.7 2012/06/22 19:13:37 gilles Exp $ */ | ||
| 2 | |||
| 3 | /* | ||
| 4 | * Copyright (c) 2012 by Gilles Chehade <gilles@openbsd.org> | ||
| 5 | * Copyright (c) 1996 by Internet Software Consortium. | ||
| 6 | * | ||
| 7 | * Permission to use, copy, modify, and distribute this software for any | ||
| 8 | * purpose with or without fee is hereby granted, provided that the above | ||
| 9 | * copyright notice and this permission notice appear in all copies. | ||
| 10 | * | ||
| 11 | * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS | ||
| 12 | * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES | ||
| 13 | * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE | ||
| 14 | * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | ||
| 15 | * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR | ||
| 16 | * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS | ||
| 17 | * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | ||
| 18 | * SOFTWARE. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include <sys/types.h> | ||
| 22 | #include <sys/socket.h> | ||
| 23 | #include <netinet/in.h> | ||
| 24 | #include <arpa/inet.h> | ||
| 25 | |||
| 26 | #include <errno.h> | ||
| 27 | #include <stdio.h> | ||
| 28 | #include <string.h> | ||
| 29 | #include <stdlib.h> | ||
| 30 | |||
| 31 | static char *inet_net_ntop_ipv4(const u_char *, int, char *, size_t); | ||
| 32 | static char *inet_net_ntop_ipv6(const u_char *, int, char *, size_t); | ||
| 33 | |||
| 34 | /* | ||
| 35 | * char * | ||
| 36 | * inet_net_ntop(af, src, bits, dst, size) | ||
| 37 | * convert network number from network to presentation format. | ||
| 38 | * generates CIDR style result always. | ||
| 39 | * return: | ||
| 40 | * pointer to dst, or NULL if an error occurred (check errno). | ||
| 41 | * author: | ||
| 42 | * Paul Vixie (ISC), July 1996 | ||
| 43 | */ | ||
| 44 | char * | ||
| 45 | inet_net_ntop(int af, const void *src, int bits, char *dst, size_t size) | ||
| 46 | { | ||
| 47 | switch (af) { | ||
| 48 | case AF_INET: | ||
| 49 | return (inet_net_ntop_ipv4(src, bits, dst, size)); | ||
| 50 | case AF_INET6: | ||
| 51 | return (inet_net_ntop_ipv6(src, bits, dst, size)); | ||
| 52 | default: | ||
| 53 | errno = EAFNOSUPPORT; | ||
| 54 | return (NULL); | ||
| 55 | } | ||
| 56 | } | ||
| 57 | |||
| 58 | /* | ||
| 59 | * static char * | ||
| 60 | * inet_net_ntop_ipv4(src, bits, dst, size) | ||
| 61 | * convert IPv4 network number from network to presentation format. | ||
| 62 | * generates CIDR style result always. | ||
| 63 | * return: | ||
| 64 | * pointer to dst, or NULL if an error occurred (check errno). | ||
| 65 | * note: | ||
| 66 | * network byte order assumed. this means 192.5.5.240/28 has | ||
| 67 | * 0x11110000 in its fourth octet. | ||
| 68 | * author: | ||
| 69 | * Paul Vixie (ISC), July 1996 | ||
| 70 | */ | ||
| 71 | static char * | ||
| 72 | inet_net_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size) | ||
| 73 | { | ||
| 74 | char *odst = dst; | ||
| 75 | u_int m; | ||
| 76 | int b; | ||
| 77 | char *ep; | ||
| 78 | int advance; | ||
| 79 | |||
| 80 | ep = dst + size; | ||
| 81 | if (ep <= dst) | ||
| 82 | goto emsgsize; | ||
| 83 | |||
| 84 | if (bits < 0 || bits > 32) { | ||
| 85 | errno = EINVAL; | ||
| 86 | return (NULL); | ||
| 87 | } | ||
| 88 | if (bits == 0) { | ||
| 89 | if (ep - dst < sizeof "0") | ||
| 90 | goto emsgsize; | ||
| 91 | *dst++ = '0'; | ||
| 92 | *dst = '\0'; | ||
| 93 | } | ||
| 94 | |||
| 95 | /* Format whole octets. */ | ||
| 96 | for (b = bits / 8; b > 0; b--) { | ||
| 97 | if (ep - dst < sizeof "255.") | ||
| 98 | goto emsgsize; | ||
| 99 | advance = snprintf(dst, ep - dst, "%u", *src++); | ||
| 100 | if (advance <= 0 || advance >= ep - dst) | ||
| 101 | goto emsgsize; | ||
| 102 | dst += advance; | ||
| 103 | if (b > 1) { | ||
| 104 | if (dst + 1 >= ep) | ||
| 105 | goto emsgsize; | ||
| 106 | *dst++ = '.'; | ||
| 107 | *dst = '\0'; | ||
| 108 | } | ||
| 109 | } | ||
| 110 | |||
| 111 | /* Format partial octet. */ | ||
| 112 | b = bits % 8; | ||
| 113 | if (b > 0) { | ||
| 114 | if (ep - dst < sizeof ".255") | ||
| 115 | goto emsgsize; | ||
| 116 | if (dst != odst) | ||
| 117 | if (dst + 1 >= ep) | ||
| 118 | goto emsgsize; | ||
| 119 | *dst++ = '.'; | ||
| 120 | m = ((1 << b) - 1) << (8 - b); | ||
| 121 | advance = snprintf(dst, ep - dst, "%u", *src & m); | ||
| 122 | if (advance <= 0 || advance >= ep - dst) | ||
| 123 | goto emsgsize; | ||
| 124 | dst += advance; | ||
| 125 | } | ||
| 126 | |||
| 127 | /* Format CIDR /width. */ | ||
| 128 | if (ep - dst < sizeof "/32") | ||
| 129 | goto emsgsize; | ||
| 130 | advance = snprintf(dst, ep - dst, "/%u", bits); | ||
| 131 | if (advance <= 0 || advance >= ep - dst) | ||
| 132 | goto emsgsize; | ||
| 133 | dst += advance; | ||
| 134 | return (odst); | ||
| 135 | |||
| 136 | emsgsize: | ||
| 137 | errno = EMSGSIZE; | ||
| 138 | return (NULL); | ||
| 139 | } | ||
| 140 | |||
| 141 | static char * | ||
| 142 | inet_net_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size) | ||
| 143 | { | ||
| 144 | int ret; | ||
| 145 | char buf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255:255:255:255/128")]; | ||
| 146 | |||
| 147 | if (bits < 0 || bits > 128) { | ||
| 148 | errno = EINVAL; | ||
| 149 | return (NULL); | ||
| 150 | } | ||
| 151 | |||
| 152 | if (inet_ntop(AF_INET6, src, buf, size) == NULL) | ||
| 153 | return (NULL); | ||
| 154 | |||
| 155 | ret = snprintf(dst, size, "%s/%d", buf, bits); | ||
| 156 | if (ret == -1 || ret >= size) { | ||
| 157 | errno = EMSGSIZE; | ||
| 158 | return (NULL); | ||
| 159 | } | ||
| 160 | |||
| 161 | return (dst); | ||
| 162 | } | ||
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..1683a79043 --- /dev/null +++ b/src/lib/libc/net/inet_net_pton.c | |||
| @@ -0,0 +1,231 @@ | |||
| 1 | /* $OpenBSD: inet_net_pton.c,v 1.8 2013/11/25 18:23:51 deraadt Exp $ */ | ||
| 2 | |||
| 3 | /* | ||
| 4 | * Copyright (c) 2012 by Gilles Chehade <gilles@openbsd.org> | ||
| 5 | * Copyright (c) 1996 by Internet Software Consortium. | ||
| 6 | * | ||
| 7 | * Permission to use, copy, modify, and distribute this software for any | ||
| 8 | * purpose with or without fee is hereby granted, provided that the above | ||
| 9 | * copyright notice and this permission notice appear in all copies. | ||
| 10 | * | ||
| 11 | * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS | ||
| 12 | * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES | ||
| 13 | * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE | ||
| 14 | * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | ||
| 15 | * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR | ||
| 16 | * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS | ||
| 17 | * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | ||
| 18 | * SOFTWARE. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include <sys/types.h> | ||
| 22 | #include <sys/socket.h> | ||
| 23 | #include <netinet/in.h> | ||
| 24 | #include <arpa/inet.h> | ||
| 25 | |||
| 26 | #include <assert.h> | ||
| 27 | #include <ctype.h> | ||
| 28 | #include <errno.h> | ||
| 29 | #include <stdio.h> | ||
| 30 | #include <string.h> | ||
| 31 | #include <stdlib.h> | ||
| 32 | |||
| 33 | static int inet_net_pton_ipv4(const char *, u_char *, size_t); | ||
| 34 | static int inet_net_pton_ipv6(const char *, u_char *, size_t); | ||
| 35 | |||
| 36 | /* | ||
| 37 | * static int | ||
| 38 | * inet_net_pton(af, src, dst, size) | ||
| 39 | * convert network number from presentation to network format. | ||
| 40 | * accepts hex octets, hex strings, decimal octets, and /CIDR. | ||
| 41 | * "size" is in bytes and describes "dst". | ||
| 42 | * return: | ||
| 43 | * number of bits, either imputed classfully or specified with /CIDR, | ||
| 44 | * or -1 if some failure occurred (check errno). ENOENT means it was | ||
| 45 | * not a valid network specification. | ||
| 46 | * author: | ||
| 47 | * Paul Vixie (ISC), June 1996 | ||
| 48 | */ | ||
| 49 | int | ||
| 50 | inet_net_pton(int af, const char *src, void *dst, size_t size) | ||
| 51 | { | ||
| 52 | switch (af) { | ||
| 53 | case AF_INET: | ||
| 54 | return (inet_net_pton_ipv4(src, dst, size)); | ||
| 55 | case AF_INET6: | ||
| 56 | return (inet_net_pton_ipv6(src, dst, size)); | ||
| 57 | default: | ||
| 58 | errno = EAFNOSUPPORT; | ||
| 59 | return (-1); | ||
| 60 | } | ||
| 61 | } | ||
| 62 | |||
| 63 | /* | ||
| 64 | * static int | ||
| 65 | * inet_net_pton_ipv4(src, dst, size) | ||
| 66 | * convert IPv4 network number from presentation to network format. | ||
| 67 | * accepts hex octets, hex strings, decimal octets, and /CIDR. | ||
| 68 | * "size" is in bytes and describes "dst". | ||
| 69 | * return: | ||
| 70 | * number of bits, either imputed classfully or specified with /CIDR, | ||
| 71 | * or -1 if some failure occurred (check errno). ENOENT means it was | ||
| 72 | * not an IPv4 network specification. | ||
| 73 | * note: | ||
| 74 | * network byte order assumed. this means 192.5.5.240/28 has | ||
| 75 | * 0x11110000 in its fourth octet. | ||
| 76 | * author: | ||
| 77 | * Paul Vixie (ISC), June 1996 | ||
| 78 | */ | ||
| 79 | static int | ||
| 80 | inet_net_pton_ipv4(const char *src, u_char *dst, size_t size) | ||
| 81 | { | ||
| 82 | static const char | ||
| 83 | xdigits[] = "0123456789abcdef", | ||
| 84 | digits[] = "0123456789"; | ||
| 85 | int n, ch, tmp, dirty, bits; | ||
| 86 | const u_char *odst = dst; | ||
| 87 | |||
| 88 | ch = (unsigned char)*src++; | ||
| 89 | if (ch == '0' && (src[0] == 'x' || src[0] == 'X') | ||
| 90 | && isascii((unsigned char)src[1]) && isxdigit((unsigned char)src[1])) { | ||
| 91 | /* Hexadecimal: Eat nybble string. */ | ||
| 92 | if (size <= 0) | ||
| 93 | goto emsgsize; | ||
| 94 | *dst = 0, dirty = 0; | ||
| 95 | src++; /* skip x or X. */ | ||
| 96 | while ((ch = (unsigned char)*src++) != '\0' && | ||
| 97 | isascii(ch) && isxdigit(ch)) { | ||
| 98 | if (isupper(ch)) | ||
| 99 | ch = tolower(ch); | ||
| 100 | n = strchr(xdigits, ch) - xdigits; | ||
| 101 | assert(n >= 0 && n <= 15); | ||
| 102 | *dst |= n; | ||
| 103 | if (!dirty++) | ||
| 104 | *dst <<= 4; | ||
| 105 | else if (size-- > 0) | ||
| 106 | *++dst = 0, dirty = 0; | ||
| 107 | else | ||
| 108 | goto emsgsize; | ||
| 109 | } | ||
| 110 | if (dirty) | ||
| 111 | size--; | ||
| 112 | } else if (isascii(ch) && isdigit(ch)) { | ||
| 113 | /* Decimal: eat dotted digit string. */ | ||
| 114 | for (;;) { | ||
| 115 | tmp = 0; | ||
| 116 | do { | ||
| 117 | n = strchr(digits, ch) - digits; | ||
| 118 | assert(n >= 0 && n <= 9); | ||
| 119 | tmp *= 10; | ||
| 120 | tmp += n; | ||
| 121 | if (tmp > 255) | ||
| 122 | goto enoent; | ||
| 123 | } while ((ch = (unsigned char)*src++) != '\0' && | ||
| 124 | isascii(ch) && isdigit(ch)); | ||
| 125 | if (size-- <= 0) | ||
| 126 | goto emsgsize; | ||
| 127 | *dst++ = (u_char) tmp; | ||
| 128 | if (ch == '\0' || ch == '/') | ||
| 129 | break; | ||
| 130 | if (ch != '.') | ||
| 131 | goto enoent; | ||
| 132 | ch = (unsigned char)*src++; | ||
| 133 | if (!isascii(ch) || !isdigit(ch)) | ||
| 134 | goto enoent; | ||
| 135 | } | ||
| 136 | } else | ||
| 137 | goto enoent; | ||
| 138 | |||
| 139 | bits = -1; | ||
| 140 | if (ch == '/' && isascii((unsigned char)src[0]) && | ||
| 141 | isdigit((unsigned char)src[0]) && dst > odst) { | ||
| 142 | /* CIDR width specifier. Nothing can follow it. */ | ||
| 143 | ch = (unsigned char)*src++; /* Skip over the /. */ | ||
| 144 | bits = 0; | ||
| 145 | do { | ||
| 146 | n = strchr(digits, ch) - digits; | ||
| 147 | assert(n >= 0 && n <= 9); | ||
| 148 | bits *= 10; | ||
| 149 | bits += n; | ||
| 150 | if (bits > 32) | ||
| 151 | goto emsgsize; | ||
| 152 | } while ((ch = (unsigned char)*src++) != '\0' && | ||
| 153 | isascii(ch) && isdigit(ch)); | ||
| 154 | if (ch != '\0') | ||
| 155 | goto enoent; | ||
| 156 | } | ||
| 157 | |||
| 158 | /* Firey death and destruction unless we prefetched EOS. */ | ||
| 159 | if (ch != '\0') | ||
| 160 | goto enoent; | ||
| 161 | |||
| 162 | /* If nothing was written to the destination, we found no address. */ | ||
| 163 | if (dst == odst) | ||
| 164 | goto enoent; | ||
| 165 | /* If no CIDR spec was given, infer width from net class. */ | ||
| 166 | if (bits == -1) { | ||
| 167 | if (*odst >= 240) /* Class E */ | ||
| 168 | bits = 32; | ||
| 169 | else if (*odst >= 224) /* Class D */ | ||
| 170 | bits = 4; | ||
| 171 | else if (*odst >= 192) /* Class C */ | ||
| 172 | bits = 24; | ||
| 173 | else if (*odst >= 128) /* Class B */ | ||
| 174 | bits = 16; | ||
| 175 | else /* Class A */ | ||
| 176 | bits = 8; | ||
| 177 | /* If imputed mask is narrower than specified octets, widen. */ | ||
| 178 | if (bits < ((dst - odst) * 8)) | ||
| 179 | bits = (dst - odst) * 8; | ||
| 180 | } | ||
| 181 | /* Extend network to cover the actual mask. */ | ||
| 182 | while (bits > ((dst - odst) * 8)) { | ||
| 183 | if (size-- <= 0) | ||
| 184 | goto emsgsize; | ||
| 185 | *dst++ = '\0'; | ||
| 186 | } | ||
| 187 | return (bits); | ||
| 188 | |||
| 189 | enoent: | ||
| 190 | errno = ENOENT; | ||
| 191 | return (-1); | ||
| 192 | |||
| 193 | emsgsize: | ||
| 194 | errno = EMSGSIZE; | ||
| 195 | return (-1); | ||
| 196 | } | ||
| 197 | |||
| 198 | |||
| 199 | static int | ||
| 200 | inet_net_pton_ipv6(const char *src, u_char *dst, size_t size) | ||
| 201 | { | ||
| 202 | int ret; | ||
| 203 | int bits; | ||
| 204 | char buf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255:255:255:255/128")]; | ||
| 205 | char *sep; | ||
| 206 | const char *errstr; | ||
| 207 | |||
| 208 | if (strlcpy(buf, src, sizeof buf) >= sizeof buf) { | ||
| 209 | errno = EMSGSIZE; | ||
| 210 | return (-1); | ||
| 211 | } | ||
| 212 | |||
| 213 | sep = strchr(buf, '/'); | ||
| 214 | if (sep != NULL) | ||
| 215 | *sep++ = '\0'; | ||
| 216 | |||
| 217 | ret = inet_pton(AF_INET6, buf, dst); | ||
| 218 | if (ret != 1) | ||
| 219 | return (-1); | ||
| 220 | |||
| 221 | if (sep == NULL) | ||
| 222 | return 128; | ||
| 223 | |||
| 224 | bits = strtonum(sep, 0, 128, &errstr); | ||
| 225 | if (errstr) { | ||
| 226 | errno = EINVAL; | ||
| 227 | return (-1); | ||
| 228 | } | ||
| 229 | |||
| 230 | return bits; | ||
| 231 | } | ||
diff --git a/src/lib/libc/net/inet_neta.c b/src/lib/libc/net/inet_neta.c new file mode 100644 index 0000000000..e3e7d0eb71 --- /dev/null +++ b/src/lib/libc/net/inet_neta.c | |||
| @@ -0,0 +1,80 @@ | |||
| 1 | /* $OpenBSD: inet_neta.c,v 1.7 2005/08/06 20:30:03 espie 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 | #include <sys/types.h> | ||
| 21 | #include <sys/socket.h> | ||
| 22 | #include <netinet/in.h> | ||
| 23 | #include <arpa/inet.h> | ||
| 24 | |||
| 25 | #include <errno.h> | ||
| 26 | #include <stdio.h> | ||
| 27 | #include <string.h> | ||
| 28 | |||
| 29 | /* | ||
| 30 | * char * | ||
| 31 | * inet_neta(src, dst, size) | ||
| 32 | * format an in_addr_t network number into presentation format. | ||
| 33 | * return: | ||
| 34 | * pointer to dst, or NULL if an error occurred (check errno). | ||
| 35 | * note: | ||
| 36 | * format of ``src'' is as for inet_network(). | ||
| 37 | * author: | ||
| 38 | * Paul Vixie (ISC), July 1996 | ||
| 39 | */ | ||
| 40 | char * | ||
| 41 | inet_neta(in_addr_t src, char *dst, size_t size) | ||
| 42 | { | ||
| 43 | char *odst = dst; | ||
| 44 | char *ep; | ||
| 45 | int advance; | ||
| 46 | |||
| 47 | if (src == 0x00000000) { | ||
| 48 | if (size < sizeof "0.0.0.0") | ||
| 49 | goto emsgsize; | ||
| 50 | strlcpy(dst, "0.0.0.0", size); | ||
| 51 | return dst; | ||
| 52 | } | ||
| 53 | ep = dst + size; | ||
| 54 | if (ep <= dst) | ||
| 55 | goto emsgsize; | ||
| 56 | while (src & 0xffffffff) { | ||
| 57 | u_char b = (src & 0xff000000) >> 24; | ||
| 58 | |||
| 59 | src <<= 8; | ||
| 60 | if (b || src) { | ||
| 61 | if (ep - dst < sizeof "255.") | ||
| 62 | goto emsgsize; | ||
| 63 | advance = snprintf(dst, ep - dst, "%u", b); | ||
| 64 | if (advance <= 0 || advance >= ep - dst) | ||
| 65 | goto emsgsize; | ||
| 66 | dst += advance; | ||
| 67 | if (src != 0L) { | ||
| 68 | if (dst + 1 >= ep) | ||
| 69 | goto emsgsize; | ||
| 70 | *dst++ = '.'; | ||
| 71 | *dst = '\0'; | ||
| 72 | } | ||
| 73 | } | ||
| 74 | } | ||
| 75 | return (odst); | ||
| 76 | |||
| 77 | emsgsize: | ||
| 78 | errno = EMSGSIZE; | ||
| 79 | return (NULL); | ||
| 80 | } | ||
diff --git a/src/lib/libc/net/inet_netof.c b/src/lib/libc/net/inet_netof.c index 02f52ca318..2f468c3aca 100644 --- a/src/lib/libc/net/inet_netof.c +++ b/src/lib/libc/net/inet_netof.c | |||
| @@ -1,5 +1,4 @@ | |||
| 1 | /* $NetBSD: inet_netof.c,v 1.4 1995/02/25 06:20:43 cgd Exp $ */ | 1 | /* $OpenBSD: inet_netof.c,v 1.6 2005/08/06 20:30:03 espie Exp $ */ |
| 2 | |||
| 3 | /* | 2 | /* |
| 4 | * Copyright (c) 1983, 1993 | 3 | * Copyright (c) 1983, 1993 |
| 5 | * The Regents of the University of California. All rights reserved. | 4 | * The Regents of the University of California. All rights reserved. |
| @@ -12,11 +11,7 @@ | |||
| 12 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
| 13 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the |
| 14 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. |
| 15 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. Neither the name of the University nor the names of its contributors |
| 16 | * must display the following acknowledgement: | ||
| 17 | * This product includes software developed by the University of | ||
| 18 | * California, Berkeley and its contributors. | ||
| 19 | * 4. Neither the name of the University nor the names of its contributors | ||
| 20 | * may be used to endorse or promote products derived from this software | 15 | * may be used to endorse or promote products derived from this software |
| 21 | * without specific prior written permission. | 16 | * without specific prior written permission. |
| 22 | * | 17 | * |
| @@ -33,14 +28,6 @@ | |||
| 33 | * SUCH DAMAGE. | 28 | * SUCH DAMAGE. |
| 34 | */ | 29 | */ |
| 35 | 30 | ||
| 36 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 37 | #if 0 | ||
| 38 | static char sccsid[] = "@(#)inet_netof.c 8.1 (Berkeley) 6/4/93"; | ||
| 39 | #else | ||
| 40 | static char rcsid[] = "$NetBSD: inet_netof.c,v 1.4 1995/02/25 06:20:43 cgd Exp $"; | ||
| 41 | #endif | ||
| 42 | #endif /* LIBC_SCCS and not lint */ | ||
| 43 | |||
| 44 | #include <sys/param.h> | 31 | #include <sys/param.h> |
| 45 | #include <netinet/in.h> | 32 | #include <netinet/in.h> |
| 46 | #include <arpa/inet.h> | 33 | #include <arpa/inet.h> |
| @@ -49,11 +36,10 @@ static char rcsid[] = "$NetBSD: inet_netof.c,v 1.4 1995/02/25 06:20:43 cgd Exp $ | |||
| 49 | * Return the network number from an internet | 36 | * Return the network number from an internet |
| 50 | * address; handles class a/b/c network #'s. | 37 | * address; handles class a/b/c network #'s. |
| 51 | */ | 38 | */ |
| 52 | u_long | 39 | in_addr_t |
| 53 | inet_netof(in) | 40 | inet_netof(struct in_addr in) |
| 54 | struct in_addr in; | ||
| 55 | { | 41 | { |
| 56 | register u_long i = ntohl(in.s_addr); | 42 | in_addr_t i = ntohl(in.s_addr); |
| 57 | 43 | ||
| 58 | if (IN_CLASSA(i)) | 44 | if (IN_CLASSA(i)) |
| 59 | return (((i)&IN_CLASSA_NET) >> IN_CLASSA_NSHIFT); | 45 | return (((i)&IN_CLASSA_NET) >> IN_CLASSA_NSHIFT); |
diff --git a/src/lib/libc/net/inet_network.c b/src/lib/libc/net/inet_network.c index 35105fa75a..ecf554e4f9 100644 --- a/src/lib/libc/net/inet_network.c +++ b/src/lib/libc/net/inet_network.c | |||
| @@ -1,5 +1,4 @@ | |||
| 1 | /* $NetBSD: inet_network.c,v 1.4 1995/02/25 06:20:45 cgd Exp $ */ | 1 | /* $OpenBSD: inet_network.c,v 1.11 2013/11/25 17:29:19 deraadt Exp $ */ |
| 2 | |||
| 3 | /* | 2 | /* |
| 4 | * Copyright (c) 1983, 1993 | 3 | * Copyright (c) 1983, 1993 |
| 5 | * The Regents of the University of California. All rights reserved. | 4 | * The Regents of the University of California. All rights reserved. |
| @@ -12,11 +11,7 @@ | |||
| 12 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
| 13 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the |
| 14 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. |
| 15 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. Neither the name of the University nor the names of its contributors |
| 16 | * must display the following acknowledgement: | ||
| 17 | * This product includes software developed by the University of | ||
| 18 | * California, Berkeley and its contributors. | ||
| 19 | * 4. Neither the name of the University nor the names of its contributors | ||
| 20 | * may be used to endorse or promote products derived from this software | 15 | * may be used to endorse or promote products derived from this software |
| 21 | * without specific prior written permission. | 16 | * without specific prior written permission. |
| 22 | * | 17 | * |
| @@ -33,14 +28,6 @@ | |||
| 33 | * SUCH DAMAGE. | 28 | * SUCH DAMAGE. |
| 34 | */ | 29 | */ |
| 35 | 30 | ||
| 36 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 37 | #if 0 | ||
| 38 | static char sccsid[] = "@(#)inet_network.c 8.1 (Berkeley) 6/4/93"; | ||
| 39 | #else | ||
| 40 | static char rcsid[] = "$NetBSD: inet_network.c,v 1.4 1995/02/25 06:20:45 cgd Exp $"; | ||
| 41 | #endif | ||
| 42 | #endif /* LIBC_SCCS and not lint */ | ||
| 43 | |||
| 44 | #include <sys/types.h> | 31 | #include <sys/types.h> |
| 45 | #include <netinet/in.h> | 32 | #include <netinet/in.h> |
| 46 | #include <arpa/inet.h> | 33 | #include <arpa/inet.h> |
| @@ -51,14 +38,13 @@ static char rcsid[] = "$NetBSD: inet_network.c,v 1.4 1995/02/25 06:20:45 cgd Exp | |||
| 51 | * The library routines call this routine to interpret | 38 | * The library routines call this routine to interpret |
| 52 | * network numbers. | 39 | * network numbers. |
| 53 | */ | 40 | */ |
| 54 | u_long | 41 | in_addr_t |
| 55 | inet_network(cp) | 42 | inet_network(const char *cp) |
| 56 | register const char *cp; | ||
| 57 | { | 43 | { |
| 58 | register u_long val, base, n; | 44 | in_addr_t val, base, n; |
| 59 | register char c; | 45 | u_char c; |
| 60 | u_long parts[4], *pp = parts; | 46 | in_addr_t parts[4], *pp = parts; |
| 61 | register int i; | 47 | int i; |
| 62 | 48 | ||
| 63 | again: | 49 | again: |
| 64 | val = 0; base = 10; | 50 | val = 0; base = 10; |
| @@ -66,7 +52,7 @@ again: | |||
| 66 | base = 8, cp++; | 52 | base = 8, cp++; |
| 67 | if (*cp == 'x' || *cp == 'X') | 53 | if (*cp == 'x' || *cp == 'X') |
| 68 | base = 16, cp++; | 54 | base = 16, cp++; |
| 69 | while (c = *cp) { | 55 | while ((c = *cp)) { |
| 70 | if (isdigit(c)) { | 56 | if (isdigit(c)) { |
| 71 | val = (val * base) + (c - '0'); | 57 | val = (val * base) + (c - '0'); |
| 72 | cp++; | 58 | cp++; |
| @@ -80,7 +66,7 @@ again: | |||
| 80 | break; | 66 | break; |
| 81 | } | 67 | } |
| 82 | if (*cp == '.') { | 68 | if (*cp == '.') { |
| 83 | if (pp >= parts + 4) | 69 | if (pp >= parts + 3) |
| 84 | return (INADDR_NONE); | 70 | return (INADDR_NONE); |
| 85 | *pp++ = val, cp++; | 71 | *pp++ = val, cp++; |
| 86 | goto again; | 72 | goto again; |
| @@ -89,11 +75,10 @@ again: | |||
| 89 | return (INADDR_NONE); | 75 | return (INADDR_NONE); |
| 90 | *pp++ = val; | 76 | *pp++ = val; |
| 91 | n = pp - parts; | 77 | n = pp - parts; |
| 92 | if (n > 4) | 78 | for (val = 0, i = 0; i < 4; i++) { |
| 93 | return (INADDR_NONE); | ||
| 94 | for (val = 0, i = 0; i < n; i++) { | ||
| 95 | val <<= 8; | 79 | val <<= 8; |
| 96 | val |= parts[i] & 0xff; | 80 | if (i < n) |
| 81 | val |= parts[i] & 0xff; | ||
| 97 | } | 82 | } |
| 98 | return (val); | 83 | return (val); |
| 99 | } | 84 | } |
diff --git a/src/lib/libc/net/inet_ntoa.c b/src/lib/libc/net/inet_ntoa.c index 2da0ab00ff..ff5d93ded2 100644 --- a/src/lib/libc/net/inet_ntoa.c +++ b/src/lib/libc/net/inet_ntoa.c | |||
| @@ -1,5 +1,4 @@ | |||
| 1 | /* $NetBSD: inet_ntoa.c,v 1.4 1995/02/25 06:20:46 cgd Exp $ */ | 1 | /* $OpenBSD: inet_ntoa.c,v 1.6 2005/08/06 20:30:03 espie Exp $ */ |
| 2 | |||
| 3 | /* | 2 | /* |
| 4 | * Copyright (c) 1983, 1993 | 3 | * Copyright (c) 1983, 1993 |
| 5 | * The Regents of the University of California. All rights reserved. | 4 | * The Regents of the University of California. All rights reserved. |
| @@ -12,11 +11,7 @@ | |||
| 12 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
| 13 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the |
| 14 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. |
| 15 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. Neither the name of the University nor the names of its contributors |
| 16 | * must display the following acknowledgement: | ||
| 17 | * This product includes software developed by the University of | ||
| 18 | * California, Berkeley and its contributors. | ||
| 19 | * 4. Neither the name of the University nor the names of its contributors | ||
| 20 | * may be used to endorse or promote products derived from this software | 15 | * may be used to endorse or promote products derived from this software |
| 21 | * without specific prior written permission. | 16 | * without specific prior written permission. |
| 22 | * | 17 | * |
| @@ -33,14 +28,6 @@ | |||
| 33 | * SUCH DAMAGE. | 28 | * SUCH DAMAGE. |
| 34 | */ | 29 | */ |
| 35 | 30 | ||
| 36 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 37 | #if 0 | ||
| 38 | static char sccsid[] = "@(#)inet_ntoa.c 8.1 (Berkeley) 6/4/93"; | ||
| 39 | #else | ||
| 40 | static char rcsid[] = "$NetBSD: inet_ntoa.c,v 1.4 1995/02/25 06:20:46 cgd Exp $"; | ||
| 41 | #endif | ||
| 42 | #endif /* LIBC_SCCS and not lint */ | ||
| 43 | |||
| 44 | /* | 31 | /* |
| 45 | * Convert network-format internet address | 32 | * Convert network-format internet address |
| 46 | * to base 256 d.d.d.d representation. | 33 | * to base 256 d.d.d.d representation. |
| @@ -51,15 +38,14 @@ static char rcsid[] = "$NetBSD: inet_ntoa.c,v 1.4 1995/02/25 06:20:46 cgd Exp $" | |||
| 51 | #include <stdio.h> | 38 | #include <stdio.h> |
| 52 | 39 | ||
| 53 | char * | 40 | char * |
| 54 | inet_ntoa(in) | 41 | inet_ntoa(struct in_addr in) |
| 55 | struct in_addr in; | ||
| 56 | { | 42 | { |
| 57 | static char b[18]; | 43 | static char b[18]; |
| 58 | register char *p; | 44 | char *p; |
| 59 | 45 | ||
| 60 | p = (char *)∈ | 46 | p = (char *)∈ |
| 61 | #define UC(b) (((int)b)&0xff) | 47 | #define UC(b) (((int)b)&0xff) |
| 62 | (void)snprintf(b, sizeof(b), | 48 | (void)snprintf(b, sizeof(b), |
| 63 | "%d.%d.%d.%d", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3])); | 49 | "%u.%u.%u.%u", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3])); |
| 64 | return (b); | 50 | return (b); |
| 65 | } | 51 | } |
diff --git a/src/lib/libc/net/inet_ntop.c b/src/lib/libc/net/inet_ntop.c new file mode 100644 index 0000000000..359acd8cda --- /dev/null +++ b/src/lib/libc/net/inet_ntop.c | |||
| @@ -0,0 +1,205 @@ | |||
| 1 | /* $OpenBSD: inet_ntop.c,v 1.9 2014/02/05 14:20:43 millert Exp $ */ | ||
| 2 | |||
| 3 | /* Copyright (c) 1996 by Internet Software Consortium. | ||
| 4 | * | ||
| 5 | * Permission to use, copy, modify, and distribute this software for any | ||
| 6 | * purpose with or without fee is hereby granted, provided that the above | ||
| 7 | * copyright notice and this permission notice appear in all copies. | ||
| 8 | * | ||
| 9 | * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS | ||
| 10 | * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES | ||
| 11 | * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE | ||
| 12 | * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | ||
| 13 | * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR | ||
| 14 | * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS | ||
| 15 | * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | ||
| 16 | * SOFTWARE. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <sys/param.h> | ||
| 20 | #include <sys/types.h> | ||
| 21 | #include <sys/socket.h> | ||
| 22 | #include <netinet/in.h> | ||
| 23 | #include <arpa/inet.h> | ||
| 24 | #include <arpa/nameser.h> | ||
| 25 | #include <string.h> | ||
| 26 | #include <errno.h> | ||
| 27 | #include <stdio.h> | ||
| 28 | |||
| 29 | /* | ||
| 30 | * WARNING: Don't even consider trying to compile this on a system where | ||
| 31 | * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. | ||
| 32 | */ | ||
| 33 | |||
| 34 | static const char *inet_ntop4(const u_char *src, char *dst, size_t size); | ||
| 35 | static const char *inet_ntop6(const u_char *src, char *dst, size_t size); | ||
| 36 | |||
| 37 | /* const char * | ||
| 38 | * inet_ntop(af, src, dst, size) | ||
| 39 | * convert a network format address to presentation format. | ||
| 40 | * return: | ||
| 41 | * pointer to presentation format address (`dst'), or NULL (see errno). | ||
| 42 | * author: | ||
| 43 | * Paul Vixie, 1996. | ||
| 44 | */ | ||
| 45 | const char * | ||
| 46 | inet_ntop(int af, const void *src, char *dst, socklen_t size) | ||
| 47 | { | ||
| 48 | switch (af) { | ||
| 49 | case AF_INET: | ||
| 50 | return (inet_ntop4(src, dst, (size_t)size)); | ||
| 51 | case AF_INET6: | ||
| 52 | return (inet_ntop6(src, dst, (size_t)size)); | ||
| 53 | default: | ||
| 54 | errno = EAFNOSUPPORT; | ||
| 55 | return (NULL); | ||
| 56 | } | ||
| 57 | /* NOTREACHED */ | ||
| 58 | } | ||
| 59 | |||
| 60 | /* const char * | ||
| 61 | * inet_ntop4(src, dst, size) | ||
| 62 | * format an IPv4 address, more or less like inet_ntoa() | ||
| 63 | * return: | ||
| 64 | * `dst' (as a const) | ||
| 65 | * notes: | ||
| 66 | * (1) uses no statics | ||
| 67 | * (2) takes a u_char* not an in_addr as input | ||
| 68 | * author: | ||
| 69 | * Paul Vixie, 1996. | ||
| 70 | */ | ||
| 71 | static const char * | ||
| 72 | inet_ntop4(const u_char *src, char *dst, size_t size) | ||
| 73 | { | ||
| 74 | static const char fmt[] = "%u.%u.%u.%u"; | ||
| 75 | char tmp[sizeof "255.255.255.255"]; | ||
| 76 | int l; | ||
| 77 | |||
| 78 | l = snprintf(tmp, size, fmt, src[0], src[1], src[2], src[3]); | ||
| 79 | if (l <= 0 || l >= size) { | ||
| 80 | errno = ENOSPC; | ||
| 81 | return (NULL); | ||
| 82 | } | ||
| 83 | strlcpy(dst, tmp, size); | ||
| 84 | return (dst); | ||
| 85 | } | ||
| 86 | |||
| 87 | /* const char * | ||
| 88 | * inet_ntop6(src, dst, size) | ||
| 89 | * convert IPv6 binary address into presentation (printable) format | ||
| 90 | * author: | ||
| 91 | * Paul Vixie, 1996. | ||
| 92 | */ | ||
| 93 | static const char * | ||
| 94 | inet_ntop6(const u_char *src, char *dst, size_t size) | ||
| 95 | { | ||
| 96 | /* | ||
| 97 | * Note that int32_t and int16_t need only be "at least" large enough | ||
| 98 | * to contain a value of the specified size. On some systems, like | ||
| 99 | * Crays, there is no such thing as an integer variable with 16 bits. | ||
| 100 | * Keep this in mind if you think this function should have been coded | ||
| 101 | * to use pointer overlays. All the world's not a VAX. | ||
| 102 | */ | ||
| 103 | char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"]; | ||
| 104 | char *tp, *ep; | ||
| 105 | struct { int base, len; } best, cur; | ||
| 106 | u_int words[IN6ADDRSZ / INT16SZ]; | ||
| 107 | int i; | ||
| 108 | int advance; | ||
| 109 | |||
| 110 | /* | ||
| 111 | * Preprocess: | ||
| 112 | * Copy the input (bytewise) array into a wordwise array. | ||
| 113 | * Find the longest run of 0x00's in src[] for :: shorthanding. | ||
| 114 | */ | ||
| 115 | memset(words, '\0', sizeof words); | ||
| 116 | for (i = 0; i < IN6ADDRSZ; i++) | ||
| 117 | words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); | ||
| 118 | best.base = -1; | ||
| 119 | cur.base = -1; | ||
| 120 | for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) { | ||
| 121 | if (words[i] == 0) { | ||
| 122 | if (cur.base == -1) | ||
| 123 | cur.base = i, cur.len = 1; | ||
| 124 | else | ||
| 125 | cur.len++; | ||
| 126 | } else { | ||
| 127 | if (cur.base != -1) { | ||
| 128 | if (best.base == -1 || cur.len > best.len) | ||
| 129 | best = cur; | ||
| 130 | cur.base = -1; | ||
| 131 | } | ||
| 132 | } | ||
| 133 | } | ||
| 134 | if (cur.base != -1) { | ||
| 135 | if (best.base == -1 || cur.len > best.len) | ||
| 136 | best = cur; | ||
| 137 | } | ||
| 138 | if (best.base != -1 && best.len < 2) | ||
| 139 | best.base = -1; | ||
| 140 | |||
| 141 | /* | ||
| 142 | * Format the result. | ||
| 143 | */ | ||
| 144 | tp = tmp; | ||
| 145 | ep = tmp + sizeof(tmp); | ||
| 146 | for (i = 0; i < (IN6ADDRSZ / INT16SZ) && tp < ep; i++) { | ||
| 147 | /* Are we inside the best run of 0x00's? */ | ||
| 148 | if (best.base != -1 && i >= best.base && | ||
| 149 | i < (best.base + best.len)) { | ||
| 150 | if (i == best.base) { | ||
| 151 | if (tp + 1 >= ep) { | ||
| 152 | errno = ENOSPC; | ||
| 153 | return (NULL); | ||
| 154 | } | ||
| 155 | *tp++ = ':'; | ||
| 156 | } | ||
| 157 | continue; | ||
| 158 | } | ||
| 159 | /* Are we following an initial run of 0x00s or any real hex? */ | ||
| 160 | if (i != 0) { | ||
| 161 | if (tp + 1 >= ep) { | ||
| 162 | errno = ENOSPC; | ||
| 163 | return (NULL); | ||
| 164 | } | ||
| 165 | *tp++ = ':'; | ||
| 166 | } | ||
| 167 | /* Is this address an encapsulated IPv4? */ | ||
| 168 | if (i == 6 && best.base == 0 && | ||
| 169 | (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { | ||
| 170 | if (!inet_ntop4(src+12, tp, (size_t)(ep - tp))) | ||
| 171 | return (NULL); | ||
| 172 | tp += strlen(tp); | ||
| 173 | break; | ||
| 174 | } | ||
| 175 | advance = snprintf(tp, ep - tp, "%x", words[i]); | ||
| 176 | if (advance <= 0 || advance >= ep - tp) { | ||
| 177 | errno = ENOSPC; | ||
| 178 | return (NULL); | ||
| 179 | } | ||
| 180 | tp += advance; | ||
| 181 | } | ||
| 182 | /* Was it a trailing run of 0x00's? */ | ||
| 183 | if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) { | ||
| 184 | if (tp + 1 >= ep) { | ||
| 185 | errno = ENOSPC; | ||
| 186 | return (NULL); | ||
| 187 | } | ||
| 188 | *tp++ = ':'; | ||
| 189 | } | ||
| 190 | if (tp + 1 >= ep) { | ||
| 191 | errno = ENOSPC; | ||
| 192 | return (NULL); | ||
| 193 | } | ||
| 194 | *tp++ = '\0'; | ||
| 195 | |||
| 196 | /* | ||
| 197 | * Check for overflow, copy, and we're done. | ||
| 198 | */ | ||
| 199 | if ((size_t)(tp - tmp) > size) { | ||
| 200 | errno = ENOSPC; | ||
| 201 | return (NULL); | ||
| 202 | } | ||
| 203 | strlcpy(dst, tmp, size); | ||
| 204 | return (dst); | ||
| 205 | } | ||
diff --git a/src/lib/libc/net/inet_pton.c b/src/lib/libc/net/inet_pton.c new file mode 100644 index 0000000000..7e521c3286 --- /dev/null +++ b/src/lib/libc/net/inet_pton.c | |||
| @@ -0,0 +1,213 @@ | |||
| 1 | /* $OpenBSD: inet_pton.c,v 1.8 2010/05/06 15:47:14 claudio 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 | #include <sys/param.h> | ||
| 20 | #include <sys/types.h> | ||
| 21 | #include <sys/socket.h> | ||
| 22 | #include <netinet/in.h> | ||
| 23 | #include <arpa/inet.h> | ||
| 24 | #include <arpa/nameser.h> | ||
| 25 | #include <string.h> | ||
| 26 | #include <errno.h> | ||
| 27 | |||
| 28 | /* | ||
| 29 | * WARNING: Don't even consider trying to compile this on a system where | ||
| 30 | * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. | ||
| 31 | */ | ||
| 32 | |||
| 33 | static int inet_pton4(const char *src, u_char *dst); | ||
| 34 | static int inet_pton6(const char *src, u_char *dst); | ||
| 35 | |||
| 36 | /* int | ||
| 37 | * inet_pton(af, src, dst) | ||
| 38 | * convert from presentation format (which usually means ASCII printable) | ||
| 39 | * to network format (which is usually some kind of binary format). | ||
| 40 | * return: | ||
| 41 | * 1 if the address was valid for the specified address family | ||
| 42 | * 0 if the address wasn't valid (`dst' is untouched in this case) | ||
| 43 | * -1 if some other error occurred (`dst' is untouched in this case, too) | ||
| 44 | * author: | ||
| 45 | * Paul Vixie, 1996. | ||
| 46 | */ | ||
| 47 | int | ||
| 48 | inet_pton(int af, const char *src, void *dst) | ||
| 49 | { | ||
| 50 | switch (af) { | ||
| 51 | case AF_INET: | ||
| 52 | return (inet_pton4(src, dst)); | ||
| 53 | case AF_INET6: | ||
| 54 | return (inet_pton6(src, dst)); | ||
| 55 | default: | ||
| 56 | errno = EAFNOSUPPORT; | ||
| 57 | return (-1); | ||
| 58 | } | ||
| 59 | /* NOTREACHED */ | ||
| 60 | } | ||
| 61 | |||
| 62 | /* int | ||
| 63 | * inet_pton4(src, dst) | ||
| 64 | * like inet_aton() but without all the hexadecimal and shorthand. | ||
| 65 | * return: | ||
| 66 | * 1 if `src' is a valid dotted quad, else 0. | ||
| 67 | * notice: | ||
| 68 | * does not touch `dst' unless it's returning 1. | ||
| 69 | * author: | ||
| 70 | * Paul Vixie, 1996. | ||
| 71 | */ | ||
| 72 | static int | ||
| 73 | inet_pton4(const char *src, u_char *dst) | ||
| 74 | { | ||
| 75 | static const char digits[] = "0123456789"; | ||
| 76 | int saw_digit, octets, ch; | ||
| 77 | u_char tmp[INADDRSZ], *tp; | ||
| 78 | |||
| 79 | saw_digit = 0; | ||
| 80 | octets = 0; | ||
| 81 | *(tp = tmp) = 0; | ||
| 82 | while ((ch = *src++) != '\0') { | ||
| 83 | const char *pch; | ||
| 84 | |||
| 85 | if ((pch = strchr(digits, ch)) != NULL) { | ||
| 86 | u_int new = *tp * 10 + (pch - digits); | ||
| 87 | |||
| 88 | if (new > 255) | ||
| 89 | return (0); | ||
| 90 | if (! saw_digit) { | ||
| 91 | if (++octets > 4) | ||
| 92 | return (0); | ||
| 93 | saw_digit = 1; | ||
| 94 | } | ||
| 95 | *tp = new; | ||
| 96 | } else if (ch == '.' && saw_digit) { | ||
| 97 | if (octets == 4) | ||
| 98 | return (0); | ||
| 99 | *++tp = 0; | ||
| 100 | saw_digit = 0; | ||
| 101 | } else | ||
| 102 | return (0); | ||
| 103 | } | ||
| 104 | if (octets < 4) | ||
| 105 | return (0); | ||
| 106 | |||
| 107 | memcpy(dst, tmp, INADDRSZ); | ||
| 108 | return (1); | ||
| 109 | } | ||
| 110 | |||
| 111 | /* int | ||
| 112 | * inet_pton6(src, dst) | ||
| 113 | * convert presentation level address to network order binary form. | ||
| 114 | * return: | ||
| 115 | * 1 if `src' is a valid [RFC1884 2.2] address, else 0. | ||
| 116 | * notice: | ||
| 117 | * does not touch `dst' unless it's returning 1. | ||
| 118 | * credit: | ||
| 119 | * inspired by Mark Andrews. | ||
| 120 | * author: | ||
| 121 | * Paul Vixie, 1996. | ||
| 122 | */ | ||
| 123 | static int | ||
| 124 | inet_pton6(const char *src, u_char *dst) | ||
| 125 | { | ||
| 126 | static const char xdigits_l[] = "0123456789abcdef", | ||
| 127 | xdigits_u[] = "0123456789ABCDEF"; | ||
| 128 | u_char tmp[IN6ADDRSZ], *tp, *endp, *colonp; | ||
| 129 | const char *xdigits, *curtok; | ||
| 130 | int ch, saw_xdigit, count_xdigit; | ||
| 131 | u_int val; | ||
| 132 | |||
| 133 | memset((tp = tmp), '\0', IN6ADDRSZ); | ||
| 134 | endp = tp + IN6ADDRSZ; | ||
| 135 | colonp = NULL; | ||
| 136 | /* Leading :: requires some special handling. */ | ||
| 137 | if (*src == ':') | ||
| 138 | if (*++src != ':') | ||
| 139 | return (0); | ||
| 140 | curtok = src; | ||
| 141 | saw_xdigit = count_xdigit = 0; | ||
| 142 | val = 0; | ||
| 143 | while ((ch = *src++) != '\0') { | ||
| 144 | const char *pch; | ||
| 145 | |||
| 146 | if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) | ||
| 147 | pch = strchr((xdigits = xdigits_u), ch); | ||
| 148 | if (pch != NULL) { | ||
| 149 | if (count_xdigit >= 4) | ||
| 150 | return (0); | ||
| 151 | val <<= 4; | ||
| 152 | val |= (pch - xdigits); | ||
| 153 | if (val > 0xffff) | ||
| 154 | return (0); | ||
| 155 | saw_xdigit = 1; | ||
| 156 | count_xdigit++; | ||
| 157 | continue; | ||
| 158 | } | ||
| 159 | if (ch == ':') { | ||
| 160 | curtok = src; | ||
| 161 | if (!saw_xdigit) { | ||
| 162 | if (colonp) | ||
| 163 | return (0); | ||
| 164 | colonp = tp; | ||
| 165 | continue; | ||
| 166 | } else if (*src == '\0') { | ||
| 167 | return (0); | ||
| 168 | } | ||
| 169 | if (tp + INT16SZ > endp) | ||
| 170 | return (0); | ||
| 171 | *tp++ = (u_char) (val >> 8) & 0xff; | ||
| 172 | *tp++ = (u_char) val & 0xff; | ||
| 173 | saw_xdigit = 0; | ||
| 174 | count_xdigit = 0; | ||
| 175 | val = 0; | ||
| 176 | continue; | ||
| 177 | } | ||
| 178 | if (ch == '.' && ((tp + INADDRSZ) <= endp) && | ||
| 179 | inet_pton4(curtok, tp) > 0) { | ||
| 180 | tp += INADDRSZ; | ||
| 181 | saw_xdigit = 0; | ||
| 182 | count_xdigit = 0; | ||
| 183 | break; /* '\0' was seen by inet_pton4(). */ | ||
| 184 | } | ||
| 185 | return (0); | ||
| 186 | } | ||
| 187 | if (saw_xdigit) { | ||
| 188 | if (tp + INT16SZ > endp) | ||
| 189 | return (0); | ||
| 190 | *tp++ = (u_char) (val >> 8) & 0xff; | ||
| 191 | *tp++ = (u_char) val & 0xff; | ||
| 192 | } | ||
| 193 | if (colonp != NULL) { | ||
| 194 | /* | ||
| 195 | * Since some memmove()'s erroneously fail to handle | ||
| 196 | * overlapping regions, we'll do the shift by hand. | ||
| 197 | */ | ||
| 198 | const int n = tp - colonp; | ||
| 199 | int i; | ||
| 200 | |||
| 201 | if (tp == endp) | ||
| 202 | return (0); | ||
| 203 | for (i = 1; i <= n; i++) { | ||
| 204 | endp[- i] = colonp[n - i]; | ||
| 205 | colonp[n - i] = 0; | ||
| 206 | } | ||
| 207 | tp = endp; | ||
| 208 | } | ||
| 209 | if (tp != endp) | ||
| 210 | return (0); | ||
| 211 | memcpy(dst, tmp, IN6ADDRSZ); | ||
| 212 | return (1); | ||
| 213 | } | ||
diff --git a/src/lib/libc/net/ip6opt.c b/src/lib/libc/net/ip6opt.c new file mode 100644 index 0000000000..7b4fdc4c4e --- /dev/null +++ b/src/lib/libc/net/ip6opt.c | |||
| @@ -0,0 +1,593 @@ | |||
| 1 | /* $OpenBSD: ip6opt.c,v 1.6 2014/02/17 21:05:39 stsp Exp $ */ | ||
| 2 | /* $KAME: ip6opt.c,v 1.18 2005/06/15 07:11:35 keiichi Exp $ */ | ||
| 3 | |||
| 4 | /* | ||
| 5 | * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. | ||
| 6 | * All rights reserved. | ||
| 7 | * | ||
| 8 | * Redistribution and use in source and binary forms, with or without | ||
| 9 | * modification, are permitted provided that the following conditions | ||
| 10 | * are met: | ||
| 11 | * 1. Redistributions of source code must retain the above copyright | ||
| 12 | * notice, this list of conditions and the following disclaimer. | ||
| 13 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in the | ||
| 15 | * documentation and/or other materials provided with the distribution. | ||
| 16 | * 3. Neither the name of the project nor the names of its contributors | ||
| 17 | * may be used to endorse or promote products derived from this software | ||
| 18 | * without specific prior written permission. | ||
| 19 | * | ||
| 20 | * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND | ||
| 21 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 22 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 23 | * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE | ||
| 24 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 25 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 26 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 27 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 28 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 29 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 30 | * SUCH DAMAGE. | ||
| 31 | */ | ||
| 32 | |||
| 33 | #include <sys/param.h> | ||
| 34 | #include <sys/types.h> | ||
| 35 | #include <sys/socket.h> | ||
| 36 | |||
| 37 | #include <netinet/in.h> | ||
| 38 | #include <netinet/ip6.h> | ||
| 39 | |||
| 40 | #include <string.h> | ||
| 41 | #include <stdio.h> | ||
| 42 | |||
| 43 | static int ip6optlen(u_int8_t *opt, u_int8_t *lim); | ||
| 44 | static void inet6_insert_padopt(u_char *p, int len); | ||
| 45 | |||
| 46 | /* | ||
| 47 | * This function returns the number of bytes required to hold an option | ||
| 48 | * when it is stored as ancillary data, including the cmsghdr structure | ||
| 49 | * at the beginning, and any padding at the end (to make its size a | ||
| 50 | * multiple of 8 bytes). The argument is the size of the structure | ||
| 51 | * defining the option, which must include any pad bytes at the | ||
| 52 | * beginning (the value y in the alignment term "xn + y"), the type | ||
| 53 | * byte, the length byte, and the option data. | ||
| 54 | */ | ||
| 55 | int | ||
| 56 | inet6_option_space(int nbytes) | ||
| 57 | { | ||
| 58 | nbytes += 2; /* we need space for nxt-hdr and length fields */ | ||
| 59 | return (CMSG_SPACE((nbytes + 7) & ~7)); | ||
| 60 | } | ||
| 61 | |||
| 62 | /* | ||
| 63 | * This function is called once per ancillary data object that will | ||
| 64 | * contain either Hop-by-Hop or Destination options. It returns 0 on | ||
| 65 | * success or -1 on an error. | ||
| 66 | */ | ||
| 67 | int | ||
| 68 | inet6_option_init(void *bp, struct cmsghdr **cmsgp, int type) | ||
| 69 | { | ||
| 70 | struct cmsghdr *ch = (struct cmsghdr *)bp; | ||
| 71 | |||
| 72 | /* argument validation */ | ||
| 73 | if (type != IPV6_HOPOPTS && type != IPV6_DSTOPTS) | ||
| 74 | return (-1); | ||
| 75 | |||
| 76 | ch->cmsg_level = IPPROTO_IPV6; | ||
| 77 | ch->cmsg_type = type; | ||
| 78 | ch->cmsg_len = CMSG_LEN(0); | ||
| 79 | |||
| 80 | *cmsgp = ch; | ||
| 81 | return (0); | ||
| 82 | } | ||
| 83 | |||
| 84 | /* | ||
| 85 | * This function appends a Hop-by-Hop option or a Destination option | ||
| 86 | * into an ancillary data object that has been initialized by | ||
| 87 | * inet6_option_init(). This function returns 0 if it succeeds or -1 on | ||
| 88 | * an error. | ||
| 89 | * multx is the value x in the alignment term "xn + y" described | ||
| 90 | * earlier. It must have a value of 1, 2, 4, or 8. | ||
| 91 | * plusy is the value y in the alignment term "xn + y" described | ||
| 92 | * earlier. It must have a value between 0 and 7, inclusive. | ||
| 93 | */ | ||
| 94 | int | ||
| 95 | inet6_option_append(struct cmsghdr *cmsg, const u_int8_t *typep, int multx, | ||
| 96 | int plusy) | ||
| 97 | { | ||
| 98 | int padlen, optlen, off; | ||
| 99 | u_char *bp = (u_char *)cmsg + cmsg->cmsg_len; | ||
| 100 | struct ip6_ext *eh = (struct ip6_ext *)CMSG_DATA(cmsg); | ||
| 101 | |||
| 102 | /* argument validation */ | ||
| 103 | if (multx != 1 && multx != 2 && multx != 4 && multx != 8) | ||
| 104 | return (-1); | ||
| 105 | if (plusy < 0 || plusy > 7) | ||
| 106 | return (-1); | ||
| 107 | #if 0 | ||
| 108 | if (typep[0] > 255) | ||
| 109 | return (-1); | ||
| 110 | #endif | ||
| 111 | |||
| 112 | /* | ||
| 113 | * If this is the first option, allocate space for the | ||
| 114 | * first 2 bytes(for next header and length fields) of | ||
| 115 | * the option header. | ||
| 116 | */ | ||
| 117 | if (bp == (u_char *)eh) { | ||
| 118 | bp += 2; | ||
| 119 | cmsg->cmsg_len += 2; | ||
| 120 | } | ||
| 121 | |||
| 122 | /* calculate pad length before the option. */ | ||
| 123 | off = bp - (u_char *)eh; | ||
| 124 | padlen = (((off % multx) + (multx - 1)) & ~(multx - 1)) - | ||
| 125 | (off % multx); | ||
| 126 | padlen += plusy; | ||
| 127 | padlen %= multx; /* keep the pad as short as possible */ | ||
| 128 | /* insert padding */ | ||
| 129 | inet6_insert_padopt(bp, padlen); | ||
| 130 | cmsg->cmsg_len += padlen; | ||
| 131 | bp += padlen; | ||
| 132 | |||
| 133 | /* copy the option */ | ||
| 134 | if (typep[0] == IP6OPT_PAD1) | ||
| 135 | optlen = 1; | ||
| 136 | else | ||
| 137 | optlen = typep[1] + 2; | ||
| 138 | memcpy(bp, typep, optlen); | ||
| 139 | bp += optlen; | ||
| 140 | cmsg->cmsg_len += optlen; | ||
| 141 | |||
| 142 | /* calculate pad length after the option and insert the padding */ | ||
| 143 | off = bp - (u_char *)eh; | ||
| 144 | padlen = ((off + 7) & ~7) - off; | ||
| 145 | inet6_insert_padopt(bp, padlen); | ||
| 146 | bp += padlen; | ||
| 147 | cmsg->cmsg_len += padlen; | ||
| 148 | |||
| 149 | /* update the length field of the ip6 option header */ | ||
| 150 | eh->ip6e_len = ((bp - (u_char *)eh) >> 3) - 1; | ||
| 151 | |||
| 152 | return (0); | ||
| 153 | } | ||
| 154 | |||
| 155 | /* | ||
| 156 | * This function appends a Hop-by-Hop option or a Destination option | ||
| 157 | * into an ancillary data object that has been initialized by | ||
| 158 | * inet6_option_init(). This function returns a pointer to the 8-bit | ||
| 159 | * option type field that starts the option on success, or NULL on an | ||
| 160 | * error. | ||
| 161 | * The difference between this function and inet6_option_append() is | ||
| 162 | * that the latter copies the contents of a previously built option into | ||
| 163 | * the ancillary data object while the current function returns a | ||
| 164 | * pointer to the space in the data object where the option's TLV must | ||
| 165 | * then be built by the caller. | ||
| 166 | * | ||
| 167 | */ | ||
| 168 | u_int8_t * | ||
| 169 | inet6_option_alloc(struct cmsghdr *cmsg, int datalen, int multx, int plusy) | ||
| 170 | { | ||
| 171 | int padlen, off; | ||
| 172 | u_int8_t *bp = (u_char *)cmsg + cmsg->cmsg_len; | ||
| 173 | u_int8_t *retval; | ||
| 174 | struct ip6_ext *eh = (struct ip6_ext *)CMSG_DATA(cmsg); | ||
| 175 | |||
| 176 | /* argument validation */ | ||
| 177 | if (multx != 1 && multx != 2 && multx != 4 && multx != 8) | ||
| 178 | return (NULL); | ||
| 179 | if (plusy < 0 || plusy > 7) | ||
| 180 | return (NULL); | ||
| 181 | |||
| 182 | /* | ||
| 183 | * If this is the first option, allocate space for the | ||
| 184 | * first 2 bytes(for next header and length fields) of | ||
| 185 | * the option header. | ||
| 186 | */ | ||
| 187 | if (bp == (u_char *)eh) { | ||
| 188 | bp += 2; | ||
| 189 | cmsg->cmsg_len += 2; | ||
| 190 | } | ||
| 191 | |||
| 192 | /* calculate pad length before the option. */ | ||
| 193 | off = bp - (u_char *)eh; | ||
| 194 | padlen = (((off % multx) + (multx - 1)) & ~(multx - 1)) - | ||
| 195 | (off % multx); | ||
| 196 | padlen += plusy; | ||
| 197 | padlen %= multx; /* keep the pad as short as possible */ | ||
| 198 | /* insert padding */ | ||
| 199 | inet6_insert_padopt(bp, padlen); | ||
| 200 | cmsg->cmsg_len += padlen; | ||
| 201 | bp += padlen; | ||
| 202 | |||
| 203 | /* keep space to store specified length of data */ | ||
| 204 | retval = bp; | ||
| 205 | bp += datalen; | ||
| 206 | cmsg->cmsg_len += datalen; | ||
| 207 | |||
| 208 | /* calculate pad length after the option and insert the padding */ | ||
| 209 | off = bp - (u_char *)eh; | ||
| 210 | padlen = ((off + 7) & ~7) - off; | ||
| 211 | inet6_insert_padopt(bp, padlen); | ||
| 212 | bp += padlen; | ||
| 213 | cmsg->cmsg_len += padlen; | ||
| 214 | |||
| 215 | /* update the length field of the ip6 option header */ | ||
| 216 | eh->ip6e_len = ((bp - (u_char *)eh) >> 3) - 1; | ||
| 217 | |||
| 218 | return (retval); | ||
| 219 | } | ||
| 220 | |||
| 221 | /* | ||
| 222 | * This function processes the next Hop-by-Hop option or Destination | ||
| 223 | * option in an ancillary data object. If another option remains to be | ||
| 224 | * processed, the return value of the function is 0 and *tptrp points to | ||
| 225 | * the 8-bit option type field (which is followed by the 8-bit option | ||
| 226 | * data length, followed by the option data). If no more options remain | ||
| 227 | * to be processed, the return value is -1 and *tptrp is NULL. If an | ||
| 228 | * error occurs, the return value is -1 and *tptrp is not NULL. | ||
| 229 | * (RFC 2292, 6.3.5) | ||
| 230 | */ | ||
| 231 | int | ||
| 232 | inet6_option_next(const struct cmsghdr *cmsg, u_int8_t **tptrp) | ||
| 233 | { | ||
| 234 | struct ip6_ext *ip6e; | ||
| 235 | int hdrlen, optlen; | ||
| 236 | u_int8_t *lim; | ||
| 237 | |||
| 238 | if (cmsg->cmsg_level != IPPROTO_IPV6 || | ||
| 239 | (cmsg->cmsg_type != IPV6_HOPOPTS && | ||
| 240 | cmsg->cmsg_type != IPV6_DSTOPTS)) | ||
| 241 | return (-1); | ||
| 242 | |||
| 243 | /* message length validation */ | ||
| 244 | if (cmsg->cmsg_len < CMSG_SPACE(sizeof(struct ip6_ext))) | ||
| 245 | return (-1); | ||
| 246 | ip6e = (struct ip6_ext *)CMSG_DATA(cmsg); | ||
| 247 | hdrlen = (ip6e->ip6e_len + 1) << 3; | ||
| 248 | if (cmsg->cmsg_len < CMSG_SPACE(hdrlen)) | ||
| 249 | return (-1); | ||
| 250 | |||
| 251 | /* | ||
| 252 | * If the caller does not specify the starting point, | ||
| 253 | * simply return the 1st option. | ||
| 254 | * Otherwise, search the option list for the next option. | ||
| 255 | */ | ||
| 256 | lim = (u_int8_t *)ip6e + hdrlen; | ||
| 257 | if (*tptrp == NULL) | ||
| 258 | *tptrp = (u_int8_t *)(ip6e + 1); | ||
| 259 | else { | ||
| 260 | if ((optlen = ip6optlen(*tptrp, lim)) == 0) | ||
| 261 | return (-1); | ||
| 262 | |||
| 263 | *tptrp = *tptrp + optlen; | ||
| 264 | } | ||
| 265 | if (*tptrp >= lim) { /* there is no option */ | ||
| 266 | *tptrp = NULL; | ||
| 267 | return (-1); | ||
| 268 | } | ||
| 269 | /* | ||
| 270 | * Finally, checks if the next option is safely stored in the | ||
| 271 | * cmsg data. | ||
| 272 | */ | ||
| 273 | if (ip6optlen(*tptrp, lim) == 0) | ||
| 274 | return (-1); | ||
| 275 | else | ||
| 276 | return (0); | ||
| 277 | } | ||
| 278 | |||
| 279 | /* | ||
| 280 | * This function is similar to the inet6_option_next() function, | ||
| 281 | * except this function lets the caller specify the option type to be | ||
| 282 | * searched for, instead of always returning the next option in the | ||
| 283 | * ancillary data object. | ||
| 284 | * Note: RFC 2292 says the type of tptrp is u_int8_t *, but we think | ||
| 285 | * it's a typo. The variable should be type of u_int8_t **. | ||
| 286 | */ | ||
| 287 | int | ||
| 288 | inet6_option_find(const struct cmsghdr *cmsg, u_int8_t **tptrp, int type) | ||
| 289 | { | ||
| 290 | struct ip6_ext *ip6e; | ||
| 291 | int hdrlen, optlen; | ||
| 292 | u_int8_t *optp, *lim; | ||
| 293 | |||
| 294 | if (cmsg->cmsg_level != IPPROTO_IPV6 || | ||
| 295 | (cmsg->cmsg_type != IPV6_HOPOPTS && | ||
| 296 | cmsg->cmsg_type != IPV6_DSTOPTS)) | ||
| 297 | return (-1); | ||
| 298 | |||
| 299 | /* message length validation */ | ||
| 300 | if (cmsg->cmsg_len < CMSG_SPACE(sizeof(struct ip6_ext))) | ||
| 301 | return (-1); | ||
| 302 | ip6e = (struct ip6_ext *)CMSG_DATA(cmsg); | ||
| 303 | hdrlen = (ip6e->ip6e_len + 1) << 3; | ||
| 304 | if (cmsg->cmsg_len < CMSG_SPACE(hdrlen)) | ||
| 305 | return (-1); | ||
| 306 | |||
| 307 | /* | ||
| 308 | * If the caller does not specify the starting point, | ||
| 309 | * search from the beginning of the option list. | ||
| 310 | * Otherwise, search from *the next option* of the specified point. | ||
| 311 | */ | ||
| 312 | lim = (u_int8_t *)ip6e + hdrlen; | ||
| 313 | if (*tptrp == NULL) | ||
| 314 | *tptrp = (u_int8_t *)(ip6e + 1); | ||
| 315 | else { | ||
| 316 | if ((optlen = ip6optlen(*tptrp, lim)) == 0) | ||
| 317 | return (-1); | ||
| 318 | |||
| 319 | *tptrp = *tptrp + optlen; | ||
| 320 | } | ||
| 321 | for (optp = *tptrp; optp < lim; optp += optlen) { | ||
| 322 | if (*optp == type) { | ||
| 323 | *tptrp = optp; | ||
| 324 | return (0); | ||
| 325 | } | ||
| 326 | if ((optlen = ip6optlen(optp, lim)) == 0) | ||
| 327 | return (-1); | ||
| 328 | } | ||
| 329 | |||
| 330 | /* search failed */ | ||
| 331 | *tptrp = NULL; | ||
| 332 | return (-1); | ||
| 333 | } | ||
| 334 | |||
| 335 | /* | ||
| 336 | * Calculate the length of a given IPv6 option. Also checks | ||
| 337 | * if the option is safely stored in user's buffer according to the | ||
| 338 | * calculated length and the limitation of the buffer. | ||
| 339 | */ | ||
| 340 | static int | ||
| 341 | ip6optlen(u_int8_t *opt, u_int8_t *lim) | ||
| 342 | { | ||
| 343 | int optlen; | ||
| 344 | |||
| 345 | if (*opt == IP6OPT_PAD1) | ||
| 346 | optlen = 1; | ||
| 347 | else { | ||
| 348 | /* is there enough space to store type and len? */ | ||
| 349 | if (opt + 2 > lim) | ||
| 350 | return (0); | ||
| 351 | optlen = *(opt + 1) + 2; | ||
| 352 | } | ||
| 353 | if (opt + optlen <= lim) | ||
| 354 | return (optlen); | ||
| 355 | |||
| 356 | return (0); | ||
| 357 | } | ||
| 358 | |||
| 359 | static void | ||
| 360 | inet6_insert_padopt(u_char *p, int len) | ||
| 361 | { | ||
| 362 | switch(len) { | ||
| 363 | case 0: | ||
| 364 | return; | ||
| 365 | case 1: | ||
| 366 | p[0] = IP6OPT_PAD1; | ||
| 367 | return; | ||
| 368 | default: | ||
| 369 | p[0] = IP6OPT_PADN; | ||
| 370 | p[1] = len - 2; | ||
| 371 | memset(&p[2], 0, len - 2); | ||
| 372 | return; | ||
| 373 | } | ||
| 374 | } | ||
| 375 | |||
| 376 | /* | ||
| 377 | * The following functions are defined in RFC3542, which is a successor | ||
| 378 | * of RFC2292. | ||
| 379 | */ | ||
| 380 | |||
| 381 | int | ||
| 382 | inet6_opt_init(void *extbuf, socklen_t extlen) | ||
| 383 | { | ||
| 384 | struct ip6_ext *ext = (struct ip6_ext *)extbuf; | ||
| 385 | |||
| 386 | if (ext) { | ||
| 387 | if (extlen <= 0 || (extlen % 8)) | ||
| 388 | return (-1); | ||
| 389 | ext->ip6e_len = (extlen >> 3) - 1; | ||
| 390 | } | ||
| 391 | |||
| 392 | return (2); /* sizeof the next and the length fields */ | ||
| 393 | } | ||
| 394 | |||
| 395 | int | ||
| 396 | inet6_opt_append(void *extbuf, socklen_t extlen, int offset, u_int8_t type, | ||
| 397 | socklen_t len, u_int8_t align, void **databufp) | ||
| 398 | { | ||
| 399 | int currentlen = offset, padlen = 0; | ||
| 400 | |||
| 401 | /* | ||
| 402 | * The option type must have a value from 2 to 255, inclusive. | ||
| 403 | * (0 and 1 are reserved for the Pad1 and PadN options, respectively.) | ||
| 404 | */ | ||
| 405 | #if 0 /* always false */ | ||
| 406 | if (type < 2 || type > 255) | ||
| 407 | #else | ||
| 408 | if (type < 2) | ||
| 409 | #endif | ||
| 410 | return (-1); | ||
| 411 | |||
| 412 | /* | ||
| 413 | * The option data length must have a value between 0 and 255, | ||
| 414 | * inclusive, and is the length of the option data that follows. | ||
| 415 | */ | ||
| 416 | if (len < 0 || len > 255) | ||
| 417 | return (-1); | ||
| 418 | |||
| 419 | /* | ||
| 420 | * The align parameter must have a value of 1, 2, 4, or 8. | ||
| 421 | * The align value can not exceed the value of len. | ||
| 422 | */ | ||
| 423 | if (align != 1 && align != 2 && align != 4 && align != 8) | ||
| 424 | return (-1); | ||
| 425 | if (align > len) | ||
| 426 | return (-1); | ||
| 427 | |||
| 428 | /* Calculate the padding length. */ | ||
| 429 | currentlen += 2 + len; /* 2 means "type + len" */ | ||
| 430 | if (currentlen % align) | ||
| 431 | padlen = align - (currentlen % align); | ||
| 432 | |||
| 433 | /* The option must fit in the extension header buffer. */ | ||
| 434 | currentlen += padlen; | ||
| 435 | if (extlen && /* XXX: right? */ | ||
| 436 | currentlen > extlen) | ||
| 437 | return (-1); | ||
| 438 | |||
| 439 | if (extbuf) { | ||
| 440 | u_int8_t *optp = (u_int8_t *)extbuf + offset; | ||
| 441 | |||
| 442 | if (padlen == 1) { | ||
| 443 | /* insert a Pad1 option */ | ||
| 444 | *optp = IP6OPT_PAD1; | ||
| 445 | optp++; | ||
| 446 | } else if (padlen > 0) { | ||
| 447 | /* insert a PadN option for alignment */ | ||
| 448 | *optp++ = IP6OPT_PADN; | ||
| 449 | *optp++ = padlen - 2; | ||
| 450 | memset(optp, 0, padlen - 2); | ||
| 451 | optp += (padlen - 2); | ||
| 452 | } | ||
| 453 | |||
| 454 | *optp++ = type; | ||
| 455 | *optp++ = len; | ||
| 456 | |||
| 457 | *databufp = optp; | ||
| 458 | } | ||
| 459 | |||
| 460 | return (currentlen); | ||
| 461 | } | ||
| 462 | |||
| 463 | int | ||
| 464 | inet6_opt_finish(void *extbuf, socklen_t extlen, int offset) | ||
| 465 | { | ||
| 466 | int updatelen = offset > 0 ? (1 + ((offset - 1) | 7)) : 0;; | ||
| 467 | |||
| 468 | if (extbuf) { | ||
| 469 | u_int8_t *padp; | ||
| 470 | int padlen = updatelen - offset; | ||
| 471 | |||
| 472 | if (updatelen > extlen) | ||
| 473 | return (-1); | ||
| 474 | |||
| 475 | padp = (u_int8_t *)extbuf + offset; | ||
| 476 | if (padlen == 1) | ||
| 477 | *padp = IP6OPT_PAD1; | ||
| 478 | else if (padlen > 0) { | ||
| 479 | *padp++ = IP6OPT_PADN; | ||
| 480 | *padp++ = (padlen - 2); | ||
| 481 | memset(padp, 0, padlen - 2); | ||
| 482 | } | ||
| 483 | } | ||
| 484 | |||
| 485 | return (updatelen); | ||
| 486 | } | ||
| 487 | |||
| 488 | int | ||
| 489 | inet6_opt_set_val(void *databuf, int offset, void *val, socklen_t vallen) | ||
| 490 | { | ||
| 491 | |||
| 492 | memcpy((u_int8_t *)databuf + offset, val, vallen); | ||
| 493 | return (offset + vallen); | ||
| 494 | } | ||
| 495 | |||
| 496 | int | ||
| 497 | inet6_opt_next(void *extbuf, socklen_t extlen, int offset, u_int8_t *typep, | ||
| 498 | socklen_t *lenp, void **databufp) | ||
| 499 | { | ||
| 500 | u_int8_t *optp, *lim; | ||
| 501 | int optlen; | ||
| 502 | |||
| 503 | /* Validate extlen. XXX: is the variable really necessary?? */ | ||
| 504 | if (extlen == 0 || (extlen % 8)) | ||
| 505 | return (-1); | ||
| 506 | lim = (u_int8_t *)extbuf + extlen; | ||
| 507 | |||
| 508 | /* | ||
| 509 | * If this is the first time this function called for this options | ||
| 510 | * header, simply return the 1st option. | ||
| 511 | * Otherwise, search the option list for the next option. | ||
| 512 | */ | ||
| 513 | if (offset == 0) | ||
| 514 | optp = (u_int8_t *)((struct ip6_hbh *)extbuf + 1); | ||
| 515 | else | ||
| 516 | optp = (u_int8_t *)extbuf + offset; | ||
| 517 | |||
| 518 | /* Find the next option skipping any padding options. */ | ||
| 519 | while (optp < lim) { | ||
| 520 | switch(*optp) { | ||
| 521 | case IP6OPT_PAD1: | ||
| 522 | optp++; | ||
| 523 | break; | ||
| 524 | case IP6OPT_PADN: | ||
| 525 | if ((optlen = ip6optlen(optp, lim)) == 0) | ||
| 526 | goto optend; | ||
| 527 | optp += optlen; | ||
| 528 | break; | ||
| 529 | default: /* found */ | ||
| 530 | if ((optlen = ip6optlen(optp, lim)) == 0) | ||
| 531 | goto optend; | ||
| 532 | *typep = *optp; | ||
| 533 | *lenp = optlen - 2; | ||
| 534 | *databufp = optp + 2; | ||
| 535 | return (optp + optlen - (u_int8_t *)extbuf); | ||
| 536 | } | ||
| 537 | } | ||
| 538 | |||
| 539 | optend: | ||
| 540 | *databufp = NULL; /* for safety */ | ||
| 541 | return (-1); | ||
| 542 | } | ||
| 543 | |||
| 544 | int | ||
| 545 | inet6_opt_find(void *extbuf, socklen_t extlen, int offset, u_int8_t type, | ||
| 546 | socklen_t *lenp, void **databufp) | ||
| 547 | { | ||
| 548 | u_int8_t *optp, *lim; | ||
| 549 | int optlen; | ||
| 550 | |||
| 551 | /* Validate extlen. XXX: is the variable really necessary?? */ | ||
| 552 | if (extlen == 0 || (extlen % 8)) | ||
| 553 | return (-1); | ||
| 554 | lim = (u_int8_t *)extbuf + extlen; | ||
| 555 | |||
| 556 | /* | ||
| 557 | * If this is the first time this function called for this options | ||
| 558 | * header, simply return the 1st option. | ||
| 559 | * Otherwise, search the option list for the next option. | ||
| 560 | */ | ||
| 561 | if (offset == 0) | ||
| 562 | optp = (u_int8_t *)((struct ip6_hbh *)extbuf + 1); | ||
| 563 | else | ||
| 564 | optp = (u_int8_t *)extbuf + offset; | ||
| 565 | |||
| 566 | /* Find the specified option */ | ||
| 567 | while (optp < lim) { | ||
| 568 | if ((optlen = ip6optlen(optp, lim)) == 0) | ||
| 569 | goto optend; | ||
| 570 | |||
| 571 | if (*optp == type) { /* found */ | ||
| 572 | *lenp = optlen - 2; | ||
| 573 | *databufp = optp + 2; | ||
| 574 | return (optp + optlen - (u_int8_t *)extbuf); | ||
| 575 | } | ||
| 576 | |||
| 577 | optp += optlen; | ||
| 578 | } | ||
| 579 | |||
| 580 | optend: | ||
| 581 | *databufp = NULL; /* for safety */ | ||
| 582 | return (-1); | ||
| 583 | } | ||
| 584 | |||
| 585 | int | ||
| 586 | inet6_opt_get_val(void *databuf, int offset, void *val, socklen_t vallen) | ||
| 587 | { | ||
| 588 | |||
| 589 | /* we can't assume alignment here */ | ||
| 590 | memcpy(val, (u_int8_t *)databuf + offset, vallen); | ||
| 591 | |||
| 592 | return (offset + vallen); | ||
| 593 | } | ||
diff --git a/src/lib/libc/net/iso_addr.3 b/src/lib/libc/net/iso_addr.3 deleted file mode 100644 index 95c136e5fc..0000000000 --- a/src/lib/libc/net/iso_addr.3 +++ /dev/null | |||
| @@ -1,112 +0,0 @@ | |||
| 1 | .\" $NetBSD: iso_addr.3,v 1.2 1995/02/25 06:20:46 cgd 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 | .\" @(#)iso_addr.3 8.1 (Berkeley) 6/4/93 | ||
| 35 | .\" | ||
| 36 | .Dd June 4, 1993 | ||
| 37 | .Dt ISO_ADDR 3 | ||
| 38 | .Os | ||
| 39 | .Sh NAME | ||
| 40 | .Nm iso_addr , | ||
| 41 | .Nm iso_ntoa | ||
| 42 | .Nd "elementary network address conversion routines for Open System Interconnection | ||
| 43 | .Sh SYNOPSIS | ||
| 44 | .Fd #include <sys/types.h> | ||
| 45 | .Fd #include <netiso/iso.h> | ||
| 46 | .Ft struct iso_addr * | ||
| 47 | .Fn iso_addr "char *cp" | ||
| 48 | .Ft char * | ||
| 49 | .Fn iso_ntoa "struct iso_addr *isoa" | ||
| 50 | .Sh DESCRIPTION | ||
| 51 | The routine | ||
| 52 | .Fn iso_addr | ||
| 53 | interprets character strings representing | ||
| 54 | .Tn OSI | ||
| 55 | addresses, returning binary information suitable | ||
| 56 | for use in system calls. | ||
| 57 | The routine | ||
| 58 | .Fn iso_ntoa | ||
| 59 | takes | ||
| 60 | .Tn OSI | ||
| 61 | addresses and returns | ||
| 62 | .Tn ASCII | ||
| 63 | strings representing NSAPs (network service | ||
| 64 | access points) in a | ||
| 65 | notation inverse to that accepted by | ||
| 66 | .Fn iso_addr . | ||
| 67 | .Pp | ||
| 68 | Unfortunately, no universal standard exists for representing | ||
| 69 | .Tn OSI | ||
| 70 | network addresses. | ||
| 71 | .Pp | ||
| 72 | The format employed by | ||
| 73 | .Fn iso_addr | ||
| 74 | is a sequence of hexadecimal | ||
| 75 | .Dq digits | ||
| 76 | (optionally separated by periods), | ||
| 77 | of the form: | ||
| 78 | .Bd -filled -offset indent | ||
| 79 | <hex digits>.<hex digits>.<hex digits> | ||
| 80 | .Ed | ||
| 81 | .Pp | ||
| 82 | Each pair of hexadecimal digits represents a byte | ||
| 83 | with the leading digit indicating the higher-ordered bits. | ||
| 84 | A period following an even number of bytes has no | ||
| 85 | effect (but may be used to increase legibility). | ||
| 86 | A period following an odd number of bytes has the | ||
| 87 | effect of causing the byte of address being translated | ||
| 88 | to have its higher order bits filled with zeros. | ||
| 89 | .Sh RETURN VALUES | ||
| 90 | .Fn iso_ntoa | ||
| 91 | always returns a null terminated string. | ||
| 92 | .Fn iso_addr | ||
| 93 | always returns a pointer to a struct iso_addr. | ||
| 94 | (See | ||
| 95 | .Sx BUGS . ) | ||
| 96 | .Sh SEE ALSO | ||
| 97 | .Xr iso 4 | ||
| 98 | .Sh HISTORY | ||
| 99 | The | ||
| 100 | .Fn iso_addr | ||
| 101 | and | ||
| 102 | .Fn iso_ntoa | ||
| 103 | functions appeared in | ||
| 104 | .Bx 4.3 Reno . | ||
| 105 | .Sh BUGS | ||
| 106 | The returned values | ||
| 107 | reside in a static memory area. | ||
| 108 | .Pp | ||
| 109 | The function | ||
| 110 | .Fn iso_addr | ||
| 111 | should diagnose improperly formed input, and there should be an unambiguous | ||
| 112 | way to recognize this. | ||
diff --git a/src/lib/libc/net/iso_addr.c b/src/lib/libc/net/iso_addr.c deleted file mode 100644 index c26ec1a64a..0000000000 --- a/src/lib/libc/net/iso_addr.c +++ /dev/null | |||
| @@ -1,125 +0,0 @@ | |||
| 1 | /* $NetBSD: iso_addr.c,v 1.4 1995/02/25 06:20:47 cgd Exp $ */ | ||
| 2 | |||
| 3 | /* | ||
| 4 | * Copyright (c) 1989, 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 | ||
| 38 | static char sccsid[] = "@(#)iso_addr.c 8.1 (Berkeley) 6/4/93"; | ||
| 39 | #else | ||
| 40 | static char rcsid[] = "$NetBSD: iso_addr.c,v 1.4 1995/02/25 06:20:47 cgd Exp $"; | ||
| 41 | #endif | ||
| 42 | #endif /* LIBC_SCCS and not lint */ | ||
| 43 | |||
| 44 | #include <sys/types.h> | ||
| 45 | #include <netiso/iso.h> | ||
| 46 | #include <string.h> | ||
| 47 | |||
| 48 | /* States*/ | ||
| 49 | #define VIRGIN 0 | ||
| 50 | #define GOTONE 1 | ||
| 51 | #define GOTTWO 2 | ||
| 52 | /* Inputs */ | ||
| 53 | #define DIGIT (4*0) | ||
| 54 | #define END (4*1) | ||
| 55 | #define DELIM (4*2) | ||
| 56 | |||
| 57 | struct iso_addr * | ||
| 58 | iso_addr(addr) | ||
| 59 | register const char *addr; | ||
| 60 | { | ||
| 61 | static struct iso_addr out_addr; | ||
| 62 | register char *cp = out_addr.isoa_genaddr; | ||
| 63 | char *cplim = cp + sizeof(out_addr.isoa_genaddr); | ||
| 64 | register int byte = 0, state = VIRGIN, new; | ||
| 65 | |||
| 66 | bzero((char *)&out_addr, sizeof(out_addr)); | ||
| 67 | do { | ||
| 68 | if ((*addr >= '0') && (*addr <= '9')) { | ||
| 69 | new = *addr - '0'; | ||
| 70 | } else if ((*addr >= 'a') && (*addr <= 'f')) { | ||
| 71 | new = *addr - 'a' + 10; | ||
| 72 | } else if ((*addr >= 'A') && (*addr <= 'F')) { | ||
| 73 | new = *addr - 'A' + 10; | ||
| 74 | } else if (*addr == 0) | ||
| 75 | state |= END; | ||
| 76 | else | ||
| 77 | state |= DELIM; | ||
| 78 | addr++; | ||
| 79 | switch (state /* | INPUT */) { | ||
| 80 | case GOTTWO | DIGIT: | ||
| 81 | *cp++ = byte; /*FALLTHROUGH*/ | ||
| 82 | case VIRGIN | DIGIT: | ||
| 83 | state = GOTONE; byte = new; continue; | ||
| 84 | case GOTONE | DIGIT: | ||
| 85 | state = GOTTWO; byte = new + (byte << 4); continue; | ||
| 86 | default: /* | DELIM */ | ||
| 87 | state = VIRGIN; *cp++ = byte; byte = 0; continue; | ||
| 88 | case GOTONE | END: | ||
| 89 | case GOTTWO | END: | ||
| 90 | *cp++ = byte; /* FALLTHROUGH */ | ||
| 91 | case VIRGIN | END: | ||
| 92 | break; | ||
| 93 | } | ||
| 94 | break; | ||
| 95 | } while (cp < cplim); | ||
| 96 | out_addr.isoa_len = cp - out_addr.isoa_genaddr; | ||
| 97 | return (&out_addr); | ||
| 98 | } | ||
| 99 | static char hexlist[] = "0123456789abcdef"; | ||
| 100 | |||
| 101 | char * | ||
| 102 | iso_ntoa(isoa) | ||
| 103 | const struct iso_addr *isoa; | ||
| 104 | { | ||
| 105 | static char obuf[64]; | ||
| 106 | register char *out = obuf; | ||
| 107 | register int i; | ||
| 108 | register u_char *in = (u_char *)isoa->isoa_genaddr; | ||
| 109 | u_char *inlim = in + isoa->isoa_len; | ||
| 110 | |||
| 111 | out[1] = 0; | ||
| 112 | while (in < inlim) { | ||
| 113 | i = *in++; | ||
| 114 | *out++ = '.'; | ||
| 115 | if (i > 0xf) { | ||
| 116 | out[1] = hexlist[i & 0xf]; | ||
| 117 | i >>= 4; | ||
| 118 | out[0] = hexlist[i]; | ||
| 119 | out += 2; | ||
| 120 | } else | ||
| 121 | *out++ = hexlist[i]; | ||
| 122 | } | ||
| 123 | *out = 0; | ||
| 124 | return(obuf + 1); | ||
| 125 | } | ||
diff --git a/src/lib/libc/net/linkaddr.3 b/src/lib/libc/net/link_addr.3 index 1a2af9b30d..f234fe84cc 100644 --- a/src/lib/libc/net/linkaddr.3 +++ b/src/lib/libc/net/link_addr.3 | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | .\" $NetBSD: linkaddr.3,v 1.2 1995/02/25 06:20:48 cgd Exp $ | 1 | .\" $OpenBSD: link_addr.3,v 1.13 2013/06/05 03:39:23 tedu Exp $ |
| 2 | .\" | 2 | .\" |
| 3 | .\" Copyright (c) 1993 | 3 | .\" Copyright (c) 1993 |
| 4 | .\" The Regents of the University of California. All rights reserved. | 4 | .\" The Regents of the University of California. All rights reserved. |
| @@ -14,11 +14,7 @@ | |||
| 14 | .\" 2. Redistributions in binary form must reproduce the above copyright | 14 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 15 | .\" notice, this list of conditions and the following disclaimer in the | 15 | .\" notice, this list of conditions and the following disclaimer in the |
| 16 | .\" documentation and/or other materials provided with the distribution. | 16 | .\" documentation and/or other materials provided with the distribution. |
| 17 | .\" 3. All advertising materials mentioning features or use of this software | 17 | .\" 3. Neither the name of the University nor the names of its contributors |
| 18 | .\" must display the following acknowledgement: | ||
| 19 | .\" This product includes software developed by the University of | ||
| 20 | .\" California, Berkeley and its contributors. | ||
| 21 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 22 | .\" may be used to endorse or promote products derived from this software | 18 | .\" may be used to endorse or promote products derived from this software |
| 23 | .\" without specific prior written permission. | 19 | .\" without specific prior written permission. |
| 24 | .\" | 20 | .\" |
| @@ -34,30 +30,27 @@ | |||
| 34 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 30 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 35 | .\" SUCH DAMAGE. | 31 | .\" SUCH DAMAGE. |
| 36 | .\" | 32 | .\" |
| 37 | .\" @(#)linkaddr.3 8.1 (Berkeley) 7/28/93 | 33 | .Dd $Mdocdate: June 5 2013 $ |
| 38 | .\" | ||
| 39 | .Dd July 28, 1993 | ||
| 40 | .Dt LINK_ADDR 3 | 34 | .Dt LINK_ADDR 3 |
| 41 | .Os BSD 4.4 | 35 | .Os |
| 42 | .Sh NAME | 36 | .Sh NAME |
| 43 | .Nm link_addr , | 37 | .Nm link_addr , |
| 44 | .Nm link_ntoa | 38 | .Nm link_ntoa |
| 45 | .Nd elementary address specification routines for link level access | 39 | .Nd elementary address specification routines for link level access |
| 46 | .Sh SYNOPSIS | 40 | .Sh SYNOPSIS |
| 47 | .Fd #include <sys/types.h> | 41 | .In sys/types.h |
| 48 | .Fd #include <sys/socket.h> | 42 | .In sys/socket.h |
| 49 | .Fd #include <net/if_dl.h> | 43 | .In net/if_dl.h |
| 50 | .Ft void | 44 | .Ft void |
| 51 | .Fn link_addr "const char *addr" "struct sockaddr_dl *sdl" | 45 | .Fn link_addr "const char *addr" "struct sockaddr_dl *sdl" |
| 52 | .Ft char * | 46 | .Ft char * |
| 53 | .Fn link_ntoa "const struct sockaddr_dl *sdl" | 47 | .Fn link_ntoa "const struct sockaddr_dl *sdl" |
| 54 | .Sh DESCRIPTION | 48 | .Sh DESCRIPTION |
| 55 | The routine | 49 | The |
| 56 | .Fn link_addr | 50 | .Fn link_addr |
| 57 | interprets character strings representing | 51 | function interprets character strings representing |
| 58 | link-level addresses, returning binary information suitable | 52 | link-level addresses, returning binary information suitable |
| 59 | for use in system calls. | 53 | for use in system calls. |
| 60 | The routine | ||
| 61 | .Fn link_ntoa | 54 | .Fn link_ntoa |
| 62 | takes | 55 | takes |
| 63 | a link-level | 56 | a link-level |
| @@ -75,9 +68,9 @@ the string | |||
| 75 | .Fa addr | 68 | .Fa addr |
| 76 | may contain | 69 | may contain |
| 77 | an optional network interface identifier of the form | 70 | an optional network interface identifier of the form |
| 78 | .Dq "name unit-number" , | 71 | .Dq name unit-number , |
| 79 | suitable for the first argument to | 72 | suitable for the first argument to |
| 80 | .Xr ifconfig 4 , | 73 | .Xr ifconfig 8 , |
| 81 | followed in all cases by a colon and | 74 | followed in all cases by a colon and |
| 82 | an interface address in the form of | 75 | an interface address in the form of |
| 83 | groups of hexadecimal digits | 76 | groups of hexadecimal digits |
| @@ -93,26 +86,27 @@ low order bytes through high order bytes. | |||
| 93 | .\" .Pp | 86 | .\" .Pp |
| 94 | Thus | 87 | Thus |
| 95 | .Li le0:8.0.9.13.d.30 | 88 | .Li le0:8.0.9.13.d.30 |
| 96 | represents an ethernet address | 89 | represents an Ethernet address |
| 97 | to be transmitted on the first Lance ethernet interface. | 90 | to be transmitted on the first Lance Ethernet interface. |
| 98 | .Sh RETURN VALUES | 91 | .Sh RETURN VALUES |
| 99 | .Fn link_ntoa | 92 | .Fn link_ntoa |
| 100 | always returns a null terminated string. | 93 | always returns a NUL-terminated string. |
| 101 | .Fn link_addr | 94 | .Fn link_addr |
| 102 | has no return value. | 95 | has no return value. |
| 103 | (See | 96 | (See |
| 104 | .Sx BUGS . ) | 97 | .Sx BUGS . ) |
| 105 | .Sh SEE ALSO | 98 | .Sh SEE ALSO |
| 106 | .Xr iso 4 , | 99 | .Xr ifconfig 8 |
| 107 | .Sh HISTORY | 100 | .Sh HISTORY |
| 108 | The | 101 | The |
| 109 | .Fn link_addr | 102 | .Fn link_addr |
| 110 | and | 103 | and |
| 111 | .Fn link_ntoa | 104 | .Fn link_ntoa |
| 112 | functions appeared in | 105 | functions appeared in |
| 113 | .Bx 4.3 Reno . | 106 | .Bx 4.3 Reno . |
| 114 | .Sh BUGS | 107 | .Sh BUGS |
| 115 | The returned values for link_ntoa | 108 | The returned values for |
| 109 | .Fn link_ntoa | ||
| 116 | reside in a static memory area. | 110 | reside in a static memory area. |
| 117 | .Pp | 111 | .Pp |
| 118 | The function | 112 | The function |
| @@ -121,7 +115,7 @@ should diagnose improperly formed input, and there should be an unambiguous | |||
| 121 | way to recognize this. | 115 | way to recognize this. |
| 122 | .Pp | 116 | .Pp |
| 123 | If the | 117 | If the |
| 124 | .Va sdl_len | 118 | .Fa sdl_len |
| 125 | field of the link socket address | 119 | field of the link socket address |
| 126 | .Fa sdl | 120 | .Fa sdl |
| 127 | is 0, | 121 | is 0, |
diff --git a/src/lib/libc/net/linkaddr.c b/src/lib/libc/net/linkaddr.c index 19a0de3abd..ac96f3acdf 100644 --- a/src/lib/libc/net/linkaddr.c +++ b/src/lib/libc/net/linkaddr.c | |||
| @@ -1,5 +1,4 @@ | |||
| 1 | /* $NetBSD: linkaddr.c,v 1.5 1995/02/25 06:20:49 cgd Exp $ */ | 1 | /* $OpenBSD: linkaddr.c,v 1.5 2005/08/06 20:30:03 espie Exp $ */ |
| 2 | |||
| 3 | /*- | 2 | /*- |
| 4 | * Copyright (c) 1990, 1993 | 3 | * Copyright (c) 1990, 1993 |
| 5 | * The Regents of the University of California. All rights reserved. | 4 | * The Regents of the University of California. All rights reserved. |
| @@ -12,11 +11,7 @@ | |||
| 12 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
| 13 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the |
| 14 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. |
| 15 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. Neither the name of the University nor the names of its contributors |
| 16 | * must display the following acknowledgement: | ||
| 17 | * This product includes software developed by the University of | ||
| 18 | * California, Berkeley and its contributors. | ||
| 19 | * 4. Neither the name of the University nor the names of its contributors | ||
| 20 | * may be used to endorse or promote products derived from this software | 15 | * may be used to endorse or promote products derived from this software |
| 21 | * without specific prior written permission. | 16 | * without specific prior written permission. |
| 22 | * | 17 | * |
| @@ -33,14 +28,6 @@ | |||
| 33 | * SUCH DAMAGE. | 28 | * SUCH DAMAGE. |
| 34 | */ | 29 | */ |
| 35 | 30 | ||
| 36 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 37 | #if 0 | ||
| 38 | static char sccsid[] = "@(#)linkaddr.c 8.1 (Berkeley) 6/4/93"; | ||
| 39 | #else | ||
| 40 | static char rcsid[] = "$NetBSD: linkaddr.c,v 1.5 1995/02/25 06:20:49 cgd Exp $"; | ||
| 41 | #endif | ||
| 42 | #endif /* LIBC_SCCS and not lint */ | ||
| 43 | |||
| 44 | #include <sys/types.h> | 31 | #include <sys/types.h> |
| 45 | #include <sys/socket.h> | 32 | #include <sys/socket.h> |
| 46 | #include <net/if_dl.h> | 33 | #include <net/if_dl.h> |
| @@ -58,13 +45,11 @@ static char rcsid[] = "$NetBSD: linkaddr.c,v 1.5 1995/02/25 06:20:49 cgd Exp $"; | |||
| 58 | #define LETTER (4*3) | 45 | #define LETTER (4*3) |
| 59 | 46 | ||
| 60 | void | 47 | void |
| 61 | link_addr(addr, sdl) | 48 | link_addr(const char *addr, struct sockaddr_dl *sdl) |
| 62 | register const char *addr; | ||
| 63 | register struct sockaddr_dl *sdl; | ||
| 64 | { | 49 | { |
| 65 | register char *cp = sdl->sdl_data; | 50 | char *cp = sdl->sdl_data; |
| 66 | char *cplim = sdl->sdl_len + (char *)sdl; | 51 | char *cplim = sdl->sdl_len + (char *)sdl; |
| 67 | register int byte = 0, state = NAMING, new; | 52 | int byte = 0, state = NAMING, new; |
| 68 | 53 | ||
| 69 | bzero((char *)&sdl->sdl_family, sdl->sdl_len - 1); | 54 | bzero((char *)&sdl->sdl_family, sdl->sdl_len - 1); |
| 70 | sdl->sdl_family = AF_LINK; | 55 | sdl->sdl_family = AF_LINK; |
| @@ -129,13 +114,12 @@ link_addr(addr, sdl) | |||
| 129 | static char hexlist[] = "0123456789abcdef"; | 114 | static char hexlist[] = "0123456789abcdef"; |
| 130 | 115 | ||
| 131 | char * | 116 | char * |
| 132 | link_ntoa(sdl) | 117 | link_ntoa(const struct sockaddr_dl *sdl) |
| 133 | register const struct sockaddr_dl *sdl; | ||
| 134 | { | 118 | { |
| 135 | static char obuf[64]; | 119 | static char obuf[64]; |
| 136 | register char *out = obuf; | 120 | char *out = obuf; |
| 137 | register int i; | 121 | int i; |
| 138 | register u_char *in = (u_char *)LLADDR(sdl); | 122 | u_char *in = (u_char *)LLADDR(sdl); |
| 139 | u_char *inlim = in + sdl->sdl_alen; | 123 | u_char *inlim = in + sdl->sdl_alen; |
| 140 | int firsttime = 1; | 124 | int firsttime = 1; |
| 141 | 125 | ||
diff --git a/src/lib/libc/net/ns.3 b/src/lib/libc/net/ns.3 deleted file mode 100644 index f89b4fe042..0000000000 --- a/src/lib/libc/net/ns.3 +++ /dev/null | |||
| @@ -1,132 +0,0 @@ | |||
| 1 | .\" $NetBSD: ns.3,v 1.3 1995/02/25 06:20:50 cgd 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 | .\" @(#)ns.3 8.1 (Berkeley) 6/4/93 | ||
| 35 | .\" | ||
| 36 | .Dd June 4, 1993 | ||
| 37 | .Dt NS 3 | ||
| 38 | .Os BSD 4.3 | ||
| 39 | .Sh NAME | ||
| 40 | .Nm ns_addr , | ||
| 41 | .Nm ns_ntoa | ||
| 42 | .Nd Xerox | ||
| 43 | .Tn NS Ns (tm) | ||
| 44 | address conversion routines | ||
| 45 | .Sh SYNOPSIS | ||
| 46 | .Fd #include <sys/types.h> | ||
| 47 | .Fd #include <netns/ns.h> | ||
| 48 | .Ft struct ns_addr | ||
| 49 | .Fn ns_addr "char *cp" | ||
| 50 | .Ft char * | ||
| 51 | .Fn ns_ntoa "struct ns_addr ns" | ||
| 52 | .Sh DESCRIPTION | ||
| 53 | The routine | ||
| 54 | .Fn ns_addr | ||
| 55 | interprets character strings representing | ||
| 56 | .Tn XNS | ||
| 57 | addresses, returning binary information suitable | ||
| 58 | for use in system calls. | ||
| 59 | The routine | ||
| 60 | .Fn ns_ntoa | ||
| 61 | takes | ||
| 62 | .Tn XNS | ||
| 63 | addresses and returns | ||
| 64 | .Tn ASCII | ||
| 65 | strings representing the address in a | ||
| 66 | notation in common use in the Xerox Development Environment: | ||
| 67 | .Bd -filled -offset indent | ||
| 68 | <network number>.<host number>.<port number> | ||
| 69 | .Ed | ||
| 70 | .Pp | ||
| 71 | Trailing zero fields are suppressed, and each number is printed in hexadecimal, | ||
| 72 | in a format suitable for input to | ||
| 73 | .Fn ns_addr . | ||
| 74 | Any fields lacking super-decimal digits will have a | ||
| 75 | trailing | ||
| 76 | .Ql H | ||
| 77 | appended. | ||
| 78 | .Pp | ||
| 79 | Unfortunately, no universal standard exists for representing | ||
| 80 | .Tn XNS | ||
| 81 | addresses. | ||
| 82 | An effort has been made to insure that | ||
| 83 | .Fn ns_addr | ||
| 84 | be compatible with most formats in common use. | ||
| 85 | It will first separate an address into 1 to 3 fields using a single delimiter | ||
| 86 | chosen from | ||
| 87 | period | ||
| 88 | .Ql \&. , | ||
| 89 | colon | ||
| 90 | .Ql \&: | ||
| 91 | or pound-sign | ||
| 92 | .Ql \&# . | ||
| 93 | Each field is then examined for byte separators (colon or period). | ||
| 94 | If there are byte separators, each subfield separated is taken to be | ||
| 95 | a small hexadecimal number, and the entirety is taken as a network-byte-ordered | ||
| 96 | quantity to be zero extended in the high-network-order bytes. | ||
| 97 | Next, the field is inspected for hyphens, in which case | ||
| 98 | the field is assumed to be a number in decimal notation | ||
| 99 | with hyphens separating the millenia. | ||
| 100 | Next, the field is assumed to be a number: | ||
| 101 | It is interpreted | ||
| 102 | as hexadecimal if there is a leading | ||
| 103 | .Ql 0x | ||
| 104 | (as in C), | ||
| 105 | a trailing | ||
| 106 | .Ql H | ||
| 107 | (as in Mesa), or there are any super-decimal digits present. | ||
| 108 | It is interpreted as octal is there is a leading | ||
| 109 | .Ql 0 | ||
| 110 | and there are no super-octal digits. | ||
| 111 | Otherwise, it is converted as a decimal number. | ||
| 112 | .Sh RETURN VALUES | ||
| 113 | None. (See | ||
| 114 | .Sx BUGS . ) | ||
| 115 | .Sh SEE ALSO | ||
| 116 | .Xr hosts 5 , | ||
| 117 | .Xr networks 5 , | ||
| 118 | .Sh HISTORY | ||
| 119 | The | ||
| 120 | .Fn ns_addr | ||
| 121 | and | ||
| 122 | .Fn ns_toa | ||
| 123 | functions appeared in | ||
| 124 | .Bx 4.3 . | ||
| 125 | .Sh BUGS | ||
| 126 | The string returned by | ||
| 127 | .Fn ns_ntoa | ||
| 128 | resides in a static memory area. | ||
| 129 | The function | ||
| 130 | .Fn ns_addr | ||
| 131 | should diagnose improperly formed input, and there should be an unambiguous | ||
| 132 | way to recognize this. | ||
diff --git a/src/lib/libc/net/ns_addr.c b/src/lib/libc/net/ns_addr.c deleted file mode 100644 index f75ddb23b7..0000000000 --- a/src/lib/libc/net/ns_addr.c +++ /dev/null | |||
| @@ -1,233 +0,0 @@ | |||
| 1 | /* $NetBSD: ns_addr.c,v 1.5 1995/02/25 06:20:51 cgd Exp $ */ | ||
| 2 | |||
| 3 | /* | ||
| 4 | * Copyright (c) 1986, 1993 | ||
| 5 | * The Regents of the University of California. All rights reserved. | ||
| 6 | * | ||
| 7 | * This code is derived from software contributed to Berkeley by | ||
| 8 | * J.Q. Johnson. | ||
| 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 University of | ||
| 21 | * California, Berkeley and its contributors. | ||
| 22 | * 4. Neither the name of the University nor the names of its contributors | ||
| 23 | * may be used to endorse or promote products derived from this software | ||
| 24 | * without specific prior written permission. | ||
| 25 | * | ||
| 26 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
| 27 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 28 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 29 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
| 30 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 31 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 32 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 33 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 34 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 35 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 36 | * SUCH DAMAGE. | ||
| 37 | */ | ||
| 38 | |||
| 39 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 40 | #if 0 | ||
| 41 | static char sccsid[] = "@(#)ns_addr.c 8.1 (Berkeley) 6/7/93"; | ||
| 42 | #else | ||
| 43 | static char rcsid[] = "$NetBSD: ns_addr.c,v 1.5 1995/02/25 06:20:51 cgd Exp $"; | ||
| 44 | #endif | ||
| 45 | #endif /* LIBC_SCCS and not lint */ | ||
| 46 | |||
| 47 | #include <sys/param.h> | ||
| 48 | #include <netns/ns.h> | ||
| 49 | #include <stdio.h> | ||
| 50 | #include <string.h> | ||
| 51 | |||
| 52 | static struct ns_addr addr, zero_addr; | ||
| 53 | |||
| 54 | static void Field(), cvtbase(); | ||
| 55 | |||
| 56 | struct ns_addr | ||
| 57 | ns_addr(name) | ||
| 58 | const char *name; | ||
| 59 | { | ||
| 60 | char separator; | ||
| 61 | char *hostname, *socketname, *cp; | ||
| 62 | char buf[50]; | ||
| 63 | |||
| 64 | (void)strncpy(buf, name, sizeof(buf) - 1); | ||
| 65 | buf[sizeof(buf) - 1] = '\0'; | ||
| 66 | |||
| 67 | /* | ||
| 68 | * First, figure out what he intends as a field separtor. | ||
| 69 | * Despite the way this routine is written, the prefered | ||
| 70 | * form 2-272.AA001234H.01777, i.e. XDE standard. | ||
| 71 | * Great efforts are made to insure backward compatability. | ||
| 72 | */ | ||
| 73 | if (hostname = strchr(buf, '#')) | ||
| 74 | separator = '#'; | ||
| 75 | else { | ||
| 76 | hostname = strchr(buf, '.'); | ||
| 77 | if ((cp = strchr(buf, ':')) && | ||
| 78 | ((hostname && cp < hostname) || (hostname == 0))) { | ||
| 79 | hostname = cp; | ||
| 80 | separator = ':'; | ||
| 81 | } else | ||
| 82 | separator = '.'; | ||
| 83 | } | ||
| 84 | if (hostname) | ||
| 85 | *hostname++ = 0; | ||
| 86 | |||
| 87 | addr = zero_addr; | ||
| 88 | Field(buf, addr.x_net.c_net, 4); | ||
| 89 | if (hostname == 0) | ||
| 90 | return (addr); /* No separator means net only */ | ||
| 91 | |||
| 92 | socketname = strchr(hostname, separator); | ||
| 93 | if (socketname) { | ||
| 94 | *socketname++ = 0; | ||
| 95 | Field(socketname, (u_char *)&addr.x_port, 2); | ||
| 96 | } | ||
| 97 | |||
| 98 | Field(hostname, addr.x_host.c_host, 6); | ||
| 99 | |||
| 100 | return (addr); | ||
| 101 | } | ||
| 102 | |||
| 103 | static void | ||
| 104 | Field(buf, out, len) | ||
| 105 | char *buf; | ||
| 106 | u_char *out; | ||
| 107 | int len; | ||
| 108 | { | ||
| 109 | register char *bp = buf; | ||
| 110 | int i, ibase, base16 = 0, base10 = 0, clen = 0; | ||
| 111 | int hb[6], *hp; | ||
| 112 | char *fmt; | ||
| 113 | |||
| 114 | /* | ||
| 115 | * first try 2-273#2-852-151-014#socket | ||
| 116 | */ | ||
| 117 | if ((*buf != '-') && | ||
| 118 | (1 < (i = sscanf(buf, "%d-%d-%d-%d-%d", | ||
| 119 | &hb[0], &hb[1], &hb[2], &hb[3], &hb[4])))) { | ||
| 120 | cvtbase(1000L, 256, hb, i, out, len); | ||
| 121 | return; | ||
| 122 | } | ||
| 123 | /* | ||
| 124 | * try form 8E1#0.0.AA.0.5E.E6#socket | ||
| 125 | */ | ||
| 126 | if (1 < (i = sscanf(buf,"%x.%x.%x.%x.%x.%x", | ||
| 127 | &hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) { | ||
| 128 | cvtbase(256L, 256, hb, i, out, len); | ||
| 129 | return; | ||
| 130 | } | ||
| 131 | /* | ||
| 132 | * try form 8E1#0:0:AA:0:5E:E6#socket | ||
| 133 | */ | ||
| 134 | if (1 < (i = sscanf(buf,"%x:%x:%x:%x:%x:%x", | ||
| 135 | &hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) { | ||
| 136 | cvtbase(256L, 256, hb, i, out, len); | ||
| 137 | return; | ||
| 138 | } | ||
| 139 | /* | ||
| 140 | * This is REALLY stretching it but there was a | ||
| 141 | * comma notation separting shorts -- definitely non standard | ||
| 142 | */ | ||
| 143 | if (1 < (i = sscanf(buf,"%x,%x,%x", | ||
| 144 | &hb[0], &hb[1], &hb[2]))) { | ||
| 145 | hb[0] = htons(hb[0]); hb[1] = htons(hb[1]); | ||
| 146 | hb[2] = htons(hb[2]); | ||
| 147 | cvtbase(65536L, 256, hb, i, out, len); | ||
| 148 | return; | ||
| 149 | } | ||
| 150 | |||
| 151 | /* Need to decide if base 10, 16 or 8 */ | ||
| 152 | while (*bp) switch (*bp++) { | ||
| 153 | |||
| 154 | case '0': case '1': case '2': case '3': case '4': case '5': | ||
| 155 | case '6': case '7': case '-': | ||
| 156 | break; | ||
| 157 | |||
| 158 | case '8': case '9': | ||
| 159 | base10 = 1; | ||
| 160 | break; | ||
| 161 | |||
| 162 | case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': | ||
| 163 | case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': | ||
| 164 | base16 = 1; | ||
| 165 | break; | ||
| 166 | |||
| 167 | case 'x': case 'X': | ||
| 168 | *--bp = '0'; | ||
| 169 | base16 = 1; | ||
| 170 | break; | ||
| 171 | |||
| 172 | case 'h': case 'H': | ||
| 173 | base16 = 1; | ||
| 174 | /* fall into */ | ||
| 175 | |||
| 176 | default: | ||
| 177 | *--bp = 0; /* Ends Loop */ | ||
| 178 | } | ||
| 179 | if (base16) { | ||
| 180 | fmt = "%3x"; | ||
| 181 | ibase = 4096; | ||
| 182 | } else if (base10 == 0 && *buf == '0') { | ||
| 183 | fmt = "%3o"; | ||
| 184 | ibase = 512; | ||
| 185 | } else { | ||
| 186 | fmt = "%3d"; | ||
| 187 | ibase = 1000; | ||
| 188 | } | ||
| 189 | |||
| 190 | for (bp = buf; *bp++; ) clen++; | ||
| 191 | if (clen == 0) clen++; | ||
| 192 | if (clen > 18) clen = 18; | ||
| 193 | i = ((clen - 1) / 3) + 1; | ||
| 194 | bp = clen + buf - 3; | ||
| 195 | hp = hb + i - 1; | ||
| 196 | |||
| 197 | while (hp > hb) { | ||
| 198 | (void)sscanf(bp, fmt, hp); | ||
| 199 | bp[0] = 0; | ||
| 200 | hp--; | ||
| 201 | bp -= 3; | ||
| 202 | } | ||
| 203 | (void)sscanf(buf, fmt, hp); | ||
| 204 | cvtbase((long)ibase, 256, hb, i, out, len); | ||
| 205 | } | ||
| 206 | |||
| 207 | static void | ||
| 208 | cvtbase(oldbase,newbase,input,inlen,result,reslen) | ||
| 209 | long oldbase; | ||
| 210 | int newbase; | ||
| 211 | int input[]; | ||
| 212 | int inlen; | ||
| 213 | unsigned char result[]; | ||
| 214 | int reslen; | ||
| 215 | { | ||
| 216 | int d, e; | ||
| 217 | long sum; | ||
| 218 | |||
| 219 | e = 1; | ||
| 220 | while (e > 0 && reslen > 0) { | ||
| 221 | d = 0; e = 0; sum = 0; | ||
| 222 | /* long division: input=input/newbase */ | ||
| 223 | while (d < inlen) { | ||
| 224 | sum = sum*oldbase + (long) input[d]; | ||
| 225 | e += (sum > 0); | ||
| 226 | input[d++] = sum / newbase; | ||
| 227 | sum %= newbase; | ||
| 228 | } | ||
| 229 | result[--reslen] = sum; /* accumulate remainder */ | ||
| 230 | } | ||
| 231 | for (d=0; d < reslen; d++) | ||
| 232 | result[d] = 0; | ||
| 233 | } | ||
diff --git a/src/lib/libc/net/ns_ntoa.c b/src/lib/libc/net/ns_ntoa.c deleted file mode 100644 index ad3265399b..0000000000 --- a/src/lib/libc/net/ns_ntoa.c +++ /dev/null | |||
| @@ -1,106 +0,0 @@ | |||
| 1 | /* $NetBSD: ns_ntoa.c,v 1.4 1995/02/25 06:20:51 cgd Exp $ */ | ||
| 2 | |||
| 3 | /* | ||
| 4 | * Copyright (c) 1986, 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 | ||
| 38 | static char sccsid[] = "@(#)ns_ntoa.c 8.1 (Berkeley) 6/4/93"; | ||
| 39 | #else | ||
| 40 | static char rcsid[] = "$NetBSD: ns_ntoa.c,v 1.4 1995/02/25 06:20:51 cgd Exp $"; | ||
| 41 | #endif | ||
| 42 | #endif /* LIBC_SCCS and not lint */ | ||
| 43 | |||
| 44 | #include <sys/param.h> | ||
| 45 | #include <netns/ns.h> | ||
| 46 | #include <stdio.h> | ||
| 47 | |||
| 48 | char * | ||
| 49 | ns_ntoa(addr) | ||
| 50 | struct ns_addr addr; | ||
| 51 | { | ||
| 52 | static char obuf[40]; | ||
| 53 | union { union ns_net net_e; u_long long_e; } net; | ||
| 54 | u_short port = htons(addr.x_port); | ||
| 55 | register char *cp; | ||
| 56 | char *cp2; | ||
| 57 | register u_char *up = addr.x_host.c_host; | ||
| 58 | u_char *uplim = up + 6; | ||
| 59 | static char *spectHex(); | ||
| 60 | |||
| 61 | net.net_e = addr.x_net; | ||
| 62 | sprintf(obuf, "%lx", ntohl(net.long_e)); | ||
| 63 | cp = spectHex(obuf); | ||
| 64 | cp2 = cp + 1; | ||
| 65 | while (*up==0 && up < uplim) up++; | ||
| 66 | if (up == uplim) { | ||
| 67 | if (port) { | ||
| 68 | sprintf(cp, ".0"); | ||
| 69 | cp += 2; | ||
| 70 | } | ||
| 71 | } else { | ||
| 72 | sprintf(cp, ".%x", *up++); | ||
| 73 | while (up < uplim) { | ||
| 74 | while (*cp) cp++; | ||
| 75 | sprintf(cp, "%02x", *up++); | ||
| 76 | } | ||
| 77 | cp = spectHex(cp2); | ||
| 78 | } | ||
| 79 | if (port) { | ||
| 80 | sprintf(cp, ".%x", port); | ||
| 81 | spectHex(cp + 1); | ||
| 82 | } | ||
| 83 | return (obuf); | ||
| 84 | } | ||
| 85 | |||
| 86 | static char * | ||
| 87 | spectHex(p0) | ||
| 88 | char *p0; | ||
| 89 | { | ||
| 90 | int ok = 0; | ||
| 91 | int nonzero = 0; | ||
| 92 | register char *p = p0; | ||
| 93 | for (; *p; p++) switch (*p) { | ||
| 94 | |||
| 95 | case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': | ||
| 96 | *p += ('A' - 'a'); | ||
| 97 | /* fall into . . . */ | ||
| 98 | case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': | ||
| 99 | ok = 1; | ||
| 100 | case '1': case '2': case '3': case '4': case '5': | ||
| 101 | case '6': case '7': case '8': case '9': | ||
| 102 | nonzero = 1; | ||
| 103 | } | ||
| 104 | if (nonzero && !ok) { *p++ = 'H'; *p = 0; } | ||
| 105 | return (p); | ||
| 106 | } | ||
diff --git a/src/lib/libc/net/ntohl.c b/src/lib/libc/net/ntohl.c index 05b7f4c9a3..36414b7a13 100644 --- a/src/lib/libc/net/ntohl.c +++ b/src/lib/libc/net/ntohl.c | |||
| @@ -1,29 +1,21 @@ | |||
| 1 | /* $NetBSD: ntohl.c,v 1.5 1995/04/28 23:25:21 jtc Exp $ */ | 1 | /* $OpenBSD: ntohl.c,v 1.6 2005/08/06 20:30:03 espie Exp $ */ |
| 2 | |||
| 3 | /* | 2 | /* |
| 4 | * Written by J.T. Conklin <jtc@netbsd.org>. | 3 | * Written by J.T. Conklin <jtc@netbsd.org>. |
| 5 | * Public domain. | 4 | * Public domain. |
| 6 | */ | 5 | */ |
| 7 | 6 | ||
| 8 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 9 | static char *rcsid = "$NetBSD: ntohl.c,v 1.5 1995/04/28 23:25:21 jtc Exp $"; | ||
| 10 | #endif | ||
| 11 | |||
| 12 | #include <sys/types.h> | 7 | #include <sys/types.h> |
| 13 | #include <machine/endian.h> | 8 | #include <machine/endian.h> |
| 14 | 9 | ||
| 15 | #undef ntohl | 10 | #undef ntohl |
| 16 | 11 | ||
| 17 | unsigned long | 12 | u_int32_t |
| 18 | ntohl(x) | 13 | ntohl(u_int32_t x) |
| 19 | unsigned long x; | ||
| 20 | { | 14 | { |
| 21 | u_int32_t y = x; | ||
| 22 | |||
| 23 | #if BYTE_ORDER == LITTLE_ENDIAN | 15 | #if BYTE_ORDER == LITTLE_ENDIAN |
| 24 | u_char *s = (u_char *)&y; | 16 | u_char *s = (u_char *)&x; |
| 25 | return s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]; | 17 | return (u_int32_t)(s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]); |
| 26 | #else | 18 | #else |
| 27 | return y; | 19 | return x; |
| 28 | #endif | 20 | #endif |
| 29 | } | 21 | } |
diff --git a/src/lib/libc/net/ntohs.c b/src/lib/libc/net/ntohs.c index 93ab83ee4d..8f345e84ad 100644 --- a/src/lib/libc/net/ntohs.c +++ b/src/lib/libc/net/ntohs.c | |||
| @@ -1,26 +1,20 @@ | |||
| 1 | /* $NetBSD: ntohs.c,v 1.5 1995/04/28 23:25:23 jtc Exp $ */ | 1 | /* $OpenBSD: ntohs.c,v 1.8 2005/08/06 20:30:03 espie Exp $ */ |
| 2 | |||
| 3 | /* | 2 | /* |
| 4 | * Written by J.T. Conklin <jtc@netbsd.org>. | 3 | * Written by J.T. Conklin <jtc@netbsd.org>. |
| 5 | * Public domain. | 4 | * Public domain. |
| 6 | */ | 5 | */ |
| 7 | 6 | ||
| 8 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 9 | static char *rcsid = "$NetBSD: ntohs.c,v 1.5 1995/04/28 23:25:23 jtc Exp $"; | ||
| 10 | #endif | ||
| 11 | |||
| 12 | #include <sys/types.h> | 7 | #include <sys/types.h> |
| 13 | #include <machine/endian.h> | 8 | #include <machine/endian.h> |
| 14 | 9 | ||
| 15 | #undef ntohs | 10 | #undef ntohs |
| 16 | 11 | ||
| 17 | unsigned short | 12 | u_int16_t |
| 18 | ntohs(x) | 13 | ntohs(u_int16_t x) |
| 19 | unsigned short x; | ||
| 20 | { | 14 | { |
| 21 | #if BYTE_ORDER == LITTLE_ENDIAN | 15 | #if BYTE_ORDER == LITTLE_ENDIAN |
| 22 | u_char *s = (u_char *) &x; | 16 | u_char *s = (u_char *) &x; |
| 23 | return s[0] << 8 | s[1]; | 17 | return (u_int16_t)(s[0] << 8 | s[1]); |
| 24 | #else | 18 | #else |
| 25 | return x; | 19 | return x; |
| 26 | #endif | 20 | #endif |
diff --git a/src/lib/libc/net/rcmd.3 b/src/lib/libc/net/rcmd.3 index 4db847c392..447aa23ff1 100644 --- a/src/lib/libc/net/rcmd.3 +++ b/src/lib/libc/net/rcmd.3 | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | .\" $NetBSD: rcmd.3,v 1.8 1995/02/25 06:20:52 cgd Exp $ | 1 | .\" $OpenBSD: rcmd.3,v 1.29 2014/01/21 03:15:45 schwarze Exp $ |
| 2 | .\" | 2 | .\" |
| 3 | .\" Copyright (c) 1983, 1991, 1993 | 3 | .\" Copyright (c) 1983, 1991, 1993 |
| 4 | .\" The Regents of the University of California. All rights reserved. | 4 | .\" The Regents of the University of California. All rights reserved. |
| @@ -11,11 +11,7 @@ | |||
| 11 | .\" 2. Redistributions in binary form must reproduce the above copyright | 11 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 12 | .\" notice, this list of conditions and the following disclaimer in the | 12 | .\" notice, this list of conditions and the following disclaimer in the |
| 13 | .\" documentation and/or other materials provided with the distribution. | 13 | .\" documentation and/or other materials provided with the distribution. |
| 14 | .\" 3. All advertising materials mentioning features or use of this software | 14 | .\" 3. Neither the name of the University nor the names of its contributors |
| 15 | .\" must display the following acknowledgement: | ||
| 16 | .\" This product includes software developed by the University of | ||
| 17 | .\" California, Berkeley and its contributors. | ||
| 18 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 19 | .\" may be used to endorse or promote products derived from this software | 15 | .\" may be used to endorse or promote products derived from this software |
| 20 | .\" without specific prior written permission. | 16 | .\" without specific prior written permission. |
| 21 | .\" | 17 | .\" |
| @@ -31,38 +27,67 @@ | |||
| 31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 27 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 32 | .\" SUCH DAMAGE. | 28 | .\" SUCH DAMAGE. |
| 33 | .\" | 29 | .\" |
| 34 | .\" @(#)rcmd.3 8.1 (Berkeley) 6/4/93 | 30 | .Dd $Mdocdate: January 21 2014 $ |
| 35 | .\" | ||
| 36 | .Dd June 4, 1993 | ||
| 37 | .Dt RCMD 3 | 31 | .Dt RCMD 3 |
| 38 | .Os BSD 4.2 | 32 | .Os |
| 39 | .Sh NAME | 33 | .Sh NAME |
| 40 | .Nm rcmd , | 34 | .Nm rcmd , |
| 35 | .Nm rcmd_af , | ||
| 41 | .Nm rresvport , | 36 | .Nm rresvport , |
| 37 | .Nm rresvport_af , | ||
| 42 | .Nm iruserok , | 38 | .Nm iruserok , |
| 43 | .Nm ruserok | 39 | .Nm ruserok , |
| 40 | .Nm iruserok_sa | ||
| 44 | .Nd routines for returning a stream to a remote command | 41 | .Nd routines for returning a stream to a remote command |
| 45 | .Sh SYNOPSIS | 42 | .Sh SYNOPSIS |
| 46 | .Fd #include <unistd.h> | 43 | .In unistd.h |
| 47 | .Ft int | 44 | .Ft int |
| 48 | .Fn rcmd "char **ahost" "int inport" "const char *locuser" "const char *remuser" "const char *cmd" "int *fd2p" | 45 | .Fn rcmd "char **ahost" "int inport" "const char *locuser" "const char *remuser" "const char *cmd" "int *fd2p" |
| 49 | .Ft int | 46 | .Ft int |
| 47 | .Fn rcmd_af "char **ahost" "int inport" "const char *locuser" "const char *remuser" "const char *cmd" "int *fd2p" "int af" | ||
| 48 | .Ft int | ||
| 50 | .Fn rresvport "int *port" | 49 | .Fn rresvport "int *port" |
| 51 | .Ft int | 50 | .Ft int |
| 52 | .Fn iruserok "u_long raddr" "int superuser" "const char *ruser" "const char *luser" | 51 | .Fn rresvport_af "int *port" "int af" |
| 52 | .Ft int | ||
| 53 | .Fn iruserok "u_int32_t raddr" "int superuser" "const char *ruser" "const char *luser" | ||
| 53 | .Ft int | 54 | .Ft int |
| 54 | .Fn ruserok "const char *rhost" "int superuser" "const char *ruser" "const char *luser" | 55 | .Fn ruserok "const char *rhost" "int superuser" "const char *ruser" "const char *luser" |
| 56 | .Ft int | ||
| 57 | .Fn iruserok_sa "const void *sa" "int salen" "int superuser" "const char *ruser" "const char *luser" | ||
| 55 | .Sh DESCRIPTION | 58 | .Sh DESCRIPTION |
| 56 | The | 59 | The |
| 57 | .Fn rcmd | 60 | .Fn rcmd |
| 58 | function | 61 | function is used by the superuser to execute a command on a remote |
| 59 | is used by the super-user to execute a command on | 62 | machine using an authentication scheme based on reserved |
| 60 | a remote machine using an authentication scheme based | 63 | port numbers. |
| 61 | on reserved port numbers. | 64 | If the calling process is not setuid, the |
| 65 | .Ev RSH | ||
| 66 | environment variable is set, and | ||
| 67 | .Fa inport | ||
| 68 | is | ||
| 69 | .Dq shell/tcp , | ||
| 70 | .Xr rcmdsh 3 | ||
| 71 | is called instead with the value of | ||
| 72 | .Ev RSH . | ||
| 73 | Alternately, if the user is not the superuser, | ||
| 74 | .Fn rcmd | ||
| 75 | will invoke | ||
| 76 | .Xr rcmdsh 3 | ||
| 77 | to run the command via | ||
| 78 | .Xr rsh 1 . | ||
| 79 | While | ||
| 80 | .Fn rcmd | ||
| 81 | can handle IPv4 cases only, | ||
| 82 | the | ||
| 83 | .Fn rcmd_af | ||
| 84 | function can handle other cases as well. | ||
| 85 | .Pp | ||
| 62 | The | 86 | The |
| 63 | .Fn rresvport | 87 | .Fn rresvport |
| 64 | function | 88 | and |
| 65 | returns a descriptor to a socket | 89 | .Fn rresvport_af |
| 90 | functions return a descriptor to a socket | ||
| 66 | with an address in the privileged port space. | 91 | with an address in the privileged port space. |
| 67 | The | 92 | The |
| 68 | .Fn iruserok | 93 | .Fn iruserok |
| @@ -75,11 +100,13 @@ All four functions are present in the same file and are used | |||
| 75 | by the | 100 | by the |
| 76 | .Xr rshd 8 | 101 | .Xr rshd 8 |
| 77 | server (among others). | 102 | server (among others). |
| 103 | .Fn iruserok_sa | ||
| 104 | is an address family independent variant of | ||
| 105 | .Fn iruserok . | ||
| 78 | .Pp | 106 | .Pp |
| 79 | The | 107 | The |
| 80 | .Fn rcmd | 108 | .Fn rcmd |
| 81 | function | 109 | function looks up the host |
| 82 | looks up the host | ||
| 83 | .Fa *ahost | 110 | .Fa *ahost |
| 84 | using | 111 | using |
| 85 | .Xr gethostbyname 3 , | 112 | .Xr gethostbyname 3 , |
| @@ -90,15 +117,15 @@ is set to the standard name of the host | |||
| 90 | and a connection is established to a server | 117 | and a connection is established to a server |
| 91 | residing at the well-known Internet port | 118 | residing at the well-known Internet port |
| 92 | .Fa inport . | 119 | .Fa inport . |
| 120 | If the user is not the superuser, the only valid port is | ||
| 121 | .Dq shell/tcp | ||
| 122 | (usually port 514). | ||
| 93 | .Pp | 123 | .Pp |
| 94 | If the connection succeeds, | 124 | If the connection succeeds, |
| 95 | a socket in the Internet domain of type | 125 | a socket in the Internet domain of type |
| 96 | .Dv SOCK_STREAM | 126 | .Dv SOCK_STREAM |
| 97 | is returned to the caller, and given to the remote | 127 | is returned to the caller, and given to the remote |
| 98 | command as | 128 | command as stdin and stdout. |
| 99 | .Em stdin | ||
| 100 | and | ||
| 101 | .Em stdout . | ||
| 102 | If | 129 | If |
| 103 | .Fa fd2p | 130 | .Fa fd2p |
| 104 | is non-zero, then an auxiliary channel to a control | 131 | is non-zero, then an auxiliary channel to a control |
| @@ -113,27 +140,46 @@ signal numbers, to be | |||
| 113 | forwarded to the process group of the command. | 140 | forwarded to the process group of the command. |
| 114 | If | 141 | If |
| 115 | .Fa fd2p | 142 | .Fa fd2p |
| 116 | is 0, then the | 143 | is |
| 117 | .Em stderr | 144 | .Va NULL , |
| 118 | (unit 2 of the remote | 145 | then the standard error (unit 2 of the remote command) will be made |
| 119 | command) will be made the same as the | 146 | the same as the standard output and no provision is made for sending |
| 120 | .Em stdout | 147 | arbitrary signals to the remote process, although you may be able to |
| 121 | and no | 148 | get its attention by using out-of-band data. |
| 122 | provision is made for sending arbitrary signals to the remote process, | 149 | Note that if the user is not the superuser, |
| 123 | although you may be able to get its attention by using out-of-band data. | 150 | .Fa fd2p |
| 151 | must be | ||
| 152 | .Va NULL . | ||
| 153 | .Pp | ||
| 154 | .Fn rcmd_af | ||
| 155 | takes address family in the last argument. | ||
| 156 | If the last argument is | ||
| 157 | .Dv PF_UNSPEC , | ||
| 158 | interpretation of | ||
| 159 | .Fa *ahost | ||
| 160 | will obey the underlying address resolution like DNS. | ||
| 124 | .Pp | 161 | .Pp |
| 125 | The protocol is described in detail in | 162 | The protocol is described in detail in |
| 126 | .Xr rshd 8 . | 163 | .Xr rshd 8 . |
| 127 | .Pp | 164 | .Pp |
| 128 | The | 165 | The |
| 129 | .Fn rresvport | 166 | .Fn rresvport |
| 130 | function is used to obtain a socket with a privileged | 167 | and |
| 131 | address bound to it. This socket is suitable for use | 168 | .Fn rresvport_af |
| 132 | by | 169 | functions are used to obtain a socket with a privileged |
| 170 | address bound to it. | ||
| 171 | This socket is suitable for use by | ||
| 133 | .Fn rcmd | 172 | .Fn rcmd |
| 134 | and several other functions. Privileged Internet ports are those | 173 | and several other functions. |
| 135 | in the range 0 to 1023. Only the super-user | 174 | Privileged Internet ports are those in the range 0 to |
| 136 | is allowed to bind an address of this sort to a socket. | 175 | .Va IPPORT_RESERVED - 1 , |
| 176 | which happens to be 1023. | ||
| 177 | Only the superuser is allowed to bind an address of this sort to a socket. | ||
| 178 | .Fn rresvport | ||
| 179 | and | ||
| 180 | .Fn rresvport_af | ||
| 181 | need to be seeded with a port number; if that port | ||
| 182 | is not available these functions will find another. | ||
| 137 | .Pp | 183 | .Pp |
| 138 | The | 184 | The |
| 139 | .Fn iruserok | 185 | .Fn iruserok |
| @@ -141,10 +187,10 @@ and | |||
| 141 | .Fn ruserok | 187 | .Fn ruserok |
| 142 | functions take a remote host's IP address or name, respectively, | 188 | functions take a remote host's IP address or name, respectively, |
| 143 | two user names and a flag indicating whether the local user's | 189 | two user names and a flag indicating whether the local user's |
| 144 | name is that of the super-user. | 190 | name is that of the superuser. |
| 145 | Then, if the user is | 191 | Then, if the user is |
| 146 | .Em NOT | 192 | .Em not |
| 147 | the super-user, it checks the | 193 | the superuser, it checks the |
| 148 | .Pa /etc/hosts.equiv | 194 | .Pa /etc/hosts.equiv |
| 149 | file. | 195 | file. |
| 150 | If that lookup is not done, or is unsuccessful, the | 196 | If that lookup is not done, or is unsuccessful, the |
| @@ -153,19 +199,19 @@ in the local user's home directory is checked to see if the request for | |||
| 153 | service is allowed. | 199 | service is allowed. |
| 154 | .Pp | 200 | .Pp |
| 155 | If this file does not exist, is not a regular file, is owned by anyone | 201 | If this file does not exist, is not a regular file, is owned by anyone |
| 156 | other than the user or the super-user, or is writeable by anyone other | 202 | other than the user or the superuser, or is writeable by anyone other |
| 157 | than the owner, the check automatically fails. | 203 | than the owner, the check automatically fails. |
| 158 | Zero is returned if the machine name is listed in the | 204 | Zero is returned if the machine name is listed in the |
| 159 | .Dq Pa hosts.equiv | 205 | .Pa hosts.equiv |
| 160 | file, or the host and remote user name are found in the | 206 | file, or the host and remote user name are found in the |
| 161 | .Dq Pa .rhosts | 207 | .Pa .rhosts |
| 162 | file; otherwise | 208 | file; otherwise |
| 163 | .Fn iruserok | 209 | .Fn iruserok |
| 164 | and | 210 | and |
| 165 | .Fn ruserok | 211 | .Fn ruserok |
| 166 | return \-1. | 212 | return \-1. |
| 167 | If the local domain (as obtained from | 213 | If the local domain (as obtained from |
| 168 | .Xr gethostname 2 ) | 214 | .Xr gethostname 3 ) |
| 169 | is the same as the remote domain, only the machine name need be specified. | 215 | is the same as the remote domain, only the machine name need be specified. |
| 170 | .Pp | 216 | .Pp |
| 171 | If the IP address of the remote host is known, | 217 | If the IP address of the remote host is known, |
| @@ -173,32 +219,48 @@ If the IP address of the remote host is known, | |||
| 173 | should be used in preference to | 219 | should be used in preference to |
| 174 | .Fn ruserok , | 220 | .Fn ruserok , |
| 175 | as it does not require trusting the DNS server for the remote host's domain. | 221 | as it does not require trusting the DNS server for the remote host's domain. |
| 222 | .Pp | ||
| 223 | While | ||
| 224 | .Fn iruserok | ||
| 225 | can handle IPv4 addresses only, | ||
| 226 | .Fn iruserok_sa | ||
| 227 | and | ||
| 228 | .Fn ruserok | ||
| 229 | can handle other address families as well, like IPv6. | ||
| 230 | The first argument of | ||
| 231 | .Fn iruserok_sa | ||
| 232 | is typed as | ||
| 233 | .Li "void *" | ||
| 234 | to avoid dependency between | ||
| 235 | .In unistd.h | ||
| 236 | and | ||
| 237 | .In sys/socket.h . | ||
| 176 | .Sh DIAGNOSTICS | 238 | .Sh DIAGNOSTICS |
| 177 | The | 239 | The |
| 178 | .Fn rcmd | 240 | .Fn rcmd |
| 179 | function | 241 | function returns a valid socket descriptor on success. |
| 180 | returns a valid socket descriptor on success. | ||
| 181 | It returns \-1 on error and prints a diagnostic message on the standard error. | 242 | It returns \-1 on error and prints a diagnostic message on the standard error. |
| 182 | .Pp | 243 | .Pp |
| 183 | The | 244 | The |
| 184 | .Fn rresvport | 245 | .Fn rresvport |
| 185 | function | 246 | and |
| 186 | returns a valid, bound socket descriptor on success. | 247 | .Fn rresvport_af |
| 248 | functions return a valid, bound socket descriptor on success. | ||
| 187 | It returns \-1 on error with the global value | 249 | It returns \-1 on error with the global value |
| 188 | .Va errno | 250 | .Va errno |
| 189 | set according to the reason for failure. | 251 | set according to the reason for failure. |
| 190 | The error code | 252 | The error code |
| 191 | .Dv EAGAIN | 253 | .Er EAGAIN |
| 192 | is overloaded to mean ``All network ports in use.'' | 254 | is overloaded to mean |
| 255 | .Dq all network ports in use . | ||
| 193 | .Sh SEE ALSO | 256 | .Sh SEE ALSO |
| 194 | .Xr rlogin 1 , | ||
| 195 | .Xr rsh 1 , | 257 | .Xr rsh 1 , |
| 196 | .Xr intro 2 , | 258 | .Xr intro 2 , |
| 197 | .Xr rexec 3 , | 259 | .Xr bindresvport 3 , |
| 198 | .Xr rexecd 8 , | 260 | .Xr bindresvport_sa 3 , |
| 199 | .Xr rlogind 8 , | 261 | .Xr rcmdsh 3 , |
| 200 | .Xr rshd 8 | 262 | .Xr rshd 8 |
| 201 | .Sh HISTORY | 263 | .Sh HISTORY |
| 202 | These | 264 | These |
| 203 | functions appeared in | 265 | functions appeared in |
| 204 | .Bx 4.2 . | 266 | .Bx 4.2 . |
diff --git a/src/lib/libc/net/rcmd.c b/src/lib/libc/net/rcmd.c index e0310031b0..d566e0ca4c 100644 --- a/src/lib/libc/net/rcmd.c +++ b/src/lib/libc/net/rcmd.c | |||
| @@ -1,6 +1,5 @@ | |||
| 1 | /* $NetBSD: rcmd.c,v 1.12 1995/06/03 22:33:34 mycroft Exp $ */ | ||
| 2 | |||
| 3 | /* | 1 | /* |
| 2 | * Copyright (c) 1995, 1996, 1998 Theo de Raadt. All rights reserved. | ||
| 4 | * Copyright (c) 1983, 1993, 1994 | 3 | * Copyright (c) 1983, 1993, 1994 |
| 5 | * The Regents of the University of California. All rights reserved. | 4 | * The Regents of the University of California. All rights reserved. |
| 6 | * | 5 | * |
| @@ -12,11 +11,7 @@ | |||
| 12 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
| 13 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the |
| 14 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. |
| 15 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. Neither the name of the University nor the names of its contributors |
| 16 | * must display the following acknowledgement: | ||
| 17 | * This product includes software developed by the University of | ||
| 18 | * California, Berkeley and its contributors. | ||
| 19 | * 4. Neither the name of the University nor the names of its contributors | ||
| 20 | * may be used to endorse or promote products derived from this software | 15 | * may be used to endorse or promote products derived from this software |
| 21 | * without specific prior written permission. | 16 | * without specific prior written permission. |
| 22 | * | 17 | * |
| @@ -33,14 +28,6 @@ | |||
| 33 | * SUCH DAMAGE. | 28 | * SUCH DAMAGE. |
| 34 | */ | 29 | */ |
| 35 | 30 | ||
| 36 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 37 | #if 0 | ||
| 38 | static char sccsid[] = "@(#)rcmd.c 8.3 (Berkeley) 3/26/94"; | ||
| 39 | #else | ||
| 40 | static char *rcsid = "$NetBSD: rcmd.c,v 1.12 1995/06/03 22:33:34 mycroft Exp $"; | ||
| 41 | #endif | ||
| 42 | #endif /* LIBC_SCCS and not lint */ | ||
| 43 | |||
| 44 | #include <sys/param.h> | 31 | #include <sys/param.h> |
| 45 | #include <sys/socket.h> | 32 | #include <sys/socket.h> |
| 46 | #include <sys/stat.h> | 33 | #include <sys/stat.h> |
| @@ -57,35 +44,77 @@ static char *rcsid = "$NetBSD: rcmd.c,v 1.12 1995/06/03 22:33:34 mycroft Exp $"; | |||
| 57 | #include <stdio.h> | 44 | #include <stdio.h> |
| 58 | #include <ctype.h> | 45 | #include <ctype.h> |
| 59 | #include <string.h> | 46 | #include <string.h> |
| 47 | #include <syslog.h> | ||
| 48 | #include <stdlib.h> | ||
| 60 | 49 | ||
| 61 | int __ivaliduser __P((FILE *, u_long, const char *, const char *)); | 50 | int |
| 62 | static int __icheckhost __P((u_long, const char *)); | 51 | rcmd(char **ahost, int rport, const char *locuser, const char *remuser, |
| 52 | const char *cmd, int *fd2p) | ||
| 53 | { | ||
| 54 | return rcmd_af(ahost, rport, locuser, remuser, cmd, fd2p, AF_INET); | ||
| 55 | } | ||
| 63 | 56 | ||
| 64 | int | 57 | int |
| 65 | rcmd(ahost, rport, locuser, remuser, cmd, fd2p) | 58 | rcmd_af(char **ahost, int porta, const char *locuser, const char *remuser, |
| 66 | char **ahost; | 59 | const char *cmd, int *fd2p, int af) |
| 67 | u_short rport; | ||
| 68 | const char *locuser, *remuser, *cmd; | ||
| 69 | int *fd2p; | ||
| 70 | { | 60 | { |
| 71 | struct hostent *hp; | 61 | static char hbuf[MAXHOSTNAMELEN]; |
| 72 | struct sockaddr_in sin, from; | 62 | char pbuf[NI_MAXSERV]; |
| 73 | fd_set reads; | 63 | struct addrinfo hints, *res, *r; |
| 74 | long oldmask; | 64 | int error; |
| 65 | struct sockaddr_storage from; | ||
| 66 | fd_set *readsp = NULL; | ||
| 67 | sigset_t oldmask, mask; | ||
| 75 | pid_t pid; | 68 | pid_t pid; |
| 76 | int s, lport, timo; | 69 | int s, lport, timo; |
| 77 | char c; | 70 | char c, *p; |
| 71 | int refused; | ||
| 72 | in_port_t rport = porta; | ||
| 73 | |||
| 74 | /* call rcmdsh() with specified remote shell if appropriate. */ | ||
| 75 | if (!issetugid() && (p = getenv("RSH")) && *p) { | ||
| 76 | struct servent *sp = getservbyname("shell", "tcp"); | ||
| 77 | |||
| 78 | if (sp && sp->s_port == rport) | ||
| 79 | return (rcmdsh(ahost, rport, locuser, remuser, | ||
| 80 | cmd, p)); | ||
| 81 | } | ||
| 82 | |||
| 83 | /* use rsh(1) if non-root and remote port is shell. */ | ||
| 84 | if (geteuid()) { | ||
| 85 | struct servent *sp = getservbyname("shell", "tcp"); | ||
| 86 | |||
| 87 | if (sp && sp->s_port == rport) | ||
| 88 | return (rcmdsh(ahost, rport, locuser, remuser, | ||
| 89 | cmd, NULL)); | ||
| 90 | } | ||
| 78 | 91 | ||
| 79 | pid = getpid(); | 92 | pid = getpid(); |
| 80 | hp = gethostbyname(*ahost); | 93 | snprintf(pbuf, sizeof(pbuf), "%u", ntohs(rport)); |
| 81 | if (hp == NULL) { | 94 | memset(&hints, 0, sizeof(hints)); |
| 82 | herror(*ahost); | 95 | hints.ai_family = af; |
| 96 | hints.ai_socktype = SOCK_STREAM; | ||
| 97 | hints.ai_flags = AI_CANONNAME; | ||
| 98 | error = getaddrinfo(*ahost, pbuf, &hints, &res); | ||
| 99 | if (error) { | ||
| 100 | #if 0 | ||
| 101 | warnx("%s: %s", *ahost, gai_strerror(error)); | ||
| 102 | #endif | ||
| 83 | return (-1); | 103 | return (-1); |
| 84 | } | 104 | } |
| 85 | *ahost = hp->h_name; | 105 | if (res->ai_canonname) { |
| 86 | oldmask = sigblock(sigmask(SIGURG)); | 106 | strlcpy(hbuf, res->ai_canonname, sizeof(hbuf)); |
| 107 | *ahost = hbuf; | ||
| 108 | } else | ||
| 109 | ; /*XXX*/ | ||
| 110 | |||
| 111 | r = res; | ||
| 112 | refused = 0; | ||
| 113 | sigemptyset(&mask); | ||
| 114 | sigaddset(&mask, SIGURG); | ||
| 115 | sigprocmask(SIG_BLOCK, &mask, &oldmask); | ||
| 87 | for (timo = 1, lport = IPPORT_RESERVED - 1;;) { | 116 | for (timo = 1, lport = IPPORT_RESERVED - 1;;) { |
| 88 | s = rresvport(&lport); | 117 | s = rresvport_af(&lport, r->ai_family); |
| 89 | if (s < 0) { | 118 | if (s < 0) { |
| 90 | if (errno == EAGAIN) | 119 | if (errno == EAGAIN) |
| 91 | (void)fprintf(stderr, | 120 | (void)fprintf(stderr, |
| @@ -93,54 +122,84 @@ rcmd(ahost, rport, locuser, remuser, cmd, fd2p) | |||
| 93 | else | 122 | else |
| 94 | (void)fprintf(stderr, "rcmd: socket: %s\n", | 123 | (void)fprintf(stderr, "rcmd: socket: %s\n", |
| 95 | strerror(errno)); | 124 | strerror(errno)); |
| 96 | sigsetmask(oldmask); | 125 | if (r->ai_next) { |
| 97 | return (-1); | 126 | r = r->ai_next; |
| 127 | continue; | ||
| 128 | } else { | ||
| 129 | sigprocmask(SIG_SETMASK, &oldmask, NULL); | ||
| 130 | freeaddrinfo(res); | ||
| 131 | return (-1); | ||
| 132 | } | ||
| 98 | } | 133 | } |
| 99 | fcntl(s, F_SETOWN, pid); | 134 | fcntl(s, F_SETOWN, pid); |
| 100 | sin.sin_len = sizeof(struct sockaddr_in); | 135 | if (connect(s, r->ai_addr, r->ai_addrlen) >= 0) |
| 101 | sin.sin_family = hp->h_addrtype; | ||
| 102 | sin.sin_port = rport; | ||
| 103 | bcopy(hp->h_addr_list[0], &sin.sin_addr, hp->h_length); | ||
| 104 | if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0) | ||
| 105 | break; | 136 | break; |
| 106 | (void)close(s); | 137 | (void)close(s); |
| 107 | if (errno == EADDRINUSE) { | 138 | if (errno == EADDRINUSE) { |
| 108 | lport--; | 139 | lport--; |
| 109 | continue; | 140 | continue; |
| 110 | } | 141 | } |
| 111 | if (errno == ECONNREFUSED && timo <= 16) { | 142 | if (errno == ECONNREFUSED) |
| 112 | (void)sleep(timo); | 143 | refused++; |
| 113 | timo *= 2; | 144 | if (r->ai_next) { |
| 114 | continue; | ||
| 115 | } | ||
| 116 | if (hp->h_addr_list[1] != NULL) { | ||
| 117 | int oerrno = errno; | 145 | int oerrno = errno; |
| 118 | 146 | char hbuf[NI_MAXHOST]; | |
| 119 | (void)fprintf(stderr, "connect to address %s: ", | 147 | const int niflags = NI_NUMERICHOST; |
| 120 | inet_ntoa(sin.sin_addr)); | 148 | |
| 149 | hbuf[0] = '\0'; | ||
| 150 | if (getnameinfo(r->ai_addr, r->ai_addrlen, | ||
| 151 | hbuf, sizeof(hbuf), NULL, 0, niflags) != 0) | ||
| 152 | strlcpy(hbuf, "(invalid)", sizeof hbuf); | ||
| 153 | (void)fprintf(stderr, "connect to address %s: ", hbuf); | ||
| 121 | errno = oerrno; | 154 | errno = oerrno; |
| 122 | perror(0); | 155 | perror(0); |
| 123 | hp->h_addr_list++; | 156 | r = r->ai_next; |
| 124 | bcopy(hp->h_addr_list[0], &sin.sin_addr, hp->h_length); | 157 | hbuf[0] = '\0'; |
| 125 | (void)fprintf(stderr, "Trying %s...\n", | 158 | if (getnameinfo(r->ai_addr, r->ai_addrlen, |
| 126 | inet_ntoa(sin.sin_addr)); | 159 | hbuf, sizeof(hbuf), NULL, 0, niflags) != 0) |
| 160 | strlcpy(hbuf, "(invalid)", sizeof hbuf); | ||
| 161 | (void)fprintf(stderr, "Trying %s...\n", hbuf); | ||
| 127 | continue; | 162 | continue; |
| 128 | } | 163 | } |
| 129 | (void)fprintf(stderr, "%s: %s\n", hp->h_name, strerror(errno)); | 164 | if (refused && timo <= 16) { |
| 130 | sigsetmask(oldmask); | 165 | (void)sleep(timo); |
| 166 | timo *= 2; | ||
| 167 | r = res; | ||
| 168 | refused = 0; | ||
| 169 | continue; | ||
| 170 | } | ||
| 171 | (void)fprintf(stderr, "%s: %s\n", res->ai_canonname, | ||
| 172 | strerror(errno)); | ||
| 173 | sigprocmask(SIG_SETMASK, &oldmask, NULL); | ||
| 174 | freeaddrinfo(res); | ||
| 131 | return (-1); | 175 | return (-1); |
| 132 | } | 176 | } |
| 177 | /* given "af" can be PF_UNSPEC, we need the real af for "s" */ | ||
| 178 | af = r->ai_family; | ||
| 179 | freeaddrinfo(res); | ||
| 180 | #if 0 | ||
| 181 | /* | ||
| 182 | * try to rresvport() to the same port. This will make rresvport() | ||
| 183 | * fail it's first bind, resulting in it choosing a random port. | ||
| 184 | */ | ||
| 133 | lport--; | 185 | lport--; |
| 186 | #endif | ||
| 134 | if (fd2p == 0) { | 187 | if (fd2p == 0) { |
| 135 | write(s, "", 1); | 188 | write(s, "", 1); |
| 136 | lport = 0; | 189 | lport = 0; |
| 137 | } else { | 190 | } else { |
| 138 | char num[8]; | 191 | char num[8]; |
| 139 | int s2 = rresvport(&lport), s3; | 192 | int s2 = rresvport_af(&lport, af), s3; |
| 140 | int len = sizeof(from); | 193 | socklen_t len = sizeof(from); |
| 194 | int fdssize = howmany(MAX(s, s2)+1, NFDBITS) * sizeof(fd_mask); | ||
| 141 | 195 | ||
| 142 | if (s2 < 0) | 196 | if (s2 < 0) |
| 143 | goto bad; | 197 | goto bad; |
| 198 | readsp = (fd_set *)malloc(fdssize); | ||
| 199 | if (readsp == NULL) { | ||
| 200 | close(s2); | ||
| 201 | goto bad; | ||
| 202 | } | ||
| 144 | listen(s2, 1); | 203 | listen(s2, 1); |
| 145 | (void)snprintf(num, sizeof(num), "%d", lport); | 204 | (void)snprintf(num, sizeof(num), "%d", lport); |
| 146 | if (write(s, num, strlen(num)+1) != strlen(num)+1) { | 205 | if (write(s, num, strlen(num)+1) != strlen(num)+1) { |
| @@ -150,12 +209,13 @@ rcmd(ahost, rport, locuser, remuser, cmd, fd2p) | |||
| 150 | (void)close(s2); | 209 | (void)close(s2); |
| 151 | goto bad; | 210 | goto bad; |
| 152 | } | 211 | } |
| 153 | FD_ZERO(&reads); | 212 | again: |
| 154 | FD_SET(s, &reads); | 213 | bzero(readsp, fdssize); |
| 155 | FD_SET(s2, &reads); | 214 | FD_SET(s, readsp); |
| 215 | FD_SET(s2, readsp); | ||
| 156 | errno = 0; | 216 | errno = 0; |
| 157 | if (select(MAX(s, s2) + 1, &reads, 0, 0, 0) < 1 || | 217 | if (select(MAX(s, s2) + 1, readsp, 0, 0, 0) < 1 || |
| 158 | !FD_ISSET(s2, &reads)) { | 218 | !FD_ISSET(s2, readsp)) { |
| 159 | if (errno != 0) | 219 | if (errno != 0) |
| 160 | (void)fprintf(stderr, | 220 | (void)fprintf(stderr, |
| 161 | "rcmd: select (setting up stderr): %s\n", | 221 | "rcmd: select (setting up stderr): %s\n", |
| @@ -167,21 +227,48 @@ rcmd(ahost, rport, locuser, remuser, cmd, fd2p) | |||
| 167 | goto bad; | 227 | goto bad; |
| 168 | } | 228 | } |
| 169 | s3 = accept(s2, (struct sockaddr *)&from, &len); | 229 | s3 = accept(s2, (struct sockaddr *)&from, &len); |
| 170 | (void)close(s2); | ||
| 171 | if (s3 < 0) { | 230 | if (s3 < 0) { |
| 172 | (void)fprintf(stderr, | 231 | (void)fprintf(stderr, |
| 173 | "rcmd: accept: %s\n", strerror(errno)); | 232 | "rcmd: accept: %s\n", strerror(errno)); |
| 174 | lport = 0; | 233 | lport = 0; |
| 234 | close(s2); | ||
| 175 | goto bad; | 235 | goto bad; |
| 176 | } | 236 | } |
| 237 | |||
| 238 | /* | ||
| 239 | * XXX careful for ftp bounce attacks. If discovered, shut them | ||
| 240 | * down and check for the real auxiliary channel to connect. | ||
| 241 | */ | ||
| 242 | switch (from.ss_family) { | ||
| 243 | case AF_INET: | ||
| 244 | case AF_INET6: | ||
| 245 | if (getnameinfo((struct sockaddr *)&from, len, | ||
| 246 | NULL, 0, num, sizeof(num), NI_NUMERICSERV) == 0 && | ||
| 247 | atoi(num) != 20) { | ||
| 248 | break; | ||
| 249 | } | ||
| 250 | close(s3); | ||
| 251 | goto again; | ||
| 252 | default: | ||
| 253 | break; | ||
| 254 | } | ||
| 255 | (void)close(s2); | ||
| 256 | |||
| 177 | *fd2p = s3; | 257 | *fd2p = s3; |
| 178 | from.sin_port = ntohs(from.sin_port); | 258 | switch (from.ss_family) { |
| 179 | if (from.sin_family != AF_INET || | 259 | case AF_INET: |
| 180 | from.sin_port >= IPPORT_RESERVED || | 260 | case AF_INET6: |
| 181 | from.sin_port < IPPORT_RESERVED / 2) { | 261 | if (getnameinfo((struct sockaddr *)&from, len, |
| 182 | (void)fprintf(stderr, | 262 | NULL, 0, num, sizeof(num), NI_NUMERICSERV) != 0 || |
| 183 | "socket: protocol failure in circuit setup.\n"); | 263 | (atoi(num) >= IPPORT_RESERVED || |
| 184 | goto bad2; | 264 | atoi(num) < IPPORT_RESERVED / 2)) { |
| 265 | (void)fprintf(stderr, | ||
| 266 | "socket: protocol failure in circuit setup.\n"); | ||
| 267 | goto bad2; | ||
| 268 | } | ||
| 269 | break; | ||
| 270 | default: | ||
| 271 | break; | ||
| 185 | } | 272 | } |
| 186 | } | 273 | } |
| 187 | (void)write(s, locuser, strlen(locuser)+1); | 274 | (void)write(s, locuser, strlen(locuser)+1); |
| @@ -200,318 +287,17 @@ rcmd(ahost, rport, locuser, remuser, cmd, fd2p) | |||
| 200 | } | 287 | } |
| 201 | goto bad2; | 288 | goto bad2; |
| 202 | } | 289 | } |
| 203 | sigsetmask(oldmask); | 290 | sigprocmask(SIG_SETMASK, &oldmask, NULL); |
| 291 | free(readsp); | ||
| 204 | return (s); | 292 | return (s); |
| 205 | bad2: | 293 | bad2: |
| 206 | if (lport) | 294 | if (lport) |
| 207 | (void)close(*fd2p); | 295 | (void)close(*fd2p); |
| 208 | bad: | 296 | bad: |
| 297 | if (readsp) | ||
| 298 | free(readsp); | ||
| 209 | (void)close(s); | 299 | (void)close(s); |
| 210 | sigsetmask(oldmask); | 300 | sigprocmask(SIG_SETMASK, &oldmask, NULL); |
| 211 | return (-1); | ||
| 212 | } | ||
| 213 | |||
| 214 | int | ||
| 215 | rresvport(alport) | ||
| 216 | int *alport; | ||
| 217 | { | ||
| 218 | struct sockaddr_in sin; | ||
| 219 | int s; | ||
| 220 | |||
| 221 | sin.sin_len = sizeof(struct sockaddr_in); | ||
| 222 | sin.sin_family = AF_INET; | ||
| 223 | sin.sin_addr.s_addr = INADDR_ANY; | ||
| 224 | s = socket(AF_INET, SOCK_STREAM, 0); | ||
| 225 | if (s < 0) | ||
| 226 | return (-1); | ||
| 227 | for (;;) { | ||
| 228 | sin.sin_port = htons((u_short)*alport); | ||
| 229 | if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0) | ||
| 230 | return (s); | ||
| 231 | if (errno != EADDRINUSE) { | ||
| 232 | (void)close(s); | ||
| 233 | return (-1); | ||
| 234 | } | ||
| 235 | (*alport)--; | ||
| 236 | if (*alport == IPPORT_RESERVED/2) { | ||
| 237 | (void)close(s); | ||
| 238 | errno = EAGAIN; /* close */ | ||
| 239 | return (-1); | ||
| 240 | } | ||
| 241 | } | ||
| 242 | } | ||
| 243 | |||
| 244 | int __check_rhosts_file = 1; | ||
| 245 | char *__rcmd_errstr; | ||
| 246 | |||
| 247 | int | ||
| 248 | ruserok(rhost, superuser, ruser, luser) | ||
| 249 | const char *rhost, *ruser, *luser; | ||
| 250 | int superuser; | ||
| 251 | { | ||
| 252 | struct hostent *hp; | ||
| 253 | char **ap; | ||
| 254 | int i; | ||
| 255 | #define MAXADDRS 35 | ||
| 256 | u_long addrs[MAXADDRS + 1]; | ||
| 257 | |||
| 258 | if ((hp = gethostbyname(rhost)) == NULL) | ||
| 259 | return (-1); | ||
| 260 | for (i = 0, ap = hp->h_addr_list; *ap && i < MAXADDRS; ++ap, ++i) | ||
| 261 | bcopy(*ap, &addrs[i], sizeof(addrs[i])); | ||
| 262 | addrs[i] = 0; | ||
| 263 | |||
| 264 | for (i = 0; i < MAXADDRS && addrs[i]; i++) | ||
| 265 | if (iruserok(addrs[i], superuser, ruser, luser) == 0) | ||
| 266 | return (0); | ||
| 267 | return (-1); | ||
| 268 | } | ||
| 269 | |||
| 270 | /* | ||
| 271 | * New .rhosts strategy: We are passed an ip address. We spin through | ||
| 272 | * hosts.equiv and .rhosts looking for a match. When the .rhosts only | ||
| 273 | * has ip addresses, we don't have to trust a nameserver. When it | ||
| 274 | * contains hostnames, we spin through the list of addresses the nameserver | ||
| 275 | * gives us and look for a match. | ||
| 276 | * | ||
| 277 | * Returns 0 if ok, -1 if not ok. | ||
| 278 | */ | ||
| 279 | int | ||
| 280 | iruserok(raddr, superuser, ruser, luser) | ||
| 281 | u_long raddr; | ||
| 282 | int superuser; | ||
| 283 | const char *ruser, *luser; | ||
| 284 | { | ||
| 285 | register char *cp; | ||
| 286 | struct stat sbuf; | ||
| 287 | struct passwd *pwd; | ||
| 288 | FILE *hostf; | ||
| 289 | uid_t uid; | ||
| 290 | int first; | ||
| 291 | char pbuf[MAXPATHLEN]; | ||
| 292 | |||
| 293 | first = 1; | ||
| 294 | hostf = superuser ? NULL : fopen(_PATH_HEQUIV, "r"); | ||
| 295 | again: | ||
| 296 | if (hostf) { | ||
| 297 | if (__ivaliduser(hostf, raddr, luser, ruser) == 0) { | ||
| 298 | (void)fclose(hostf); | ||
| 299 | return (0); | ||
| 300 | } | ||
| 301 | (void)fclose(hostf); | ||
| 302 | } | ||
| 303 | if (first == 1 && (__check_rhosts_file || superuser)) { | ||
| 304 | first = 0; | ||
| 305 | if ((pwd = getpwnam(luser)) == NULL) | ||
| 306 | return (-1); | ||
| 307 | (void)strcpy(pbuf, pwd->pw_dir); | ||
| 308 | (void)strcat(pbuf, "/.rhosts"); | ||
| 309 | |||
| 310 | /* | ||
| 311 | * Change effective uid while opening .rhosts. If root and | ||
| 312 | * reading an NFS mounted file system, can't read files that | ||
| 313 | * are protected read/write owner only. | ||
| 314 | */ | ||
| 315 | uid = geteuid(); | ||
| 316 | (void)seteuid(pwd->pw_uid); | ||
| 317 | hostf = fopen(pbuf, "r"); | ||
| 318 | (void)seteuid(uid); | ||
| 319 | |||
| 320 | if (hostf == NULL) | ||
| 321 | return (-1); | ||
| 322 | /* | ||
| 323 | * If not a regular file, or is owned by someone other than | ||
| 324 | * user or root or if writeable by anyone but the owner, quit. | ||
| 325 | */ | ||
| 326 | cp = NULL; | ||
| 327 | if (lstat(pbuf, &sbuf) < 0) | ||
| 328 | cp = ".rhosts lstat failed"; | ||
| 329 | else if (!S_ISREG(sbuf.st_mode)) | ||
| 330 | cp = ".rhosts not regular file"; | ||
| 331 | else if (fstat(fileno(hostf), &sbuf) < 0) | ||
| 332 | cp = ".rhosts fstat failed"; | ||
| 333 | else if (sbuf.st_uid && sbuf.st_uid != pwd->pw_uid) | ||
| 334 | cp = "bad .rhosts owner"; | ||
| 335 | else if (sbuf.st_mode & (S_IWGRP|S_IWOTH)) | ||
| 336 | cp = ".rhosts writeable by other than owner"; | ||
| 337 | /* If there were any problems, quit. */ | ||
| 338 | if (cp) { | ||
| 339 | __rcmd_errstr = cp; | ||
| 340 | (void)fclose(hostf); | ||
| 341 | return (-1); | ||
| 342 | } | ||
| 343 | goto again; | ||
| 344 | } | ||
| 345 | return (-1); | 301 | return (-1); |
| 346 | } | 302 | } |
| 347 | 303 | ||
| 348 | /* | ||
| 349 | * XXX | ||
| 350 | * Don't make static, used by lpd(8). | ||
| 351 | * | ||
| 352 | * Returns 0 if ok, -1 if not ok. | ||
| 353 | */ | ||
| 354 | int | ||
| 355 | __ivaliduser(hostf, raddr, luser, ruser) | ||
| 356 | FILE *hostf; | ||
| 357 | u_long raddr; | ||
| 358 | const char *luser, *ruser; | ||
| 359 | { | ||
| 360 | register char *user, *p; | ||
| 361 | int ch; | ||
| 362 | char buf[MAXHOSTNAMELEN + 128]; /* host + login */ | ||
| 363 | const char *auser, *ahost; | ||
| 364 | int hostok, userok; | ||
| 365 | char rhost[MAXHOSTNAMELEN]; | ||
| 366 | struct hostent *hp; | ||
| 367 | char domain[MAXHOSTNAMELEN]; | ||
| 368 | |||
| 369 | getdomainname(domain, sizeof(domain)); | ||
| 370 | |||
| 371 | while (fgets(buf, sizeof(buf), hostf)) { | ||
| 372 | p = buf; | ||
| 373 | /* Skip lines that are too long. */ | ||
| 374 | if (strchr(p, '\n') == NULL) { | ||
| 375 | while ((ch = getc(hostf)) != '\n' && ch != EOF); | ||
| 376 | continue; | ||
| 377 | } | ||
| 378 | while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') { | ||
| 379 | *p = isupper(*p) ? tolower(*p) : *p; | ||
| 380 | p++; | ||
| 381 | } | ||
| 382 | if (*p == ' ' || *p == '\t') { | ||
| 383 | *p++ = '\0'; | ||
| 384 | while (*p == ' ' || *p == '\t') | ||
| 385 | p++; | ||
| 386 | user = p; | ||
| 387 | while (*p != '\n' && *p != ' ' && | ||
| 388 | *p != '\t' && *p != '\0') | ||
| 389 | p++; | ||
| 390 | } else | ||
| 391 | user = p; | ||
| 392 | *p = '\0'; | ||
| 393 | |||
| 394 | if (p == buf) | ||
| 395 | continue; | ||
| 396 | |||
| 397 | auser = *user ? user : luser; | ||
| 398 | ahost = buf; | ||
| 399 | |||
| 400 | if ((hp = gethostbyaddr((char *) &raddr, | ||
| 401 | sizeof(raddr), AF_INET)) == NULL) { | ||
| 402 | abort(); | ||
| 403 | return -1; | ||
| 404 | } | ||
| 405 | (void) strncpy(rhost, hp->h_name, sizeof(rhost)); | ||
| 406 | rhost[sizeof(rhost) - 1] = '\0'; | ||
| 407 | |||
| 408 | if (ahost[0] == '+') | ||
| 409 | switch (ahost[1]) { | ||
| 410 | case '\0': | ||
| 411 | hostok = 1; | ||
| 412 | break; | ||
| 413 | |||
| 414 | case '@': | ||
| 415 | hostok = innetgr(&ahost[2], rhost, NULL, | ||
| 416 | domain); | ||
| 417 | break; | ||
| 418 | |||
| 419 | default: | ||
| 420 | hostok = __icheckhost(raddr, &ahost[1]); | ||
| 421 | break; | ||
| 422 | } | ||
| 423 | else if (ahost[0] == '-') | ||
| 424 | switch (ahost[1]) { | ||
| 425 | case '\0': | ||
| 426 | hostok = -1; | ||
| 427 | break; | ||
| 428 | |||
| 429 | case '@': | ||
| 430 | hostok = -innetgr(&ahost[2], rhost, NULL, | ||
| 431 | domain); | ||
| 432 | break; | ||
| 433 | |||
| 434 | default: | ||
| 435 | hostok = -__icheckhost(raddr, &ahost[1]); | ||
| 436 | break; | ||
| 437 | } | ||
| 438 | else | ||
| 439 | hostok = __icheckhost(raddr, ahost); | ||
| 440 | |||
| 441 | |||
| 442 | if (auser[0] == '+') | ||
| 443 | switch (auser[1]) { | ||
| 444 | case '\0': | ||
| 445 | userok = 1; | ||
| 446 | break; | ||
| 447 | |||
| 448 | case '@': | ||
| 449 | userok = innetgr(&auser[2], NULL, ruser, | ||
| 450 | domain); | ||
| 451 | break; | ||
| 452 | |||
| 453 | default: | ||
| 454 | userok = strcmp(ruser, &auser[1]) == 0; | ||
| 455 | break; | ||
| 456 | } | ||
| 457 | else if (auser[0] == '-') | ||
| 458 | switch (auser[1]) { | ||
| 459 | case '\0': | ||
| 460 | userok = -1; | ||
| 461 | break; | ||
| 462 | |||
| 463 | case '@': | ||
| 464 | userok = -innetgr(&auser[2], NULL, ruser, | ||
| 465 | domain); | ||
| 466 | break; | ||
| 467 | |||
| 468 | default: | ||
| 469 | userok = -(strcmp(ruser, &auser[1]) == 0); | ||
| 470 | break; | ||
| 471 | } | ||
| 472 | else | ||
| 473 | userok = strcmp(ruser, auser) == 0; | ||
| 474 | |||
| 475 | /* Check if one component did not match */ | ||
| 476 | if (hostok == 0 || userok == 0) | ||
| 477 | continue; | ||
| 478 | |||
| 479 | /* Check if we got a forbidden pair */ | ||
| 480 | if (userok == -1 || hostok == -1) | ||
| 481 | return -1; | ||
| 482 | |||
| 483 | /* Check if we got a valid pair */ | ||
| 484 | if (hostok == 1 && userok == 1) | ||
| 485 | return 0; | ||
| 486 | } | ||
| 487 | return -1; | ||
| 488 | } | ||
| 489 | |||
| 490 | /* | ||
| 491 | * Returns "true" if match, 0 if no match. | ||
| 492 | */ | ||
| 493 | static int | ||
| 494 | __icheckhost(raddr, lhost) | ||
| 495 | u_long raddr; | ||
| 496 | const char *lhost; | ||
| 497 | { | ||
| 498 | register struct hostent *hp; | ||
| 499 | register u_long laddr; | ||
| 500 | register char **pp; | ||
| 501 | |||
| 502 | /* Try for raw ip address first. */ | ||
| 503 | if (isdigit(*lhost) && (long)(laddr = inet_addr(lhost)) != -1) | ||
| 504 | return (raddr == laddr); | ||
| 505 | |||
| 506 | /* Better be a hostname. */ | ||
| 507 | if ((hp = gethostbyname(lhost)) == NULL) | ||
| 508 | return (0); | ||
| 509 | |||
| 510 | /* Spin through ip addresses. */ | ||
| 511 | for (pp = hp->h_addr_list; *pp; ++pp) | ||
| 512 | if (!bcmp(&raddr, *pp, sizeof(u_long))) | ||
| 513 | return (1); | ||
| 514 | |||
| 515 | /* No match. */ | ||
| 516 | return (0); | ||
| 517 | } | ||
diff --git a/src/lib/libc/net/rcmdsh.3 b/src/lib/libc/net/rcmdsh.3 new file mode 100644 index 0000000000..c84a2e4d93 --- /dev/null +++ b/src/lib/libc/net/rcmdsh.3 | |||
| @@ -0,0 +1,96 @@ | |||
| 1 | .\" $OpenBSD: rcmdsh.3,v 1.14 2013/06/05 03:39:23 tedu Exp $ | ||
| 2 | .\" | ||
| 3 | .\" Copyright (c) 1983, 1991, 1993 | ||
| 4 | .\" The Regents of the University of California. All rights reserved. | ||
| 5 | .\" | ||
| 6 | .\" Redistribution and use in source and binary forms, with or without | ||
| 7 | .\" modification, are permitted provided that the following conditions | ||
| 8 | .\" are met: | ||
| 9 | .\" 1. Redistributions of source code must retain the above copyright | ||
| 10 | .\" notice, this list of conditions and the following disclaimer. | ||
| 11 | .\" 2. Redistributions in binary form must reproduce the above copyright | ||
| 12 | .\" notice, this list of conditions and the following disclaimer in the | ||
| 13 | .\" documentation and/or other materials provided with the distribution. | ||
| 14 | .\" 3. Neither the name of the University nor the names of its contributors | ||
| 15 | .\" may be used to endorse or promote products derived from this software | ||
| 16 | .\" without specific prior written permission. | ||
| 17 | .\" | ||
| 18 | .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
| 19 | .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 20 | .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 21 | .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
| 22 | .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 23 | .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 24 | .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 25 | .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 26 | .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 27 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 28 | .\" SUCH DAMAGE. | ||
| 29 | .\" | ||
| 30 | .Dd $Mdocdate: June 5 2013 $ | ||
| 31 | .Dt RCMDSH 3 | ||
| 32 | .Os | ||
| 33 | .Sh NAME | ||
| 34 | .Nm rcmdsh | ||
| 35 | .Nd return a stream to a remote command without superuser | ||
| 36 | .Sh SYNOPSIS | ||
| 37 | .In unistd.h | ||
| 38 | .Ft int | ||
| 39 | .Fn rcmdsh "char **ahost" "int inport" "const char *locuser" "const char *remuser" "const char *cmd" "char *rshprog" | ||
| 40 | .Sh DESCRIPTION | ||
| 41 | The | ||
| 42 | .Fn rcmdsh | ||
| 43 | function is used by normal users to execute a command on a remote machine | ||
| 44 | using an authentication scheme based on reserved port numbers using | ||
| 45 | .Xr rsh 1 | ||
| 46 | or the value of | ||
| 47 | .Fa rshprog | ||
| 48 | (if non-null). | ||
| 49 | .Fa rshprog | ||
| 50 | may be a fully-qualified path, a non-qualified command, or a command containing | ||
| 51 | space-separated command line arguments. | ||
| 52 | .Pp | ||
| 53 | The | ||
| 54 | .Fn rcmdsh | ||
| 55 | function looks up the host | ||
| 56 | .Fa *ahost | ||
| 57 | using | ||
| 58 | .Xr gethostbyname 3 , | ||
| 59 | returning \-1 if the host does not exist. | ||
| 60 | Otherwise | ||
| 61 | .Fa *ahost | ||
| 62 | is set to the standard name of the host and a connection is established to | ||
| 63 | a server residing at the well-known Internet port | ||
| 64 | .Li shell/tcp | ||
| 65 | (or whatever port is used by | ||
| 66 | .Fa rshprog ) . | ||
| 67 | The parameter | ||
| 68 | .Fa inport | ||
| 69 | is ignored; it is only included to provide an interface similar to | ||
| 70 | .Xr rcmd 3 . | ||
| 71 | .Pp | ||
| 72 | If the connection succeeds, a socket in the | ||
| 73 | .Ux Ns -domain | ||
| 74 | of type | ||
| 75 | .Dv SOCK_STREAM | ||
| 76 | is returned to the caller, and given to the remote | ||
| 77 | command as stdin and stdout, and stderr. | ||
| 78 | .Sh DIAGNOSTICS | ||
| 79 | The | ||
| 80 | .Fn rcmdsh | ||
| 81 | function returns a valid socket descriptor on success. | ||
| 82 | It returns \-1 on error and prints a diagnostic message on the standard error. | ||
| 83 | .Sh SEE ALSO | ||
| 84 | .Xr rsh 1 , | ||
| 85 | .Xr socketpair 2 , | ||
| 86 | .Xr rcmd 3 , | ||
| 87 | .Xr rshd 8 | ||
| 88 | .Sh HISTORY | ||
| 89 | The | ||
| 90 | .Fn rcmdsh | ||
| 91 | function first appeared in | ||
| 92 | .Ox 2.0 . | ||
| 93 | .Sh BUGS | ||
| 94 | If | ||
| 95 | .Xr rsh 1 | ||
| 96 | encounters an error, a file descriptor is still returned instead of \-1. | ||
diff --git a/src/lib/libc/net/rcmdsh.c b/src/lib/libc/net/rcmdsh.c new file mode 100644 index 0000000000..a472162711 --- /dev/null +++ b/src/lib/libc/net/rcmdsh.c | |||
| @@ -0,0 +1,186 @@ | |||
| 1 | /* $OpenBSD: rcmdsh.c,v 1.12 2007/09/02 15:19:17 deraadt Exp $ */ | ||
| 2 | |||
| 3 | /* | ||
| 4 | * Copyright (c) 2001, MagniComp | ||
| 5 | * All rights reserved. | ||
| 6 | * | ||
| 7 | * Redistribution and use in source and binary forms, with or without | ||
| 8 | * modification, are permitted provided that the following conditions | ||
| 9 | * are met: | ||
| 10 | * 1. Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 13 | * notice, this list of conditions and the following disclaimer in | ||
| 14 | * the documentation and/or other materials provided with the distribution. | ||
| 15 | * 3. Neither the name of the MagniComp nor the names of its contributors may | ||
| 16 | * be used to endorse or promote products derived from this software | ||
| 17 | * without specific prior written permission. | ||
| 18 | * | ||
| 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
| 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR | ||
| 23 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||
| 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | ||
| 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE | ||
| 28 | * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 29 | */ | ||
| 30 | |||
| 31 | /* | ||
| 32 | * This is an rcmd() replacement originally by | ||
| 33 | * Chris Siebenmann <cks@utcc.utoronto.ca>. | ||
| 34 | */ | ||
| 35 | |||
| 36 | #include <sys/types.h> | ||
| 37 | #include <sys/socket.h> | ||
| 38 | #include <sys/wait.h> | ||
| 39 | #include <signal.h> | ||
| 40 | #include <errno.h> | ||
| 41 | #include <netdb.h> | ||
| 42 | #include <stdio.h> | ||
| 43 | #include <stdlib.h> | ||
| 44 | #include <string.h> | ||
| 45 | #include <pwd.h> | ||
| 46 | #include <paths.h> | ||
| 47 | #include <unistd.h> | ||
| 48 | |||
| 49 | /* | ||
| 50 | * This is a replacement rcmd() function that uses the rsh(1) | ||
| 51 | * program in place of a direct rcmd(3) function call so as to | ||
| 52 | * avoid having to be root. Note that rport is ignored. | ||
| 53 | */ | ||
| 54 | /* ARGSUSED */ | ||
| 55 | int | ||
| 56 | rcmdsh(char **ahost, int rport, const char *locuser, const char *remuser, | ||
| 57 | const char *cmd, char *rshprog) | ||
| 58 | { | ||
| 59 | struct hostent *hp; | ||
| 60 | int sp[2]; | ||
| 61 | pid_t cpid; | ||
| 62 | char *p; | ||
| 63 | struct passwd *pw; | ||
| 64 | |||
| 65 | /* What rsh/shell to use. */ | ||
| 66 | if (rshprog == NULL) | ||
| 67 | rshprog = _PATH_RSH; | ||
| 68 | |||
| 69 | /* locuser must exist on this host. */ | ||
| 70 | if ((pw = getpwnam(locuser)) == NULL) { | ||
| 71 | (void) fprintf(stderr, "rcmdsh: unknown user: %s\n", locuser); | ||
| 72 | return(-1); | ||
| 73 | } | ||
| 74 | |||
| 75 | /* Validate remote hostname. */ | ||
| 76 | if (strcmp(*ahost, "localhost") != 0) { | ||
| 77 | if (((hp = gethostbyname2(*ahost, AF_INET)) == NULL) && | ||
| 78 | ((hp = gethostbyname2(*ahost, AF_INET6)) == NULL)) { | ||
| 79 | herror(*ahost); | ||
| 80 | return(-1); | ||
| 81 | } | ||
| 82 | *ahost = hp->h_name; | ||
| 83 | } | ||
| 84 | |||
| 85 | /* Get a socketpair we'll use for stdin and stdout. */ | ||
| 86 | if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, sp) < 0) { | ||
| 87 | perror("rcmdsh: socketpair"); | ||
| 88 | return(-1); | ||
| 89 | } | ||
| 90 | |||
| 91 | cpid = fork(); | ||
| 92 | if (cpid < 0) { | ||
| 93 | perror("rcmdsh: fork failed"); | ||
| 94 | return(-1); | ||
| 95 | } else if (cpid == 0) { | ||
| 96 | /* | ||
| 97 | * Child. We use sp[1] to be stdin/stdout, and close sp[0]. | ||
| 98 | */ | ||
| 99 | (void) close(sp[0]); | ||
| 100 | if (dup2(sp[1], 0) < 0 || dup2(0, 1) < 0) { | ||
| 101 | perror("rcmdsh: dup2 failed"); | ||
| 102 | _exit(255); | ||
| 103 | } | ||
| 104 | /* Fork again to lose parent. */ | ||
| 105 | cpid = fork(); | ||
| 106 | if (cpid < 0) { | ||
| 107 | perror("rcmdsh: fork to lose parent failed"); | ||
| 108 | _exit(255); | ||
| 109 | } | ||
| 110 | if (cpid > 0) | ||
| 111 | _exit(0); | ||
| 112 | |||
| 113 | /* In grandchild here. Become local user for rshprog. */ | ||
| 114 | if (setuid(pw->pw_uid)) { | ||
| 115 | (void) fprintf(stderr, "rcmdsh: setuid(%u): %s\n", | ||
| 116 | pw->pw_uid, strerror(errno)); | ||
| 117 | _exit(255); | ||
| 118 | } | ||
| 119 | |||
| 120 | /* | ||
| 121 | * If remote host is "localhost" and local and remote user | ||
| 122 | * are the same, avoid running remote shell for efficiency. | ||
| 123 | */ | ||
| 124 | if (!strcmp(*ahost, "localhost") && !strcmp(locuser, remuser)) { | ||
| 125 | char *argv[4]; | ||
| 126 | if (pw->pw_shell[0] == '\0') | ||
| 127 | rshprog = _PATH_BSHELL; | ||
| 128 | else | ||
| 129 | rshprog = pw->pw_shell; | ||
| 130 | p = strrchr(rshprog, '/'); | ||
| 131 | argv[0] = p ? p + 1 : rshprog; | ||
| 132 | argv[1] = "-c"; | ||
| 133 | argv[2] = (char *)cmd; | ||
| 134 | argv[3] = NULL; | ||
| 135 | execvp(rshprog, argv); | ||
| 136 | } else if ((p = strchr(rshprog, ' ')) == NULL) { | ||
| 137 | /* simple case */ | ||
| 138 | char *argv[6]; | ||
| 139 | p = strrchr(rshprog, '/'); | ||
| 140 | argv[0] = p ? p + 1 : rshprog; | ||
| 141 | argv[1] = "-l"; | ||
| 142 | argv[2] = (char *)remuser; | ||
| 143 | argv[3] = *ahost; | ||
| 144 | argv[4] = (char *)cmd; | ||
| 145 | argv[5] = NULL; | ||
| 146 | execvp(rshprog, argv); | ||
| 147 | } else { | ||
| 148 | /* must pull args out of rshprog and dyn alloc argv */ | ||
| 149 | char **argv, **ap; | ||
| 150 | int n; | ||
| 151 | for (n = 7; (p = strchr(++p, ' ')) != NULL; n++) | ||
| 152 | continue; | ||
| 153 | rshprog = strdup(rshprog); | ||
| 154 | ap = argv = calloc(sizeof(char *), n); | ||
| 155 | if (rshprog == NULL || argv == NULL) { | ||
| 156 | perror("rcmdsh"); | ||
| 157 | _exit(255); | ||
| 158 | } | ||
| 159 | while ((p = strsep(&rshprog, " ")) != NULL) { | ||
| 160 | if (*p == '\0') | ||
| 161 | continue; | ||
| 162 | *ap++ = p; | ||
| 163 | } | ||
| 164 | if (ap != argv) /* all spaces?!? */ | ||
| 165 | rshprog = argv[0]; | ||
| 166 | if ((p = strrchr(argv[0], '/')) != NULL) | ||
| 167 | argv[0] = p + 1; | ||
| 168 | *ap++ = "-l"; | ||
| 169 | *ap++ = (char *)remuser; | ||
| 170 | *ap++ = *ahost; | ||
| 171 | *ap++ = (char *)cmd; | ||
| 172 | *ap++ = NULL; | ||
| 173 | execvp(rshprog, argv); | ||
| 174 | } | ||
| 175 | (void) fprintf(stderr, "rcmdsh: execvp %s failed: %s\n", | ||
| 176 | rshprog, strerror(errno)); | ||
| 177 | _exit(255); | ||
| 178 | } else { | ||
| 179 | /* Parent. close sp[1], return sp[0]. */ | ||
| 180 | (void) close(sp[1]); | ||
| 181 | /* Reap child. */ | ||
| 182 | (void) wait(NULL); | ||
| 183 | return(sp[0]); | ||
| 184 | } | ||
| 185 | /* NOTREACHED */ | ||
| 186 | } | ||
diff --git a/src/lib/libc/net/recv.c b/src/lib/libc/net/recv.c index 44296378cb..6241cc6b12 100644 --- a/src/lib/libc/net/recv.c +++ b/src/lib/libc/net/recv.c | |||
| @@ -1,5 +1,4 @@ | |||
| 1 | /* $NetBSD: recv.c,v 1.6 1995/02/25 06:20:54 cgd Exp $ */ | 1 | /* $OpenBSD: recv.c,v 1.5 2005/08/06 20:30:03 espie Exp $ */ |
| 2 | |||
| 3 | /* | 2 | /* |
| 4 | * Copyright (c) 1988, 1993 | 3 | * Copyright (c) 1988, 1993 |
| 5 | * The Regents of the University of California. All rights reserved. | 4 | * The Regents of the University of California. All rights reserved. |
| @@ -12,11 +11,7 @@ | |||
| 12 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
| 13 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the |
| 14 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. |
| 15 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. Neither the name of the University nor the names of its contributors |
| 16 | * must display the following acknowledgement: | ||
| 17 | * This product includes software developed by the University of | ||
| 18 | * California, Berkeley and its contributors. | ||
| 19 | * 4. Neither the name of the University nor the names of its contributors | ||
| 20 | * may be used to endorse or promote products derived from this software | 15 | * may be used to endorse or promote products derived from this software |
| 21 | * without specific prior written permission. | 16 | * without specific prior written permission. |
| 22 | * | 17 | * |
| @@ -33,24 +28,13 @@ | |||
| 33 | * SUCH DAMAGE. | 28 | * SUCH DAMAGE. |
| 34 | */ | 29 | */ |
| 35 | 30 | ||
| 36 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 37 | #if 0 | ||
| 38 | static char sccsid[] = "@(#)recv.c 8.2 (Berkeley) 2/21/94"; | ||
| 39 | #else | ||
| 40 | static char rcsid[] = "$NetBSD: recv.c,v 1.6 1995/02/25 06:20:54 cgd Exp $"; | ||
| 41 | #endif | ||
| 42 | #endif /* LIBC_SCCS and not lint */ | ||
| 43 | |||
| 44 | #include <sys/types.h> | 31 | #include <sys/types.h> |
| 45 | #include <sys/socket.h> | 32 | #include <sys/socket.h> |
| 46 | 33 | ||
| 47 | #include <stddef.h> | 34 | #include <stddef.h> |
| 48 | 35 | ||
| 49 | ssize_t | 36 | ssize_t |
| 50 | recv(s, buf, len, flags) | 37 | recv(int s, void *buf, size_t len, int flags) |
| 51 | int s, flags; | ||
| 52 | size_t len; | ||
| 53 | void *buf; | ||
| 54 | { | 38 | { |
| 55 | return (recvfrom(s, buf, len, flags, NULL, 0)); | 39 | return (recvfrom(s, buf, len, flags, NULL, 0)); |
| 56 | } | 40 | } |
diff --git a/src/lib/libc/net/res_comp.c b/src/lib/libc/net/res_comp.c index 9d7bbecdda..69a6ce0abb 100644 --- a/src/lib/libc/net/res_comp.c +++ b/src/lib/libc/net/res_comp.c | |||
| @@ -1,9 +1,11 @@ | |||
| 1 | /* $NetBSD: res_comp.c,v 1.6 1995/02/25 06:20:55 cgd Exp $ */ | 1 | /* $OpenBSD: res_comp.c,v 1.14 2008/04/16 22:35:23 deraadt Exp $ */ |
| 2 | 2 | ||
| 3 | /*- | 3 | /* |
| 4 | * ++Copyright++ 1985, 1993 | ||
| 5 | * - | ||
| 4 | * Copyright (c) 1985, 1993 | 6 | * Copyright (c) 1985, 1993 |
| 5 | * The Regents of the University of California. All rights reserved. | 7 | * The Regents of the University of California. All rights reserved. |
| 6 | * | 8 | * |
| 7 | * Redistribution and use in source and binary forms, with or without | 9 | * Redistribution and use in source and binary forms, with or without |
| 8 | * modification, are permitted provided that the following conditions | 10 | * modification, are permitted provided that the following conditions |
| 9 | * are met: | 11 | * are met: |
| @@ -12,14 +14,10 @@ | |||
| 12 | * 2. Redistributions in binary form must reproduce the above copyright | 14 | * 2. Redistributions in binary form must reproduce the above copyright |
| 13 | * notice, this list of conditions and the following disclaimer in the | 15 | * notice, this list of conditions and the following disclaimer in the |
| 14 | * documentation and/or other materials provided with the distribution. | 16 | * documentation and/or other materials provided with the distribution. |
| 15 | * 3. All advertising materials mentioning features or use of this software | 17 | * 3. Neither the name of the University nor the names of its contributors |
| 16 | * must display the following acknowledgement: | ||
| 17 | * This product includes software developed by the University of | ||
| 18 | * California, Berkeley and its contributors. | ||
| 19 | * 4. Neither the name of the University nor the names of its contributors | ||
| 20 | * may be used to endorse or promote products derived from this software | 18 | * may be used to endorse or promote products derived from this software |
| 21 | * without specific prior written permission. | 19 | * without specific prior written permission. |
| 22 | * | 20 | * |
| 23 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | 21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
| 24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| @@ -53,22 +51,19 @@ | |||
| 53 | * --Copyright-- | 51 | * --Copyright-- |
| 54 | */ | 52 | */ |
| 55 | 53 | ||
| 56 | #if defined(LIBC_SCCS) && !defined(lint) | 54 | #include <sys/types.h> |
| 57 | #if 0 | ||
| 58 | static char sccsid[] = "@(#)res_comp.c 8.1 (Berkeley) 6/4/93"; | ||
| 59 | static char rcsid[] = "$Id: res_comp.c,v 4.9.1.1 1993/05/02 22:43:03 vixie Rel "; | ||
| 60 | #else | ||
| 61 | static char rcsid[] = "$NetBSD: res_comp.c,v 1.6 1995/02/25 06:20:55 cgd Exp $"; | ||
| 62 | #endif | ||
| 63 | #endif /* LIBC_SCCS and not lint */ | ||
| 64 | |||
| 65 | #include <sys/param.h> | 55 | #include <sys/param.h> |
| 66 | #include <arpa/nameser.h> | ||
| 67 | #include <netinet/in.h> | 56 | #include <netinet/in.h> |
| 68 | #include <resolv.h> | 57 | #include <arpa/nameser.h> |
| 58 | |||
| 69 | #include <stdio.h> | 59 | #include <stdio.h> |
| 60 | #include <resolv.h> | ||
| 61 | #include <ctype.h> | ||
| 62 | |||
| 63 | #include <unistd.h> | ||
| 64 | #include <string.h> | ||
| 70 | 65 | ||
| 71 | static int dn_find(); | 66 | static int dn_find(u_char *, u_char *, u_char **, u_char **); |
| 72 | 67 | ||
| 73 | /* | 68 | /* |
| 74 | * Expand compressed domain name 'comp_dn' to full domain name. | 69 | * Expand compressed domain name 'comp_dn' to full domain name. |
| @@ -77,23 +72,25 @@ static int dn_find(); | |||
| 77 | * 'exp_dn' is a pointer to a buffer of size 'length' for the result. | 72 | * 'exp_dn' is a pointer to a buffer of size 'length' for the result. |
| 78 | * Return size of compressed name or -1 if there was an error. | 73 | * Return size of compressed name or -1 if there was an error. |
| 79 | */ | 74 | */ |
| 80 | dn_expand(msg, eomorig, comp_dn, exp_dn, length) | 75 | int |
| 81 | const u_char *msg, *eomorig, *comp_dn; | 76 | dn_expand(const u_char *msg, const u_char *eomorig, const u_char *comp_dn, |
| 82 | u_char *exp_dn; | 77 | char *exp_dn, int length) |
| 83 | int length; | ||
| 84 | { | 78 | { |
| 85 | register u_char *cp, *dn; | 79 | const u_char *cp; |
| 86 | register int n, c; | 80 | char *dn; |
| 87 | u_char *eom; | 81 | int n, c; |
| 82 | char *eom; | ||
| 88 | int len = -1, checked = 0; | 83 | int len = -1, checked = 0; |
| 89 | 84 | ||
| 90 | dn = exp_dn; | 85 | dn = exp_dn; |
| 91 | cp = (u_char *)comp_dn; | 86 | cp = comp_dn; |
| 87 | if (length > MAXHOSTNAMELEN-1) | ||
| 88 | length = MAXHOSTNAMELEN-1; | ||
| 92 | eom = exp_dn + length; | 89 | eom = exp_dn + length; |
| 93 | /* | 90 | /* |
| 94 | * fetch next label in domain name | 91 | * fetch next label in domain name |
| 95 | */ | 92 | */ |
| 96 | while (n = *cp++) { | 93 | while ((n = *cp++)) { |
| 97 | /* | 94 | /* |
| 98 | * Check for indirection | 95 | * Check for indirection |
| 99 | */ | 96 | */ |
| @@ -108,23 +105,23 @@ dn_expand(msg, eomorig, comp_dn, exp_dn, length) | |||
| 108 | return (-1); | 105 | return (-1); |
| 109 | checked += n + 1; | 106 | checked += n + 1; |
| 110 | while (--n >= 0) { | 107 | while (--n >= 0) { |
| 111 | if ((c = *cp++) == '.') { | 108 | if (((c = *cp++) == '.') || (c == '\\')) { |
| 112 | if (dn + n + 2 >= eom) | 109 | if (dn + n + 2 >= eom) |
| 113 | return (-1); | 110 | return (-1); |
| 114 | *dn++ = '\\'; | 111 | *dn++ = '\\'; |
| 115 | } | 112 | } |
| 116 | *dn++ = c; | 113 | *dn++ = c; |
| 117 | if (cp >= eomorig) /* out of range */ | 114 | if (cp >= eomorig) /* out of range */ |
| 118 | return(-1); | 115 | return (-1); |
| 119 | } | 116 | } |
| 120 | break; | 117 | break; |
| 121 | 118 | ||
| 122 | case INDIR_MASK: | 119 | case INDIR_MASK: |
| 123 | if (len < 0) | 120 | if (len < 0) |
| 124 | len = cp - comp_dn + 1; | 121 | len = cp - comp_dn + 1; |
| 125 | cp = (u_char *)msg + (((n & 0x3f) << 8) | (*cp & 0xff)); | 122 | cp = msg + (((n & 0x3f) << 8) | (*cp & 0xff)); |
| 126 | if (cp < msg || cp >= eomorig) /* out of range */ | 123 | if (cp < msg || cp >= eomorig) /* out of range */ |
| 127 | return(-1); | 124 | return (-1); |
| 128 | checked += 2; | 125 | checked += 2; |
| 129 | /* | 126 | /* |
| 130 | * Check for loops in the compressed name; | 127 | * Check for loops in the compressed name; |
| @@ -157,19 +154,19 @@ dn_expand(msg, eomorig, comp_dn, exp_dn, length) | |||
| 157 | * If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr' | 154 | * If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr' |
| 158 | * is NULL, we don't update the list. | 155 | * is NULL, we don't update the list. |
| 159 | */ | 156 | */ |
| 160 | dn_comp(exp_dn, comp_dn, length, dnptrs, lastdnptr) | 157 | int |
| 161 | const u_char *exp_dn; | 158 | dn_comp(const char *exp_dn, u_char *comp_dn, int length, u_char **dnptrs, |
| 162 | u_char *comp_dn, **dnptrs, **lastdnptr; | 159 | u_char **lastdnptr) |
| 163 | int length; | ||
| 164 | { | 160 | { |
| 165 | register u_char *cp, *dn; | 161 | u_char *cp, *dn; |
| 166 | register int c, l; | 162 | int c, l; |
| 167 | u_char **cpp, **lpp, *sp, *eob; | 163 | u_char **cpp, **lpp, *sp, *eob; |
| 168 | u_char *msg; | 164 | u_char *msg; |
| 169 | 165 | ||
| 170 | dn = (u_char *)exp_dn; | 166 | dn = (u_char *)exp_dn; |
| 171 | cp = comp_dn; | 167 | cp = comp_dn; |
| 172 | eob = cp + length; | 168 | eob = cp + length; |
| 169 | lpp = cpp = NULL; | ||
| 173 | if (dnptrs != NULL) { | 170 | if (dnptrs != NULL) { |
| 174 | if ((msg = *dnptrs++) != NULL) { | 171 | if ((msg = *dnptrs++) != NULL) { |
| 175 | for (cpp = dnptrs; *cpp != NULL; cpp++) | 172 | for (cpp = dnptrs; *cpp != NULL; cpp++) |
| @@ -235,13 +232,13 @@ dn_comp(exp_dn, comp_dn, length, dnptrs, lastdnptr) | |||
| 235 | /* | 232 | /* |
| 236 | * Skip over a compressed domain name. Return the size or -1. | 233 | * Skip over a compressed domain name. Return the size or -1. |
| 237 | */ | 234 | */ |
| 238 | __dn_skipname(comp_dn, eom) | 235 | int |
| 239 | const u_char *comp_dn, *eom; | 236 | __dn_skipname(const u_char *comp_dn, const u_char *eom) |
| 240 | { | 237 | { |
| 241 | register u_char *cp; | 238 | const u_char *cp; |
| 242 | register int n; | 239 | int n; |
| 243 | 240 | ||
| 244 | cp = (u_char *)comp_dn; | 241 | cp = comp_dn; |
| 245 | while (cp < eom && (n = *cp++)) { | 242 | while (cp < eom && (n = *cp++)) { |
| 246 | /* | 243 | /* |
| 247 | * check for indirection | 244 | * check for indirection |
| @@ -259,10 +256,18 @@ __dn_skipname(comp_dn, eom) | |||
| 259 | break; | 256 | break; |
| 260 | } | 257 | } |
| 261 | if (cp > eom) | 258 | if (cp > eom) |
| 262 | return -1; | 259 | return (-1); |
| 263 | return (cp - comp_dn); | 260 | return (cp - comp_dn); |
| 264 | } | 261 | } |
| 265 | 262 | ||
| 263 | static int | ||
| 264 | mklower(int ch) | ||
| 265 | { | ||
| 266 | if (isascii(ch) && isupper(ch)) | ||
| 267 | return (tolower(ch)); | ||
| 268 | return (ch); | ||
| 269 | } | ||
| 270 | |||
| 266 | /* | 271 | /* |
| 267 | * Search for expanded name from a list of previously compressed names. | 272 | * Search for expanded name from a list of previously compressed names. |
| 268 | * Return the offset from msg if found or -1. | 273 | * Return the offset from msg if found or -1. |
| @@ -270,18 +275,16 @@ __dn_skipname(comp_dn, eom) | |||
| 270 | * not the pointer to the start of the message. | 275 | * not the pointer to the start of the message. |
| 271 | */ | 276 | */ |
| 272 | static int | 277 | static int |
| 273 | dn_find(exp_dn, msg, dnptrs, lastdnptr) | 278 | dn_find(u_char *exp_dn, u_char *msg, u_char **dnptrs, u_char **lastdnptr) |
| 274 | u_char *exp_dn, *msg; | ||
| 275 | u_char **dnptrs, **lastdnptr; | ||
| 276 | { | 279 | { |
| 277 | register u_char *dn, *cp, **cpp; | 280 | u_char *dn, *cp, **cpp; |
| 278 | register int n; | 281 | int n; |
| 279 | u_char *sp; | 282 | u_char *sp; |
| 280 | 283 | ||
| 281 | for (cpp = dnptrs; cpp < lastdnptr; cpp++) { | 284 | for (cpp = dnptrs; cpp < lastdnptr; cpp++) { |
| 282 | dn = exp_dn; | 285 | dn = exp_dn; |
| 283 | sp = cp = *cpp; | 286 | sp = cp = *cpp; |
| 284 | while (n = *cp++) { | 287 | while ((n = *cp++)) { |
| 285 | /* | 288 | /* |
| 286 | * check for indirection | 289 | * check for indirection |
| 287 | */ | 290 | */ |
| @@ -292,7 +295,7 @@ dn_find(exp_dn, msg, dnptrs, lastdnptr) | |||
| 292 | goto next; | 295 | goto next; |
| 293 | if (*dn == '\\') | 296 | if (*dn == '\\') |
| 294 | dn++; | 297 | dn++; |
| 295 | if (*dn++ != *cp++) | 298 | if (mklower(*dn++) != mklower(*cp++)) |
| 296 | goto next; | 299 | goto next; |
| 297 | } | 300 | } |
| 298 | if ((n = *dn++) == '\0' && *cp == '\0') | 301 | if ((n = *dn++) == '\0' && *cp == '\0') |
| @@ -301,11 +304,12 @@ dn_find(exp_dn, msg, dnptrs, lastdnptr) | |||
| 301 | continue; | 304 | continue; |
| 302 | goto next; | 305 | goto next; |
| 303 | 306 | ||
| 304 | default: /* illegal type */ | ||
| 305 | return (-1); | ||
| 306 | |||
| 307 | case INDIR_MASK: /* indirection */ | 307 | case INDIR_MASK: /* indirection */ |
| 308 | cp = msg + (((n & 0x3f) << 8) | *cp); | 308 | cp = msg + (((n & 0x3f) << 8) | *cp); |
| 309 | break; | ||
| 310 | |||
| 311 | default: /* illegal type */ | ||
| 312 | return (-1); | ||
| 309 | } | 313 | } |
| 310 | } | 314 | } |
| 311 | if (*dn == '\0') | 315 | if (*dn == '\0') |
| @@ -316,49 +320,156 @@ dn_find(exp_dn, msg, dnptrs, lastdnptr) | |||
| 316 | } | 320 | } |
| 317 | 321 | ||
| 318 | /* | 322 | /* |
| 319 | * Routines to insert/extract short/long's. Must account for byte | 323 | * Verify that a domain name uses an acceptable character set. |
| 320 | * order and non-alignment problems. This code at least has the | 324 | */ |
| 321 | * advantage of being portable. | 325 | |
| 322 | * | 326 | /* |
| 323 | * used by sendmail. | 327 | * Note the conspicuous absence of ctype macros in these definitions. On |
| 328 | * non-ASCII hosts, we can't depend on string literals or ctype macros to | ||
| 329 | * tell us anything about network-format data. The rest of the BIND system | ||
| 330 | * is not careful about this, but for some reason, we're doing it right here. | ||
| 331 | */ | ||
| 332 | #define PERIOD 0x2e | ||
| 333 | #define hyphenchar(c) ((c) == 0x2d) | ||
| 334 | #define bslashchar(c) ((c) == 0x5c) | ||
| 335 | #define underscorechar(c) ((c) == 0x5f) | ||
| 336 | #define periodchar(c) ((c) == PERIOD) | ||
| 337 | #define asterchar(c) ((c) == 0x2a) | ||
| 338 | #define alphachar(c) (((c) >= 0x41 && (c) <= 0x5a) \ | ||
| 339 | || ((c) >= 0x61 && (c) <= 0x7a)) | ||
| 340 | #define digitchar(c) ((c) >= 0x30 && (c) <= 0x39) | ||
| 341 | |||
| 342 | #define borderchar(c) (alphachar(c) || digitchar(c)) | ||
| 343 | #define middlechar(c) (borderchar(c) || hyphenchar(c) || underscorechar(c)) | ||
| 344 | #define domainchar(c) ((c) > 0x20 && (c) < 0x7f) | ||
| 345 | |||
| 346 | int | ||
| 347 | res_hnok(const char *dn) | ||
| 348 | { | ||
| 349 | int pch = PERIOD, ch = *dn++; | ||
| 350 | |||
| 351 | while (ch != '\0') { | ||
| 352 | int nch = *dn++; | ||
| 353 | |||
| 354 | if (periodchar(ch)) { | ||
| 355 | ; | ||
| 356 | } else if (periodchar(pch)) { | ||
| 357 | if (!borderchar(ch)) | ||
| 358 | return (0); | ||
| 359 | } else if (periodchar(nch) || nch == '\0') { | ||
| 360 | if (!borderchar(ch)) | ||
| 361 | return (0); | ||
| 362 | } else { | ||
| 363 | if (!middlechar(ch)) | ||
| 364 | return (0); | ||
| 365 | } | ||
| 366 | pch = ch, ch = nch; | ||
| 367 | } | ||
| 368 | return (1); | ||
| 369 | } | ||
| 370 | |||
| 371 | /* | ||
| 372 | * hostname-like (A, MX, WKS) owners can have "*" as their first label | ||
| 373 | * but must otherwise be as a host name. | ||
| 324 | */ | 374 | */ |
| 375 | int | ||
| 376 | res_ownok(const char *dn) | ||
| 377 | { | ||
| 378 | if (asterchar(dn[0])) { | ||
| 379 | if (periodchar(dn[1])) | ||
| 380 | return (res_hnok(dn+2)); | ||
| 381 | if (dn[1] == '\0') | ||
| 382 | return (1); | ||
| 383 | } | ||
| 384 | return (res_hnok(dn)); | ||
| 385 | } | ||
| 325 | 386 | ||
| 326 | u_short | 387 | /* |
| 327 | _getshort(msgp) | 388 | * SOA RNAMEs and RP RNAMEs can have any printable character in their first |
| 328 | register u_char *msgp; | 389 | * label, but the rest of the name has to look like a host name. |
| 390 | */ | ||
| 391 | int | ||
| 392 | res_mailok(const char *dn) | ||
| 329 | { | 393 | { |
| 330 | register u_int16_t u; | 394 | int ch, escaped = 0; |
| 395 | |||
| 396 | /* "." is a valid missing representation */ | ||
| 397 | if (*dn == '\0') | ||
| 398 | return(1); | ||
| 399 | |||
| 400 | /* otherwise <label>.<hostname> */ | ||
| 401 | while ((ch = *dn++) != '\0') { | ||
| 402 | if (!domainchar(ch)) | ||
| 403 | return (0); | ||
| 404 | if (!escaped && periodchar(ch)) | ||
| 405 | break; | ||
| 406 | if (escaped) | ||
| 407 | escaped = 0; | ||
| 408 | else if (bslashchar(ch)) | ||
| 409 | escaped = 1; | ||
| 410 | } | ||
| 411 | if (periodchar(ch)) | ||
| 412 | return (res_hnok(dn)); | ||
| 413 | return(0); | ||
| 414 | } | ||
| 415 | |||
| 416 | /* | ||
| 417 | * This function is quite liberal, since RFC 1034's character sets are only | ||
| 418 | * recommendations. | ||
| 419 | */ | ||
| 420 | int | ||
| 421 | res_dnok(const char *dn) | ||
| 422 | { | ||
| 423 | int ch; | ||
| 424 | |||
| 425 | while ((ch = *dn++) != '\0') | ||
| 426 | if (!domainchar(ch)) | ||
| 427 | return (0); | ||
| 428 | return (1); | ||
| 429 | } | ||
| 430 | |||
| 431 | /* | ||
| 432 | * Routines to insert/extract short/long's. | ||
| 433 | */ | ||
| 434 | |||
| 435 | u_int16_t | ||
| 436 | _getshort(const u_char *msgp) | ||
| 437 | { | ||
| 438 | u_int16_t u; | ||
| 331 | 439 | ||
| 332 | GETSHORT(u, msgp); | 440 | GETSHORT(u, msgp); |
| 333 | return (u); | 441 | return (u); |
| 334 | } | 442 | } |
| 335 | 443 | ||
| 444 | #ifdef NeXT | ||
| 445 | /* | ||
| 446 | * nExt machines have some funky library conventions, which we must maintain. | ||
| 447 | */ | ||
| 448 | u_int16_t | ||
| 449 | res_getshort(msgp) | ||
| 450 | const u_char *msgp; | ||
| 451 | { | ||
| 452 | return (_getshort(msgp)); | ||
| 453 | } | ||
| 454 | #endif | ||
| 455 | |||
| 336 | u_int32_t | 456 | u_int32_t |
| 337 | _getlong(msgp) | 457 | _getlong(const u_char *msgp) |
| 338 | register u_char *msgp; | ||
| 339 | { | 458 | { |
| 340 | register u_int32_t u; | 459 | u_int32_t u; |
| 341 | 460 | ||
| 342 | GETLONG(u, msgp); | 461 | GETLONG(u, msgp); |
| 343 | return (u); | 462 | return (u); |
| 344 | } | 463 | } |
| 345 | 464 | ||
| 346 | void | 465 | void |
| 347 | #if defined(__STDC__) || defined(__cplusplus) | 466 | __putshort(u_int16_t s, u_char *msgp) |
| 348 | __putshort(register u_int16_t s, register u_char *msgp) | ||
| 349 | #else | ||
| 350 | __putshort(s, msgp) | ||
| 351 | register u_int16_t s; | ||
| 352 | register u_char *msgp; | ||
| 353 | #endif | ||
| 354 | { | 467 | { |
| 355 | PUTSHORT(s, msgp); | 468 | PUTSHORT(s, msgp); |
| 356 | } | 469 | } |
| 357 | 470 | ||
| 358 | void | 471 | void |
| 359 | __putlong(l, msgp) | 472 | __putlong(u_int32_t l, u_char *msgp) |
| 360 | register u_int32_t l; | ||
| 361 | register u_char *msgp; | ||
| 362 | { | 473 | { |
| 363 | PUTLONG(l, msgp); | 474 | PUTLONG(l, msgp); |
| 364 | } | 475 | } |
diff --git a/src/lib/libc/net/res_data.c b/src/lib/libc/net/res_data.c new file mode 100644 index 0000000000..a5f6b03a7f --- /dev/null +++ b/src/lib/libc/net/res_data.c | |||
| @@ -0,0 +1,105 @@ | |||
| 1 | /* $OpenBSD: res_data.c,v 1.3 2005/08/06 20:30:03 espie Exp $ */ | ||
| 2 | |||
| 3 | /* | ||
| 4 | * ++Copyright++ 1995 | ||
| 5 | * - | ||
| 6 | * Copyright (c) 1995 | ||
| 7 | * The Regents of the University of California. All rights reserved. | ||
| 8 | * | ||
| 9 | * Redistribution and use in source and binary forms, with or without | ||
| 10 | * modification, are permitted provided that the following conditions | ||
| 11 | * are met: | ||
| 12 | * 1. Redistributions of source code must retain the above copyright | ||
| 13 | * notice, this list of conditions and the following disclaimer. | ||
| 14 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 15 | * notice, this list of conditions and the following disclaimer in the | ||
| 16 | * documentation and/or other materials provided with the distribution. | ||
| 17 | * 3. Neither the name of the University nor the names of its contributors | ||
| 18 | * may be used to endorse or promote products derived from this software | ||
| 19 | * without specific prior written permission. | ||
| 20 | * | ||
| 21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
| 22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
| 25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 31 | * SUCH DAMAGE. | ||
| 32 | * - | ||
| 33 | * Portions Copyright (c) 1993 by Digital Equipment Corporation. | ||
| 34 | * | ||
| 35 | * Permission to use, copy, modify, and distribute this software for any | ||
| 36 | * purpose with or without fee is hereby granted, provided that the above | ||
| 37 | * copyright notice and this permission notice appear in all copies, and that | ||
| 38 | * the name of Digital Equipment Corporation not be used in advertising or | ||
| 39 | * publicity pertaining to distribution of the document or software without | ||
| 40 | * specific, written prior permission. | ||
| 41 | * | ||
| 42 | * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL | ||
| 43 | * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES | ||
| 44 | * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT | ||
| 45 | * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | ||
| 46 | * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR | ||
| 47 | * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS | ||
| 48 | * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | ||
| 49 | * SOFTWARE. | ||
| 50 | * - | ||
| 51 | * --Copyright-- | ||
| 52 | */ | ||
| 53 | |||
| 54 | #include <sys/types.h> | ||
| 55 | #include <sys/param.h> | ||
| 56 | #include <sys/socket.h> | ||
| 57 | #include <sys/time.h> | ||
| 58 | #include <netinet/in.h> | ||
| 59 | #include <arpa/inet.h> | ||
| 60 | #include <arpa/nameser.h> | ||
| 61 | |||
| 62 | #include <stdio.h> | ||
| 63 | #include <ctype.h> | ||
| 64 | #include <resolv.h> | ||
| 65 | #include <unistd.h> | ||
| 66 | #include <stdlib.h> | ||
| 67 | #include <string.h> | ||
| 68 | |||
| 69 | const char *_res_opcodes[] = { | ||
| 70 | "QUERY", | ||
| 71 | "IQUERY", | ||
| 72 | "CQUERYM", | ||
| 73 | "CQUERYU", /* experimental */ | ||
| 74 | "NOTIFY", /* experimental */ | ||
| 75 | "5", | ||
| 76 | "6", | ||
| 77 | "7", | ||
| 78 | "8", | ||
| 79 | "UPDATEA", | ||
| 80 | "UPDATED", | ||
| 81 | "UPDATEDA", | ||
| 82 | "UPDATEM", | ||
| 83 | "UPDATEMA", | ||
| 84 | "ZONEINIT", | ||
| 85 | "ZONEREF", | ||
| 86 | }; | ||
| 87 | |||
| 88 | const char *_res_resultcodes[] = { | ||
| 89 | "NOERROR", | ||
| 90 | "FORMERR", | ||
| 91 | "SERVFAIL", | ||
| 92 | "NXDOMAIN", | ||
| 93 | "NOTIMP", | ||
| 94 | "REFUSED", | ||
| 95 | "6", | ||
| 96 | "7", | ||
| 97 | "8", | ||
| 98 | "9", | ||
| 99 | "10", | ||
| 100 | "11", | ||
| 101 | "12", | ||
| 102 | "13", | ||
| 103 | "14", | ||
| 104 | "NOCHANGE", | ||
| 105 | }; | ||
diff --git a/src/lib/libc/net/res_debug.c b/src/lib/libc/net/res_debug.c deleted file mode 100644 index d841293f18..0000000000 --- a/src/lib/libc/net/res_debug.c +++ /dev/null | |||
| @@ -1,749 +0,0 @@ | |||
| 1 | /* $NetBSD: res_debug.c,v 1.7 1995/02/25 06:20:56 cgd Exp $ */ | ||
| 2 | |||
| 3 | /*- | ||
| 4 | * Copyright (c) 1985, 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 | * Portions Copyright (c) 1993 by Digital Equipment Corporation. | ||
| 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, and that | ||
| 40 | * the name of Digital Equipment Corporation not be used in advertising or | ||
| 41 | * publicity pertaining to distribution of the document or software without | ||
| 42 | * specific, written prior permission. | ||
| 43 | * | ||
| 44 | * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL | ||
| 45 | * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES | ||
| 46 | * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT | ||
| 47 | * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | ||
| 48 | * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR | ||
| 49 | * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS | ||
| 50 | * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | ||
| 51 | * SOFTWARE. | ||
| 52 | * - | ||
| 53 | * --Copyright-- | ||
| 54 | */ | ||
| 55 | |||
| 56 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 57 | #if 0 | ||
| 58 | static char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93"; | ||
| 59 | #else | ||
| 60 | static char rcsid[] = "$NetBSD: res_debug.c,v 1.7 1995/02/25 06:20:56 cgd Exp $"; | ||
| 61 | #endif | ||
| 62 | #endif /* LIBC_SCCS and not lint */ | ||
| 63 | |||
| 64 | #include <sys/param.h> | ||
| 65 | #include <netinet/in.h> | ||
| 66 | #include <arpa/inet.h> | ||
| 67 | #include <arpa/nameser.h> | ||
| 68 | #include <resolv.h> | ||
| 69 | #include <stdio.h> | ||
| 70 | #include <string.h> | ||
| 71 | |||
| 72 | void __fp_query(); | ||
| 73 | char *__p_class(), *__p_time(), *__p_type(); | ||
| 74 | char *p_cdname(), *p_fqname(), *p_rr(); | ||
| 75 | static char *p_option __P((u_int32_t)); | ||
| 76 | |||
| 77 | char *_res_opcodes[] = { | ||
| 78 | "QUERY", | ||
| 79 | "IQUERY", | ||
| 80 | "CQUERYM", | ||
| 81 | "CQUERYU", | ||
| 82 | "4", | ||
| 83 | "5", | ||
| 84 | "6", | ||
| 85 | "7", | ||
| 86 | "8", | ||
| 87 | "UPDATEA", | ||
| 88 | "UPDATED", | ||
| 89 | "UPDATEDA", | ||
| 90 | "UPDATEM", | ||
| 91 | "UPDATEMA", | ||
| 92 | "ZONEINIT", | ||
| 93 | "ZONEREF", | ||
| 94 | }; | ||
| 95 | |||
| 96 | char *_res_resultcodes[] = { | ||
| 97 | "NOERROR", | ||
| 98 | "FORMERR", | ||
| 99 | "SERVFAIL", | ||
| 100 | "NXDOMAIN", | ||
| 101 | "NOTIMP", | ||
| 102 | "REFUSED", | ||
| 103 | "6", | ||
| 104 | "7", | ||
| 105 | "8", | ||
| 106 | "9", | ||
| 107 | "10", | ||
| 108 | "11", | ||
| 109 | "12", | ||
| 110 | "13", | ||
| 111 | "14", | ||
| 112 | "NOCHANGE", | ||
| 113 | }; | ||
| 114 | |||
| 115 | static char retbuf[16]; | ||
| 116 | |||
| 117 | static char * | ||
| 118 | dewks(wks) | ||
| 119 | int wks; | ||
| 120 | { | ||
| 121 | switch (wks) { | ||
| 122 | case 5: return("rje"); | ||
| 123 | case 7: return("echo"); | ||
| 124 | case 9: return("discard"); | ||
| 125 | case 11: return("systat"); | ||
| 126 | case 13: return("daytime"); | ||
| 127 | case 15: return("netstat"); | ||
| 128 | case 17: return("qotd"); | ||
| 129 | case 19: return("chargen"); | ||
| 130 | case 20: return("ftp-data"); | ||
| 131 | case 21: return("ftp"); | ||
| 132 | case 23: return("telnet"); | ||
| 133 | case 25: return("smtp"); | ||
| 134 | case 37: return("time"); | ||
| 135 | case 39: return("rlp"); | ||
| 136 | case 42: return("name"); | ||
| 137 | case 43: return("whois"); | ||
| 138 | case 53: return("domain"); | ||
| 139 | case 57: return("apts"); | ||
| 140 | case 59: return("apfs"); | ||
| 141 | case 67: return("bootps"); | ||
| 142 | case 68: return("bootpc"); | ||
| 143 | case 69: return("tftp"); | ||
| 144 | case 77: return("rje"); | ||
| 145 | case 79: return("finger"); | ||
| 146 | case 87: return("link"); | ||
| 147 | case 95: return("supdup"); | ||
| 148 | case 100: return("newacct"); | ||
| 149 | case 101: return("hostnames"); | ||
| 150 | case 102: return("iso-tsap"); | ||
| 151 | case 103: return("x400"); | ||
| 152 | case 104: return("x400-snd"); | ||
| 153 | case 105: return("csnet-ns"); | ||
| 154 | case 109: return("pop-2"); | ||
| 155 | case 111: return("sunrpc"); | ||
| 156 | case 113: return("auth"); | ||
| 157 | case 115: return("sftp"); | ||
| 158 | case 117: return("uucp-path"); | ||
| 159 | case 119: return("nntp"); | ||
| 160 | case 121: return("erpc"); | ||
| 161 | case 123: return("ntp"); | ||
| 162 | case 133: return("statsrv"); | ||
| 163 | case 136: return("profile"); | ||
| 164 | case 144: return("NeWS"); | ||
| 165 | case 161: return("snmp"); | ||
| 166 | case 162: return("snmp-trap"); | ||
| 167 | case 170: return("print-srv"); | ||
| 168 | default: (void) sprintf(retbuf, "%d", wks); return(retbuf); | ||
| 169 | } | ||
| 170 | } | ||
| 171 | |||
| 172 | static char * | ||
| 173 | deproto(protonum) | ||
| 174 | int protonum; | ||
| 175 | { | ||
| 176 | switch (protonum) { | ||
| 177 | case 1: return("icmp"); | ||
| 178 | case 2: return("igmp"); | ||
| 179 | case 3: return("ggp"); | ||
| 180 | case 5: return("st"); | ||
| 181 | case 6: return("tcp"); | ||
| 182 | case 7: return("ucl"); | ||
| 183 | case 8: return("egp"); | ||
| 184 | case 9: return("igp"); | ||
| 185 | case 11: return("nvp-II"); | ||
| 186 | case 12: return("pup"); | ||
| 187 | case 16: return("chaos"); | ||
| 188 | case 17: return("udp"); | ||
| 189 | default: (void) sprintf(retbuf, "%d", protonum); return(retbuf); | ||
| 190 | } | ||
| 191 | } | ||
| 192 | |||
| 193 | static char * | ||
| 194 | do_rrset(msg, cp, cnt, pflag, file, hs) | ||
| 195 | int cnt, pflag; | ||
| 196 | char *cp,*msg, *hs; | ||
| 197 | FILE *file; | ||
| 198 | { | ||
| 199 | int n; | ||
| 200 | int sflag; | ||
| 201 | /* | ||
| 202 | * Print answer records | ||
| 203 | */ | ||
| 204 | sflag = (_res.pfcode & pflag); | ||
| 205 | if (n = ntohs(cnt)) { | ||
| 206 | if ((!_res.pfcode) || ((sflag) && (_res.pfcode & RES_PRF_HEAD1))) | ||
| 207 | fprintf(file, hs); | ||
| 208 | while (--n >= 0) { | ||
| 209 | cp = p_rr(cp, msg, file); | ||
| 210 | if ((cp-msg) > PACKETSZ) | ||
| 211 | return (NULL); | ||
| 212 | } | ||
| 213 | if ((!_res.pfcode) || ((sflag) && (_res.pfcode & RES_PRF_HEAD1))) | ||
| 214 | putc('\n', file); | ||
| 215 | } | ||
| 216 | return(cp); | ||
| 217 | } | ||
| 218 | |||
| 219 | __p_query(msg) | ||
| 220 | char *msg; | ||
| 221 | { | ||
| 222 | __fp_query(msg, stdout); | ||
| 223 | } | ||
| 224 | |||
| 225 | /* | ||
| 226 | * Print the current options. | ||
| 227 | * This is intended to be primarily a debugging routine. | ||
| 228 | */ | ||
| 229 | void | ||
| 230 | __fp_resstat(statp, file) | ||
| 231 | struct __res_state *statp; | ||
| 232 | FILE *file; | ||
| 233 | { | ||
| 234 | int bit; | ||
| 235 | |||
| 236 | fprintf(file, ";; res options:"); | ||
| 237 | if (!statp) | ||
| 238 | statp = &_res; | ||
| 239 | for (bit = 0; bit < 32; bit++) { /* XXX 32 - bad assumption! */ | ||
| 240 | if (statp->options & (1<<bit)) | ||
| 241 | fprintf(file, " %s", p_option(1<<bit)); | ||
| 242 | } | ||
| 243 | putc('\n', file); | ||
| 244 | } | ||
| 245 | |||
| 246 | /* | ||
| 247 | * Print the contents of a query. | ||
| 248 | * This is intended to be primarily a debugging routine. | ||
| 249 | */ | ||
| 250 | void | ||
| 251 | __fp_query(msg,file) | ||
| 252 | char *msg; | ||
| 253 | FILE *file; | ||
| 254 | { | ||
| 255 | register char *cp; | ||
| 256 | register HEADER *hp; | ||
| 257 | register int n; | ||
| 258 | |||
| 259 | /* | ||
| 260 | * Print header fields. | ||
| 261 | */ | ||
| 262 | hp = (HEADER *)msg; | ||
| 263 | cp = msg + sizeof(HEADER); | ||
| 264 | if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX) || hp->rcode) { | ||
| 265 | fprintf(file,";; ->>HEADER<<- opcode: %s, status: %s, id: %d", | ||
| 266 | _res_opcodes[hp->opcode], | ||
| 267 | _res_resultcodes[hp->rcode], | ||
| 268 | ntohs(hp->id)); | ||
| 269 | putc('\n', file); | ||
| 270 | } | ||
| 271 | putc(';', file); | ||
| 272 | if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD2)) { | ||
| 273 | fprintf(file,"; flags:"); | ||
| 274 | if (hp->qr) | ||
| 275 | fprintf(file," qr"); | ||
| 276 | if (hp->aa) | ||
| 277 | fprintf(file," aa"); | ||
| 278 | if (hp->tc) | ||
| 279 | fprintf(file," tc"); | ||
| 280 | if (hp->rd) | ||
| 281 | fprintf(file," rd"); | ||
| 282 | if (hp->ra) | ||
| 283 | fprintf(file," ra"); | ||
| 284 | if (hp->pr) | ||
| 285 | fprintf(file," pr"); | ||
| 286 | } | ||
| 287 | if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD1)) { | ||
| 288 | fprintf(file,"; Ques: %d", ntohs(hp->qdcount)); | ||
| 289 | fprintf(file,", Ans: %d", ntohs(hp->ancount)); | ||
| 290 | fprintf(file,", Auth: %d", ntohs(hp->nscount)); | ||
| 291 | fprintf(file,", Addit: %d\n", ntohs(hp->arcount)); | ||
| 292 | } | ||
| 293 | #if 0 | ||
| 294 | if (_res.pfcode & (RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1)) { | ||
| 295 | putc('\n',file); | ||
| 296 | } | ||
| 297 | #endif | ||
| 298 | /* | ||
| 299 | * Print question records. | ||
| 300 | */ | ||
| 301 | if (n = ntohs(hp->qdcount)) { | ||
| 302 | if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) | ||
| 303 | fprintf(file,";; QUESTIONS:\n"); | ||
| 304 | while (--n >= 0) { | ||
| 305 | fprintf(file,";;\t"); | ||
| 306 | cp = p_cdname(cp, msg, file); | ||
| 307 | if (cp == NULL) | ||
| 308 | return; | ||
| 309 | if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) | ||
| 310 | fprintf(file, ", type = %s", | ||
| 311 | __p_type(_getshort(cp))); | ||
| 312 | cp += sizeof(u_int16_t); | ||
| 313 | if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) | ||
| 314 | fprintf(file, ", class = %s\n\n", | ||
| 315 | __p_class(_getshort(cp))); | ||
| 316 | cp += sizeof(u_int16_t); | ||
| 317 | } | ||
| 318 | } | ||
| 319 | /* | ||
| 320 | * Print authoritative answer records | ||
| 321 | */ | ||
| 322 | cp = do_rrset(msg, cp, hp->ancount, RES_PRF_ANS, file, | ||
| 323 | ";; ANSWERS:\n"); | ||
| 324 | if (cp == NULL) | ||
| 325 | return; | ||
| 326 | |||
| 327 | /* | ||
| 328 | * print name server records | ||
| 329 | */ | ||
| 330 | cp = do_rrset(msg, cp, hp->nscount, RES_PRF_AUTH, file, | ||
| 331 | ";; AUTHORITY RECORDS:\n"); | ||
| 332 | if (!cp) | ||
| 333 | return; | ||
| 334 | |||
| 335 | /* | ||
| 336 | * print additional records | ||
| 337 | */ | ||
| 338 | cp = do_rrset(msg, cp, hp->arcount, RES_PRF_ADD, file, | ||
| 339 | ";; ADDITIONAL RECORDS:\n"); | ||
| 340 | if (!cp) | ||
| 341 | return; | ||
| 342 | } | ||
| 343 | |||
| 344 | char * | ||
| 345 | p_cdname(cp, msg, file) | ||
| 346 | char *cp, *msg; | ||
| 347 | FILE *file; | ||
| 348 | { | ||
| 349 | char name[MAXDNAME]; | ||
| 350 | int n; | ||
| 351 | |||
| 352 | if ((n = dn_expand((u_char *)msg, (u_char *)cp + MAXCDNAME, | ||
| 353 | (u_char *)cp, (u_char *)name, sizeof(name))) < 0) | ||
| 354 | return (NULL); | ||
| 355 | if (name[0] == '\0') | ||
| 356 | putc('.', file); | ||
| 357 | else | ||
| 358 | fputs(name, file); | ||
| 359 | return (cp + n); | ||
| 360 | } | ||
| 361 | |||
| 362 | char * | ||
| 363 | p_fqname(cp, msg, file) | ||
| 364 | char *cp, *msg; | ||
| 365 | FILE *file; | ||
| 366 | { | ||
| 367 | char name[MAXDNAME]; | ||
| 368 | int n, len; | ||
| 369 | |||
| 370 | if ((n = dn_expand((u_char *)msg, (u_char *)cp + MAXCDNAME, | ||
| 371 | (u_char *)cp, (u_char *)name, sizeof(name))) < 0) | ||
| 372 | return (NULL); | ||
| 373 | if (name[0] == '\0') { | ||
| 374 | putc('.', file); | ||
| 375 | } else { | ||
| 376 | fputs(name, file); | ||
| 377 | if (name[strlen(name) - 1] != '.') | ||
| 378 | putc('.', file); | ||
| 379 | } | ||
| 380 | return (cp + n); | ||
| 381 | } | ||
| 382 | |||
| 383 | /* | ||
| 384 | * Print resource record fields in human readable form. | ||
| 385 | */ | ||
| 386 | char * | ||
| 387 | p_rr(cp, msg, file) | ||
| 388 | char *cp, *msg; | ||
| 389 | FILE *file; | ||
| 390 | { | ||
| 391 | int type, class, dlen, n, c; | ||
| 392 | struct in_addr inaddr; | ||
| 393 | char *cp1, *cp2; | ||
| 394 | u_int32_t tmpttl, t; | ||
| 395 | int lcnt; | ||
| 396 | |||
| 397 | if ((cp = p_fqname(cp, msg, file)) == NULL) | ||
| 398 | return (NULL); /* compression error */ | ||
| 399 | type = _getshort(cp); | ||
| 400 | cp += sizeof(u_int16_t); | ||
| 401 | class = _getshort(cp); | ||
| 402 | cp += sizeof(u_int16_t); | ||
| 403 | tmpttl = _getlong(cp); | ||
| 404 | cp += sizeof(u_int32_t); | ||
| 405 | dlen = _getshort(cp); | ||
| 406 | cp += sizeof(u_int16_t); | ||
| 407 | cp1 = cp; | ||
| 408 | if ((!_res.pfcode) || (_res.pfcode & RES_PRF_TTLID)) | ||
| 409 | fprintf(file, "\t%lu", tmpttl); | ||
| 410 | if ((!_res.pfcode) || (_res.pfcode & RES_PRF_CLASS)) | ||
| 411 | fprintf(file, "\t%s", __p_class(class)); | ||
| 412 | fprintf(file, "\t%s", __p_type(type)); | ||
| 413 | /* | ||
| 414 | * Print type specific data, if appropriate | ||
| 415 | */ | ||
| 416 | switch (type) { | ||
| 417 | case T_A: | ||
| 418 | switch (class) { | ||
| 419 | case C_IN: | ||
| 420 | case C_HS: | ||
| 421 | bcopy(cp, (char *)&inaddr, sizeof(inaddr)); | ||
| 422 | if (dlen == 4) { | ||
| 423 | fprintf(file,"\t%s", inet_ntoa(inaddr)); | ||
| 424 | cp += dlen; | ||
| 425 | } else if (dlen == 7) { | ||
| 426 | char *address; | ||
| 427 | u_char protocol; | ||
| 428 | u_short port; | ||
| 429 | |||
| 430 | address = inet_ntoa(inaddr); | ||
| 431 | cp += sizeof(inaddr); | ||
| 432 | protocol = *(u_char*)cp; | ||
| 433 | cp += sizeof(u_char); | ||
| 434 | port = _getshort(cp); | ||
| 435 | cp += sizeof(u_int16_t); | ||
| 436 | fprintf(file, "\t%s\t; proto %d, port %d", | ||
| 437 | address, protocol, port); | ||
| 438 | } | ||
| 439 | break; | ||
| 440 | default: | ||
| 441 | cp += dlen; | ||
| 442 | } | ||
| 443 | break; | ||
| 444 | case T_CNAME: | ||
| 445 | case T_MB: | ||
| 446 | case T_MG: | ||
| 447 | case T_MR: | ||
| 448 | case T_NS: | ||
| 449 | case T_PTR: | ||
| 450 | putc('\t', file); | ||
| 451 | cp = p_fqname(cp, msg, file); | ||
| 452 | break; | ||
| 453 | |||
| 454 | case T_HINFO: | ||
| 455 | if (n = *cp++) { | ||
| 456 | fprintf(file,"\t%.*s", n, cp); | ||
| 457 | cp += n; | ||
| 458 | } | ||
| 459 | if (n = *cp++) { | ||
| 460 | fprintf(file,"\t%.*s", n, cp); | ||
| 461 | cp += n; | ||
| 462 | } | ||
| 463 | break; | ||
| 464 | |||
| 465 | case T_SOA: | ||
| 466 | putc('\t', file); | ||
| 467 | cp = p_fqname(cp, msg, file); /* origin */ | ||
| 468 | putc(' ', file); | ||
| 469 | cp = p_fqname(cp, msg, file); /* mail addr */ | ||
| 470 | fputs(" (\n", file); | ||
| 471 | t = _getlong(cp); cp += sizeof(u_int32_t); | ||
| 472 | fprintf(file,"\t\t\t%lu\t; serial\n", t); | ||
| 473 | t = _getlong(cp); cp += sizeof(u_int32_t); | ||
| 474 | fprintf(file,"\t\t\t%lu\t; refresh (%s)\n", t, __p_time(t)); | ||
| 475 | t = _getlong(cp); cp += sizeof(u_int32_t); | ||
| 476 | fprintf(file,"\t\t\t%lu\t; retry (%s)\n", t, __p_time(t)); | ||
| 477 | t = _getlong(cp); cp += sizeof(u_int32_t); | ||
| 478 | fprintf(file,"\t\t\t%lu\t; expire (%s)\n", t, __p_time(t)); | ||
| 479 | t = _getlong(cp); cp += sizeof(u_int32_t); | ||
| 480 | fprintf(file,"\t\t\t%lu )\t; minimum (%s)", t, __p_time(t)); | ||
| 481 | break; | ||
| 482 | |||
| 483 | case T_MX: | ||
| 484 | case T_AFSDB: | ||
| 485 | fprintf(file,"\t%d ", _getshort(cp)); | ||
| 486 | cp += sizeof(u_int16_t); | ||
| 487 | cp = p_fqname(cp, msg, file); | ||
| 488 | break; | ||
| 489 | |||
| 490 | case T_TXT: | ||
| 491 | (void) fputs("\t\"", file); | ||
| 492 | cp2 = cp1 + dlen; | ||
| 493 | while (cp < cp2) { | ||
| 494 | if (n = (unsigned char) *cp++) { | ||
| 495 | for (c = n; c > 0 && cp < cp2; c--) | ||
| 496 | if (*cp == '\n') { | ||
| 497 | (void) putc('\\', file); | ||
| 498 | (void) putc(*cp++, file); | ||
| 499 | } else | ||
| 500 | (void) putc(*cp++, file); | ||
| 501 | } | ||
| 502 | } | ||
| 503 | putc('"', file); | ||
| 504 | break; | ||
| 505 | |||
| 506 | case T_MINFO: | ||
| 507 | case T_RP: | ||
| 508 | putc('\t', file); | ||
| 509 | cp = p_fqname(cp, msg, file); | ||
| 510 | putc(' ', file); | ||
| 511 | cp = p_fqname(cp, msg, file); | ||
| 512 | break; | ||
| 513 | |||
| 514 | case T_UINFO: | ||
| 515 | putc('\t', file); | ||
| 516 | fputs(cp, file); | ||
| 517 | cp += dlen; | ||
| 518 | break; | ||
| 519 | |||
| 520 | case T_UID: | ||
| 521 | case T_GID: | ||
| 522 | if (dlen == 4) { | ||
| 523 | fprintf(file,"\t%u", _getlong(cp)); | ||
| 524 | cp += sizeof(int32_t); | ||
| 525 | } | ||
| 526 | break; | ||
| 527 | |||
| 528 | case T_WKS: | ||
| 529 | if (dlen < sizeof(u_int32_t) + 1) | ||
| 530 | break; | ||
| 531 | bcopy(cp, (char *)&inaddr, sizeof(inaddr)); | ||
| 532 | cp += sizeof(u_int32_t); | ||
| 533 | fprintf(file, "\t%s %s ( ", | ||
| 534 | inet_ntoa(inaddr), | ||
| 535 | deproto((int) *cp)); | ||
| 536 | cp += sizeof(u_char); | ||
| 537 | n = 0; | ||
| 538 | lcnt = 0; | ||
| 539 | while (cp < cp1 + dlen) { | ||
| 540 | c = *cp++; | ||
| 541 | do { | ||
| 542 | if (c & 0200) { | ||
| 543 | if (lcnt == 0) { | ||
| 544 | fputs("\n\t\t\t", file); | ||
| 545 | lcnt = 5; | ||
| 546 | } | ||
| 547 | fputs(dewks(n), file); | ||
| 548 | putc(' ', file); | ||
| 549 | lcnt--; | ||
| 550 | } | ||
| 551 | c <<= 1; | ||
| 552 | } while (++n & 07); | ||
| 553 | } | ||
| 554 | putc(')', file); | ||
| 555 | break; | ||
| 556 | |||
| 557 | #ifdef ALLOW_T_UNSPEC | ||
| 558 | case T_UNSPEC: | ||
| 559 | { | ||
| 560 | int NumBytes = 8; | ||
| 561 | char *DataPtr; | ||
| 562 | int i; | ||
| 563 | |||
| 564 | if (dlen < NumBytes) NumBytes = dlen; | ||
| 565 | fprintf(file, "\tFirst %d bytes of hex data:", | ||
| 566 | NumBytes); | ||
| 567 | for (i = 0, DataPtr = cp; i < NumBytes; i++, DataPtr++) | ||
| 568 | fprintf(file, " %x", *DataPtr); | ||
| 569 | cp += dlen; | ||
| 570 | } | ||
| 571 | break; | ||
| 572 | #endif /* ALLOW_T_UNSPEC */ | ||
| 573 | |||
| 574 | default: | ||
| 575 | fprintf(file,"\t?%d?", type); | ||
| 576 | cp += dlen; | ||
| 577 | } | ||
| 578 | #if 0 | ||
| 579 | fprintf(file, "\t; dlen=%d, ttl %s\n", dlen, __p_time(tmpttl)); | ||
| 580 | #else | ||
| 581 | putc('\n', file); | ||
| 582 | #endif | ||
| 583 | if (cp - cp1 != dlen) { | ||
| 584 | fprintf(file,";; packet size error (found %d, dlen was %d)\n", | ||
| 585 | cp - cp1, dlen); | ||
| 586 | cp = NULL; | ||
| 587 | } | ||
| 588 | return (cp); | ||
| 589 | } | ||
| 590 | |||
| 591 | static char nbuf[40]; | ||
| 592 | |||
| 593 | /* | ||
| 594 | * Return a string for the type | ||
| 595 | */ | ||
| 596 | char * | ||
| 597 | __p_type(type) | ||
| 598 | int type; | ||
| 599 | { | ||
| 600 | switch (type) { | ||
| 601 | case T_A: | ||
| 602 | return("A"); | ||
| 603 | case T_NS: /* authoritative server */ | ||
| 604 | return("NS"); | ||
| 605 | case T_CNAME: /* canonical name */ | ||
| 606 | return("CNAME"); | ||
| 607 | case T_SOA: /* start of authority zone */ | ||
| 608 | return("SOA"); | ||
| 609 | case T_MB: /* mailbox domain name */ | ||
| 610 | return("MB"); | ||
| 611 | case T_MG: /* mail group member */ | ||
| 612 | return("MG"); | ||
| 613 | case T_MR: /* mail rename name */ | ||
| 614 | return("MR"); | ||
| 615 | case T_NULL: /* null resource record */ | ||
| 616 | return("NULL"); | ||
| 617 | case T_WKS: /* well known service */ | ||
| 618 | return("WKS"); | ||
| 619 | case T_PTR: /* domain name pointer */ | ||
| 620 | return("PTR"); | ||
| 621 | case T_HINFO: /* host information */ | ||
| 622 | return("HINFO"); | ||
| 623 | case T_MINFO: /* mailbox information */ | ||
| 624 | return("MINFO"); | ||
| 625 | case T_MX: /* mail routing info */ | ||
| 626 | return("MX"); | ||
| 627 | case T_TXT: /* text */ | ||
| 628 | return("TXT"); | ||
| 629 | case T_RP: /* responsible person */ | ||
| 630 | return("RP"); | ||
| 631 | case T_AFSDB: /* AFS cell database */ | ||
| 632 | return("AFSDB"); | ||
| 633 | case T_AXFR: /* zone transfer */ | ||
| 634 | return("AXFR"); | ||
| 635 | case T_MAILB: /* mail box */ | ||
| 636 | return("MAILB"); | ||
| 637 | case T_MAILA: /* mail address */ | ||
| 638 | return("MAILA"); | ||
| 639 | case T_ANY: /* matches any type */ | ||
| 640 | return("ANY"); | ||
| 641 | case T_UINFO: | ||
| 642 | return("UINFO"); | ||
| 643 | case T_UID: | ||
| 644 | return("UID"); | ||
| 645 | case T_GID: | ||
| 646 | return("GID"); | ||
| 647 | #ifdef ALLOW_T_UNSPEC | ||
| 648 | case T_UNSPEC: | ||
| 649 | return("UNSPEC"); | ||
| 650 | #endif /* ALLOW_T_UNSPEC */ | ||
| 651 | |||
| 652 | default: | ||
| 653 | (void)sprintf(nbuf, "%d", type); | ||
| 654 | return(nbuf); | ||
| 655 | } | ||
| 656 | } | ||
| 657 | |||
| 658 | /* | ||
| 659 | * Return a mnemonic for class | ||
| 660 | */ | ||
| 661 | char * | ||
| 662 | __p_class(class) | ||
| 663 | int class; | ||
| 664 | { | ||
| 665 | |||
| 666 | switch (class) { | ||
| 667 | case C_IN: /* internet class */ | ||
| 668 | return("IN"); | ||
| 669 | case C_HS: /* hesiod class */ | ||
| 670 | return("HS"); | ||
| 671 | case C_ANY: /* matches any class */ | ||
| 672 | return("ANY"); | ||
| 673 | default: | ||
| 674 | (void)sprintf(nbuf, "%d", class); | ||
| 675 | return(nbuf); | ||
| 676 | } | ||
| 677 | } | ||
| 678 | |||
| 679 | /* | ||
| 680 | * Return a mnemonic for an option | ||
| 681 | */ | ||
| 682 | static char * | ||
| 683 | p_option(option) | ||
| 684 | u_int32_t option; | ||
| 685 | { | ||
| 686 | switch (option) { | ||
| 687 | case RES_INIT: return "init"; | ||
| 688 | case RES_DEBUG: return "debug"; | ||
| 689 | case RES_AAONLY: return "aaonly"; | ||
| 690 | case RES_USEVC: return "usevc"; | ||
| 691 | case RES_PRIMARY: return "primry"; | ||
| 692 | case RES_IGNTC: return "igntc"; | ||
| 693 | case RES_RECURSE: return "recurs"; | ||
| 694 | case RES_DEFNAMES: return "defnam"; | ||
| 695 | case RES_STAYOPEN: return "styopn"; | ||
| 696 | case RES_DNSRCH: return "dnsrch"; | ||
| 697 | default: sprintf(nbuf, "?0x%x?", option); return nbuf; | ||
| 698 | } | ||
| 699 | } | ||
| 700 | |||
| 701 | /* | ||
| 702 | * Return a mnemonic for a time to live | ||
| 703 | */ | ||
| 704 | char * | ||
| 705 | __p_time(value) | ||
| 706 | u_int32_t value; | ||
| 707 | { | ||
| 708 | int secs, mins, hours, days; | ||
| 709 | register char *p; | ||
| 710 | |||
| 711 | if (value == 0) { | ||
| 712 | strcpy(nbuf, "0 secs"); | ||
| 713 | return(nbuf); | ||
| 714 | } | ||
| 715 | |||
| 716 | secs = value % 60; | ||
| 717 | value /= 60; | ||
| 718 | mins = value % 60; | ||
| 719 | value /= 60; | ||
| 720 | hours = value % 24; | ||
| 721 | value /= 24; | ||
| 722 | days = value; | ||
| 723 | value = 0; | ||
| 724 | |||
| 725 | #define PLURALIZE(x) x, (x == 1) ? "" : "s" | ||
| 726 | p = nbuf; | ||
| 727 | if (days) { | ||
| 728 | (void)sprintf(p, "%d day%s", PLURALIZE(days)); | ||
| 729 | while (*++p); | ||
| 730 | } | ||
| 731 | if (hours) { | ||
| 732 | if (days) | ||
| 733 | *p++ = ' '; | ||
| 734 | (void)sprintf(p, "%d hour%s", PLURALIZE(hours)); | ||
| 735 | while (*++p); | ||
| 736 | } | ||
| 737 | if (mins) { | ||
| 738 | if (days || hours) | ||
| 739 | *p++ = ' '; | ||
| 740 | (void)sprintf(p, "%d min%s", PLURALIZE(mins)); | ||
| 741 | while (*++p); | ||
| 742 | } | ||
| 743 | if (secs || ! (days || hours || mins)) { | ||
| 744 | if (days || hours || mins) | ||
| 745 | *p++ = ' '; | ||
| 746 | (void)sprintf(p, "%d sec%s", PLURALIZE(secs)); | ||
| 747 | } | ||
| 748 | return(nbuf); | ||
| 749 | } | ||
diff --git a/src/lib/libc/net/res_debug_syms.c b/src/lib/libc/net/res_debug_syms.c new file mode 100644 index 0000000000..7e7d22c914 --- /dev/null +++ b/src/lib/libc/net/res_debug_syms.c | |||
| @@ -0,0 +1,189 @@ | |||
| 1 | /* $OpenBSD: res_debug_syms.c,v 1.1 2005/08/06 20:30:04 espie 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. 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 | * Portions Copyright (c) 1995 by International Business Machines, Inc. | ||
| 52 | * | ||
| 53 | * International Business Machines, Inc. (hereinafter called IBM) grants | ||
| 54 | * permission under its copyrights to use, copy, modify, and distribute this | ||
| 55 | * Software with or without fee, provided that the above copyright notice and | ||
| 56 | * all paragraphs of this notice appear in all copies, and that the name of IBM | ||
| 57 | * not be used in connection with the marketing of any product incorporating | ||
| 58 | * the Software or modifications thereof, without specific, written prior | ||
| 59 | * permission. | ||
| 60 | * | ||
| 61 | * To the extent it has a right to do so, IBM grants an immunity from suit | ||
| 62 | * under its patents, if any, for the use, sale or manufacture of products to | ||
| 63 | * the extent that such products are used for performing Domain Name System | ||
| 64 | * dynamic updates in TCP/IP networks by means of the Software. No immunity is | ||
| 65 | * granted for any product per se or for any other function of any product. | ||
| 66 | * | ||
| 67 | * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, | ||
| 68 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A | ||
| 69 | * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, | ||
| 70 | * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING | ||
| 71 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN | ||
| 72 | * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. | ||
| 73 | * --Copyright-- | ||
| 74 | */ | ||
| 75 | |||
| 76 | |||
| 77 | #include <sys/types.h> | ||
| 78 | #include <netinet/in.h> | ||
| 79 | #include <arpa/nameser.h> | ||
| 80 | |||
| 81 | #include <resolv.h> | ||
| 82 | #include <stdio.h> | ||
| 83 | |||
| 84 | /* | ||
| 85 | * Names of RR classes and qclasses. Classes and qclasses are the same, except | ||
| 86 | * that C_ANY is a qclass but not a class. (You can ask for records of class | ||
| 87 | * C_ANY, but you can't have any records of that class in the database.) | ||
| 88 | */ | ||
| 89 | const struct res_sym __p_class_syms[] = { | ||
| 90 | {C_IN, "IN"}, | ||
| 91 | {C_CHAOS, "CHAOS"}, | ||
| 92 | {C_HS, "HS"}, | ||
| 93 | {C_HS, "HESIOD"}, | ||
| 94 | {C_ANY, "ANY"}, | ||
| 95 | {C_IN, (char *)0} | ||
| 96 | }; | ||
| 97 | |||
| 98 | /* | ||
| 99 | * Names of RR types and qtypes. Types and qtypes are the same, except | ||
| 100 | * that T_ANY is a qtype but not a type. (You can ask for records of type | ||
| 101 | * T_ANY, but you can't have any records of that type in the database.) | ||
| 102 | */ | ||
| 103 | const struct res_sym __p_type_syms[] = { | ||
| 104 | {T_A, "A", "address"}, | ||
| 105 | {T_NS, "NS", "name server"}, | ||
| 106 | {T_MD, "MD", "mail destination (deprecated)"}, | ||
| 107 | {T_MF, "MF", "mail forwarder (deprecated)"}, | ||
| 108 | {T_CNAME, "CNAME", "canonical name"}, | ||
| 109 | {T_SOA, "SOA", "start of authority"}, | ||
| 110 | {T_MB, "MB", "mailbox"}, | ||
| 111 | {T_MG, "MG", "mail group member"}, | ||
| 112 | {T_MR, "MR", "mail rename"}, | ||
| 113 | {T_NULL, "NULL", "null"}, | ||
| 114 | {T_WKS, "WKS", "well-known service (deprecated)"}, | ||
| 115 | {T_PTR, "PTR", "domain name pointer"}, | ||
| 116 | {T_HINFO, "HINFO", "host information"}, | ||
| 117 | {T_MINFO, "MINFO", "mailbox information"}, | ||
| 118 | {T_MX, "MX", "mail exchanger"}, | ||
| 119 | {T_TXT, "TXT", "text"}, | ||
| 120 | {T_RP, "RP", "responsible person"}, | ||
| 121 | {T_AFSDB, "AFSDB", "DCE or AFS server"}, | ||
| 122 | {T_X25, "X25", "X25 address"}, | ||
| 123 | {T_ISDN, "ISDN", "ISDN address"}, | ||
| 124 | {T_RT, "RT", "router"}, | ||
| 125 | {T_NSAP, "NSAP", "nsap address"}, | ||
| 126 | {T_NSAP_PTR, "NSAP_PTR", "domain name pointer"}, | ||
| 127 | {T_SIG, "SIG", "signature"}, | ||
| 128 | {T_KEY, "KEY", "key"}, | ||
| 129 | {T_PX, "PX", "mapping information"}, | ||
| 130 | {T_GPOS, "GPOS", "geographical position (withdrawn)"}, | ||
| 131 | {T_AAAA, "AAAA", "IPv6 address"}, | ||
| 132 | {T_LOC, "LOC", "location"}, | ||
| 133 | {T_NXT, "NXT", "next valid name (unimplemented)"}, | ||
| 134 | {T_EID, "EID", "endpoint identifier (unimplemented)"}, | ||
| 135 | {T_NIMLOC, "NIMLOC", "NIMROD locator (unimplemented)"}, | ||
| 136 | {T_SRV, "SRV", "server selection"}, | ||
| 137 | {T_ATMA, "ATMA", "ATM address (unimplemented)"}, | ||
| 138 | {T_IXFR, "IXFR", "incremental zone transfer"}, | ||
| 139 | {T_AXFR, "AXFR", "zone transfer"}, | ||
| 140 | {T_MAILB, "MAILB", "mailbox-related data (deprecated)"}, | ||
| 141 | {T_MAILA, "MAILA", "mail agent (deprecated)"}, | ||
| 142 | {T_UINFO, "UINFO", "user information (nonstandard)"}, | ||
| 143 | {T_UID, "UID", "user ID (nonstandard)"}, | ||
| 144 | {T_GID, "GID", "group ID (nonstandard)"}, | ||
| 145 | {T_NAPTR, "NAPTR", "URN Naming Authority"}, | ||
| 146 | #ifdef ALLOW_T_UNSPEC | ||
| 147 | {T_UNSPEC, "UNSPEC", "unspecified data (nonstandard)"}, | ||
| 148 | #endif /* ALLOW_T_UNSPEC */ | ||
| 149 | {T_ANY, "ANY", "\"any\""}, | ||
| 150 | {0, NULL, NULL} | ||
| 151 | }; | ||
| 152 | |||
| 153 | const char * | ||
| 154 | __sym_ntos(const struct res_sym *syms, int number, int *success) | ||
| 155 | { | ||
| 156 | static char unname[20]; | ||
| 157 | |||
| 158 | for (; syms->name != 0; syms++) { | ||
| 159 | if (number == syms->number) { | ||
| 160 | if (success) | ||
| 161 | *success = 1; | ||
| 162 | return (syms->name); | ||
| 163 | } | ||
| 164 | } | ||
| 165 | |||
| 166 | snprintf(unname, sizeof unname, "%d", number); | ||
| 167 | if (success) | ||
| 168 | *success = 0; | ||
| 169 | return (unname); | ||
| 170 | } | ||
| 171 | |||
| 172 | /* | ||
| 173 | * Return a string for the type | ||
| 174 | */ | ||
| 175 | const char * | ||
| 176 | __p_type(int type) | ||
| 177 | { | ||
| 178 | return (__sym_ntos (__p_type_syms, type, (int *)0)); | ||
| 179 | } | ||
| 180 | |||
| 181 | /* | ||
| 182 | * Return a mnemonic for class | ||
| 183 | */ | ||
| 184 | const char * | ||
| 185 | __p_class(int class) | ||
| 186 | { | ||
| 187 | return (__sym_ntos (__p_class_syms, class, (int *)0)); | ||
| 188 | } | ||
| 189 | |||
diff --git a/src/lib/libc/net/res_init.c b/src/lib/libc/net/res_init.c deleted file mode 100644 index 33cc8d39f1..0000000000 --- a/src/lib/libc/net/res_init.c +++ /dev/null | |||
| @@ -1,394 +0,0 @@ | |||
| 1 | /* $NetBSD: res_init.c,v 1.8 1995/06/03 22:33:36 mycroft Exp $ */ | ||
| 2 | |||
| 3 | /*- | ||
| 4 | * Copyright (c) 1985, 1989, 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 | * Portions Copyright (c) 1993 by Digital Equipment Corporation. | ||
| 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, and that | ||
| 40 | * the name of Digital Equipment Corporation not be used in advertising or | ||
| 41 | * publicity pertaining to distribution of the document or software without | ||
| 42 | * specific, written prior permission. | ||
| 43 | * | ||
| 44 | * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL | ||
| 45 | * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES | ||
| 46 | * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT | ||
| 47 | * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | ||
| 48 | * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR | ||
| 49 | * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS | ||
| 50 | * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | ||
| 51 | * SOFTWARE. | ||
| 52 | * - | ||
| 53 | * --Copyright-- | ||
| 54 | */ | ||
| 55 | |||
| 56 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 57 | #if 0 | ||
| 58 | static char sccsid[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93"; | ||
| 59 | static char rcsid[] = "$Id: res_init.c,v 4.9.1.1 1993/05/02 22:43:03 vixie Rel "; | ||
| 60 | #else | ||
| 61 | static char rcsid[] = "$NetBSD: res_init.c,v 1.8 1995/06/03 22:33:36 mycroft Exp $"; | ||
| 62 | #endif | ||
| 63 | #endif /* LIBC_SCCS and not lint */ | ||
| 64 | |||
| 65 | #include <sys/param.h> | ||
| 66 | #include <sys/socket.h> | ||
| 67 | #include <netinet/in.h> | ||
| 68 | #include <arpa/inet.h> | ||
| 69 | #include <arpa/nameser.h> | ||
| 70 | #include <resolv.h> | ||
| 71 | #include <unistd.h> | ||
| 72 | #include <stdio.h> | ||
| 73 | #include <stdlib.h> | ||
| 74 | #include <string.h> | ||
| 75 | |||
| 76 | static void res_setoptions __P((char *, char *)); | ||
| 77 | static u_int32_t net_mask __P((struct in_addr)); | ||
| 78 | |||
| 79 | /* | ||
| 80 | * Resolver state default settings | ||
| 81 | */ | ||
| 82 | |||
| 83 | struct __res_state _res = { | ||
| 84 | RES_TIMEOUT, /* retransmition time interval */ | ||
| 85 | 4, /* number of times to retransmit */ | ||
| 86 | RES_DEFAULT, /* options flags */ | ||
| 87 | 1, /* number of name servers */ | ||
| 88 | }; | ||
| 89 | |||
| 90 | /* | ||
| 91 | * Set up default settings. If the configuration file exist, the values | ||
| 92 | * there will have precedence. Otherwise, the server address is set to | ||
| 93 | * INADDR_ANY and the default domain name comes from the gethostname(). | ||
| 94 | * | ||
| 95 | * The configuration file should only be used if you want to redefine your | ||
| 96 | * domain or run without a server on your machine. | ||
| 97 | * | ||
| 98 | * Return 0 if completes successfully, -1 on error | ||
| 99 | */ | ||
| 100 | res_init() | ||
| 101 | { | ||
| 102 | register FILE *fp; | ||
| 103 | register char *cp, **pp, *net; | ||
| 104 | register int n; | ||
| 105 | char buf[BUFSIZ], buf2[BUFSIZ]; | ||
| 106 | int nserv = 0; /* number of nameserver records read from file */ | ||
| 107 | int haveenv = 0; | ||
| 108 | int havesearch = 0; | ||
| 109 | int nsort = 0; | ||
| 110 | u_long mask; | ||
| 111 | |||
| 112 | _res.nsaddr.sin_len = sizeof(struct sockaddr_in); | ||
| 113 | _res.nsaddr.sin_family = AF_INET; | ||
| 114 | _res.nsaddr.sin_port = htons(NAMESERVER_PORT); | ||
| 115 | #ifdef USELOOPBACK | ||
| 116 | _res.nsaddr.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1); | ||
| 117 | #else | ||
| 118 | _res.nsaddr.sin_addr.s_addr = INADDR_ANY; | ||
| 119 | #endif | ||
| 120 | _res.nscount = 1; | ||
| 121 | _res.ndots = 1; | ||
| 122 | _res.pfcode = 0; | ||
| 123 | strncpy(_res.lookups, "f", sizeof _res.lookups); | ||
| 124 | |||
| 125 | /* Allow user to override the local domain definition */ | ||
| 126 | if ((cp = getenv("LOCALDOMAIN")) != NULL) { | ||
| 127 | (void)strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1); | ||
| 128 | if ((cp = strpbrk(_res.defdname, " \t\n")) != NULL) | ||
| 129 | *cp = '\0'; | ||
| 130 | haveenv++; | ||
| 131 | |||
| 132 | /* | ||
| 133 | * Set search list to be blank-separated strings | ||
| 134 | * from rest of env value. Permits users of LOCALDOMAIN | ||
| 135 | * to still have a search list, and anyone to set the | ||
| 136 | * one that they want to use as an individual (even more | ||
| 137 | * important now that the rfc1535 stuff restricts searches) | ||
| 138 | */ | ||
| 139 | cp = _res.defdname; | ||
| 140 | pp = _res.dnsrch; | ||
| 141 | *pp++ = cp; | ||
| 142 | for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) { | ||
| 143 | if (*cp == '\n') /* silly backwards compat */ | ||
| 144 | break; | ||
| 145 | else if (*cp == ' ' || *cp == '\t') { | ||
| 146 | *cp = 0; | ||
| 147 | n = 1; | ||
| 148 | } else if (n) { | ||
| 149 | *pp++ = cp; | ||
| 150 | n = 0; | ||
| 151 | havesearch = 1; | ||
| 152 | } | ||
| 153 | } | ||
| 154 | /* null terminate last domain if there are excess */ | ||
| 155 | while (*cp != '\0' && *cp != ' ' && *cp != '\t' && *cp != '\n') | ||
| 156 | cp++; | ||
| 157 | *cp = '\0'; | ||
| 158 | *pp++ = 0; | ||
| 159 | } | ||
| 160 | |||
| 161 | if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) { | ||
| 162 | strncpy(_res.lookups, "bf", sizeof _res.lookups); | ||
| 163 | |||
| 164 | /* read the config file */ | ||
| 165 | while (fgets(buf, sizeof(buf), fp) != NULL) { | ||
| 166 | /* skip comments */ | ||
| 167 | if ((*buf == ';') || (*buf == '#')) | ||
| 168 | continue; | ||
| 169 | /* read default domain name */ | ||
| 170 | if (!strncmp(buf, "domain", sizeof("domain") - 1)) { | ||
| 171 | if (haveenv) /* skip if have from environ */ | ||
| 172 | continue; | ||
| 173 | cp = buf + sizeof("domain") - 1; | ||
| 174 | while (*cp == ' ' || *cp == '\t') | ||
| 175 | cp++; | ||
| 176 | if ((*cp == '\0') || (*cp == '\n')) | ||
| 177 | continue; | ||
| 178 | (void)strncpy(_res.defdname, cp, | ||
| 179 | sizeof(_res.defdname) - 1); | ||
| 180 | if ((cp = strpbrk(_res.defdname, " \t\n")) != NULL) | ||
| 181 | *cp = '\0'; | ||
| 182 | havesearch = 0; | ||
| 183 | continue; | ||
| 184 | } | ||
| 185 | /* lookup types */ | ||
| 186 | if (!strncmp(buf, "lookup", sizeof("lookup") -1)) { | ||
| 187 | char *sp = NULL; | ||
| 188 | |||
| 189 | bzero(_res.lookups, sizeof _res.lookups); | ||
| 190 | cp = buf + sizeof("lookup") - 1; | ||
| 191 | for (n = 0;; cp++) { | ||
| 192 | if (n == MAXDNSLUS) | ||
| 193 | break; | ||
| 194 | if ((*cp == '\0') || (*cp == '\n')) { | ||
| 195 | if (sp) { | ||
| 196 | if (*sp=='y' || *sp=='b' || *sp=='f') | ||
| 197 | _res.lookups[n++] = *sp; | ||
| 198 | sp = NULL; | ||
| 199 | } | ||
| 200 | break; | ||
| 201 | } else if ((*cp == ' ') || (*cp == '\t') || (*cp == ',')) { | ||
| 202 | if (sp) { | ||
| 203 | if (*sp=='y' || *sp=='b' || *sp=='f') | ||
| 204 | _res.lookups[n++] = *sp; | ||
| 205 | sp = NULL; | ||
| 206 | } | ||
| 207 | } else if (sp == NULL) | ||
| 208 | sp = cp; | ||
| 209 | } | ||
| 210 | continue; | ||
| 211 | } | ||
| 212 | /* set search list */ | ||
| 213 | if (!strncmp(buf, "search", sizeof("search") - 1)) { | ||
| 214 | if (haveenv) /* skip if have from environ */ | ||
| 215 | continue; | ||
| 216 | cp = buf + sizeof("search") - 1; | ||
| 217 | while (*cp == ' ' || *cp == '\t') | ||
| 218 | cp++; | ||
| 219 | if ((*cp == '\0') || (*cp == '\n')) | ||
| 220 | continue; | ||
| 221 | (void)strncpy(_res.defdname, cp, | ||
| 222 | sizeof(_res.defdname) - 1); | ||
| 223 | if ((cp = strchr(_res.defdname, '\n')) != NULL) | ||
| 224 | *cp = '\0'; | ||
| 225 | /* | ||
| 226 | * Set search list to be blank-separated strings | ||
| 227 | * on rest of line. | ||
| 228 | */ | ||
| 229 | cp = _res.defdname; | ||
| 230 | pp = _res.dnsrch; | ||
| 231 | *pp++ = cp; | ||
| 232 | for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) { | ||
| 233 | if (*cp == ' ' || *cp == '\t') { | ||
| 234 | *cp = 0; | ||
| 235 | n = 1; | ||
| 236 | } else if (n) { | ||
| 237 | *pp++ = cp; | ||
| 238 | n = 0; | ||
| 239 | } | ||
| 240 | } | ||
| 241 | /* null terminate last domain if there are excess */ | ||
| 242 | while (*cp != '\0' && *cp != ' ' && *cp != '\t') | ||
| 243 | cp++; | ||
| 244 | *cp = '\0'; | ||
| 245 | *pp++ = 0; | ||
| 246 | havesearch = 1; | ||
| 247 | continue; | ||
| 248 | } | ||
| 249 | /* read nameservers to query */ | ||
| 250 | if (!strncmp(buf, "nameserver", sizeof("nameserver") - 1) && | ||
| 251 | nserv < MAXNS) { | ||
| 252 | struct in_addr a; | ||
| 253 | |||
| 254 | cp = buf + sizeof("nameserver") - 1; | ||
| 255 | while (*cp == ' ' || *cp == '\t') | ||
| 256 | cp++; | ||
| 257 | if ((*cp != '\0') && (*cp != '\n') && inet_aton(cp, &a)) { | ||
| 258 | _res.nsaddr_list[nserv].sin_len = sizeof(struct sockaddr_in); | ||
| 259 | _res.nsaddr_list[nserv].sin_family = AF_INET; | ||
| 260 | _res.nsaddr_list[nserv].sin_port = | ||
| 261 | htons(NAMESERVER_PORT); | ||
| 262 | _res.nsaddr_list[nserv].sin_addr = a; | ||
| 263 | nserv++; | ||
| 264 | } | ||
| 265 | continue; | ||
| 266 | } | ||
| 267 | if (!strncmp(buf, "sortlist", sizeof("sortlist") - 1)) { | ||
| 268 | struct in_addr a; | ||
| 269 | |||
| 270 | cp = buf + sizeof("sortlist") - 1; | ||
| 271 | while (*cp == ' ' || *cp == '\t') | ||
| 272 | cp++; | ||
| 273 | while (sscanf(cp,"%[0-9./]s", buf2) && nsort < MAXRESOLVSORT) { | ||
| 274 | if (net = strchr(buf2, '/')) | ||
| 275 | *net = '\0'; | ||
| 276 | if (inet_aton(buf2, &a)) { | ||
| 277 | _res.sort_list[nsort].addr = a; | ||
| 278 | if (net && inet_aton(net+1, &a)) { | ||
| 279 | _res.sort_list[nsort].mask = a.s_addr; | ||
| 280 | } else { | ||
| 281 | _res.sort_list[nsort].mask = | ||
| 282 | net_mask(_res.sort_list[nsort].addr); | ||
| 283 | } | ||
| 284 | nsort++; | ||
| 285 | } | ||
| 286 | if (net) | ||
| 287 | *net = '/'; | ||
| 288 | cp += strlen(buf2); | ||
| 289 | while (*cp == ' ' || *cp == '\t') | ||
| 290 | cp++; | ||
| 291 | } | ||
| 292 | continue; | ||
| 293 | } | ||
| 294 | if (!strncmp(buf, "options", sizeof("options") -1)) { | ||
| 295 | res_setoptions(buf + sizeof("options") - 1, "conf"); | ||
| 296 | continue; | ||
| 297 | } | ||
| 298 | } | ||
| 299 | if (nserv > 1) | ||
| 300 | _res.nscount = nserv; | ||
| 301 | _res.nsort = nsort; | ||
| 302 | (void) fclose(fp); | ||
| 303 | } | ||
| 304 | if (_res.defdname[0] == 0) { | ||
| 305 | if (gethostname(buf, sizeof(_res.defdname) - 1) == 0 && | ||
| 306 | (cp = strchr(buf, '.'))) | ||
| 307 | (void)strcpy(_res.defdname, cp + 1); | ||
| 308 | } | ||
| 309 | |||
| 310 | /* find components of local domain that might be searched */ | ||
| 311 | if (havesearch == 0) { | ||
| 312 | pp = _res.dnsrch; | ||
| 313 | *pp++ = _res.defdname; | ||
| 314 | #ifndef SEARCH_LOCAL_DOMAINS | ||
| 315 | *pp = NULL; | ||
| 316 | #else | ||
| 317 | for (cp = _res.defdname, n = 0; *cp; cp++) | ||
| 318 | if (*cp == '.') | ||
| 319 | n++; | ||
| 320 | cp = _res.defdname; | ||
| 321 | for (; n >= LOCALDOMAINPARTS && pp < _res.dnsrch + MAXDFLSRCH; | ||
| 322 | n--) { | ||
| 323 | cp = strchr(cp, '.'); | ||
| 324 | *pp++ = ++cp; | ||
| 325 | } | ||
| 326 | *pp++ = 0; | ||
| 327 | #endif | ||
| 328 | } | ||
| 329 | |||
| 330 | if ((cp = getenv("RES_OPTIONS")) != NULL) | ||
| 331 | res_setoptions(cp, "env"); | ||
| 332 | _res.options |= RES_INIT; | ||
| 333 | return (0); | ||
| 334 | } | ||
| 335 | |||
| 336 | static void | ||
| 337 | res_setoptions(options, source) | ||
| 338 | char *options, *source; | ||
| 339 | { | ||
| 340 | char *cp = options; | ||
| 341 | int i; | ||
| 342 | |||
| 343 | #ifdef DEBUG | ||
| 344 | if (_res.options & RES_DEBUG) { | ||
| 345 | printf(";; res_setoptions(\"%s\", \"%s\")...\n", | ||
| 346 | options, source); | ||
| 347 | } | ||
| 348 | #endif | ||
| 349 | while (*cp) { | ||
| 350 | /* skip leading and inner runs of spaces */ | ||
| 351 | while (*cp == ' ' || *cp == '\t') | ||
| 352 | cp++; | ||
| 353 | /* search for and process individual options */ | ||
| 354 | if (!strncmp(cp, "ndots:", sizeof("ndots:")-1)) { | ||
| 355 | i = atoi(cp + sizeof("ndots:") - 1); | ||
| 356 | if (i <= RES_MAXNDOTS) | ||
| 357 | _res.ndots = i; | ||
| 358 | else | ||
| 359 | _res.ndots = RES_MAXNDOTS; | ||
| 360 | #ifdef DEBUG | ||
| 361 | if (_res.options & RES_DEBUG) { | ||
| 362 | printf(";;\tndots=%d\n", _res.ndots); | ||
| 363 | } | ||
| 364 | #endif | ||
| 365 | } else if (!strncmp(cp, "debug", sizeof("debug")-1)) { | ||
| 366 | #ifdef DEBUG | ||
| 367 | if (!(_res.options & RES_DEBUG)) { | ||
| 368 | printf(";; res_setoptions(\"%s\", \"%s\")..\n", | ||
| 369 | options, source); | ||
| 370 | _res.options |= RES_DEBUG; | ||
| 371 | } | ||
| 372 | printf(";;\tdebug\n"); | ||
| 373 | #endif | ||
| 374 | } else { | ||
| 375 | /* XXX - print a warning here? */ | ||
| 376 | } | ||
| 377 | /* skip to next run of spaces */ | ||
| 378 | while (*cp && *cp != ' ' && *cp != '\t') | ||
| 379 | cp++; | ||
| 380 | } | ||
| 381 | } | ||
| 382 | |||
| 383 | static u_int32_t | ||
| 384 | net_mask(in) /* XXX - should really use system's version of this */ | ||
| 385 | struct in_addr in; | ||
| 386 | { | ||
| 387 | register u_int32_t i = ntohl(in.s_addr); | ||
| 388 | |||
| 389 | if (IN_CLASSA(i)) | ||
| 390 | return (htonl(IN_CLASSA_NET)); | ||
| 391 | if (IN_CLASSB(i)) | ||
| 392 | return (htonl(IN_CLASSB_NET)); | ||
| 393 | return (htonl(IN_CLASSC_NET)); | ||
| 394 | } | ||
diff --git a/src/lib/libc/net/res_mkquery.c b/src/lib/libc/net/res_mkquery.c deleted file mode 100644 index 25f025e147..0000000000 --- a/src/lib/libc/net/res_mkquery.c +++ /dev/null | |||
| @@ -1,236 +0,0 @@ | |||
| 1 | /* $NetBSD: res_mkquery.c,v 1.5 1995/02/25 06:20:58 cgd Exp $ */ | ||
| 2 | |||
| 3 | /*- | ||
| 4 | * Copyright (c) 1985, 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 | * Portions Copyright (c) 1993 by Digital Equipment Corporation. | ||
| 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, and that | ||
| 40 | * the name of Digital Equipment Corporation not be used in advertising or | ||
| 41 | * publicity pertaining to distribution of the document or software without | ||
| 42 | * specific, written prior permission. | ||
| 43 | * | ||
| 44 | * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL | ||
| 45 | * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES | ||
| 46 | * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT | ||
| 47 | * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | ||
| 48 | * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR | ||
| 49 | * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS | ||
| 50 | * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | ||
| 51 | * SOFTWARE. | ||
| 52 | * - | ||
| 53 | * --Copyright-- | ||
| 54 | */ | ||
| 55 | |||
| 56 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 57 | #if 0 | ||
| 58 | static char sccsid[] = "@(#)res_mkquery.c 8.1 (Berkeley) 6/4/93"; | ||
| 59 | static char rcsid[] = "$Id: res_mkquery.c,v 4.9.1.2 1993/05/17 10:00:01 vixie Exp "; | ||
| 60 | #else | ||
| 61 | static char rcsid[] = "$NetBSD: res_mkquery.c,v 1.5 1995/02/25 06:20:58 cgd Exp $"; | ||
| 62 | #endif | ||
| 63 | #endif /* LIBC_SCCS and not lint */ | ||
| 64 | |||
| 65 | #include <sys/param.h> | ||
| 66 | #include <netinet/in.h> | ||
| 67 | #include <arpa/nameser.h> | ||
| 68 | #include <resolv.h> | ||
| 69 | #include <stdio.h> | ||
| 70 | #include <string.h> | ||
| 71 | |||
| 72 | /* | ||
| 73 | * Form all types of queries. | ||
| 74 | * Returns the size of the result or -1. | ||
| 75 | */ | ||
| 76 | res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen) | ||
| 77 | int op; /* opcode of query */ | ||
| 78 | const char *dname; /* domain name */ | ||
| 79 | int class, type; /* class and type of query */ | ||
| 80 | const char *data; /* resource record data */ | ||
| 81 | int datalen; /* length of data */ | ||
| 82 | const char *newrr_in; /* new rr for modify or append */ | ||
| 83 | char *buf; /* buffer to put query */ | ||
| 84 | int buflen; /* size of buffer */ | ||
| 85 | { | ||
| 86 | register HEADER *hp; | ||
| 87 | register char *cp; | ||
| 88 | register int n; | ||
| 89 | struct rrec *newrr = (struct rrec *) newrr_in; | ||
| 90 | char *dnptrs[10], **dpp, **lastdnptr; | ||
| 91 | |||
| 92 | #ifdef DEBUG | ||
| 93 | if (_res.options & RES_DEBUG) | ||
| 94 | printf(";; res_mkquery(%d, %s, %d, %d)\n", | ||
| 95 | op, dname, class, type); | ||
| 96 | #endif | ||
| 97 | /* | ||
| 98 | * Initialize header fields. | ||
| 99 | */ | ||
| 100 | if ((buf == NULL) || (buflen < sizeof(HEADER))) | ||
| 101 | return(-1); | ||
| 102 | bzero(buf, sizeof(HEADER)); | ||
| 103 | hp = (HEADER *) buf; | ||
| 104 | hp->id = htons(++_res.id); | ||
| 105 | hp->opcode = op; | ||
| 106 | hp->pr = (_res.options & RES_PRIMARY) != 0; | ||
| 107 | hp->rd = (_res.options & RES_RECURSE) != 0; | ||
| 108 | hp->rcode = NOERROR; | ||
| 109 | cp = buf + sizeof(HEADER); | ||
| 110 | buflen -= sizeof(HEADER); | ||
| 111 | dpp = dnptrs; | ||
| 112 | *dpp++ = buf; | ||
| 113 | *dpp++ = NULL; | ||
| 114 | lastdnptr = dnptrs + sizeof(dnptrs)/sizeof(dnptrs[0]); | ||
| 115 | /* | ||
| 116 | * perform opcode specific processing | ||
| 117 | */ | ||
| 118 | switch (op) { | ||
| 119 | case QUERY: | ||
| 120 | if ((buflen -= QFIXEDSZ) < 0) | ||
| 121 | return(-1); | ||
| 122 | if ((n = dn_comp((u_char *)dname, (u_char *)cp, buflen, | ||
| 123 | (u_char **)dnptrs, (u_char **)lastdnptr)) < 0) | ||
| 124 | return (-1); | ||
| 125 | cp += n; | ||
| 126 | buflen -= n; | ||
| 127 | __putshort(type, (u_char *)cp); | ||
| 128 | cp += sizeof(u_int16_t); | ||
| 129 | __putshort(class, (u_char *)cp); | ||
| 130 | cp += sizeof(u_int16_t); | ||
| 131 | hp->qdcount = htons(1); | ||
| 132 | if (op == QUERY || data == NULL) | ||
| 133 | break; | ||
| 134 | /* | ||
| 135 | * Make an additional record for completion domain. | ||
| 136 | */ | ||
| 137 | buflen -= RRFIXEDSZ; | ||
| 138 | if ((n = dn_comp((u_char *)data, (u_char *)cp, buflen, | ||
| 139 | (u_char **)dnptrs, (u_char **)lastdnptr)) < 0) | ||
| 140 | return (-1); | ||
| 141 | cp += n; | ||
| 142 | buflen -= n; | ||
| 143 | __putshort(T_NULL, (u_char *)cp); | ||
| 144 | cp += sizeof(u_int16_t); | ||
| 145 | __putshort(class, (u_char *)cp); | ||
| 146 | cp += sizeof(u_int16_t); | ||
| 147 | __putlong(0, (u_char *)cp); | ||
| 148 | cp += sizeof(u_int32_t); | ||
| 149 | __putshort(0, (u_char *)cp); | ||
| 150 | cp += sizeof(u_int16_t); | ||
| 151 | hp->arcount = htons(1); | ||
| 152 | break; | ||
| 153 | |||
| 154 | case IQUERY: | ||
| 155 | /* | ||
| 156 | * Initialize answer section | ||
| 157 | */ | ||
| 158 | if (buflen < 1 + RRFIXEDSZ + datalen) | ||
| 159 | return (-1); | ||
| 160 | *cp++ = '\0'; /* no domain name */ | ||
| 161 | __putshort(type, (u_char *)cp); | ||
| 162 | cp += sizeof(u_int16_t); | ||
| 163 | __putshort(class, (u_char *)cp); | ||
| 164 | cp += sizeof(u_int16_t); | ||
| 165 | __putlong(0, (u_char *)cp); | ||
| 166 | cp += sizeof(u_int32_t); | ||
| 167 | __putshort(datalen, (u_char *)cp); | ||
| 168 | cp += sizeof(u_int16_t); | ||
| 169 | if (datalen) { | ||
| 170 | bcopy(data, cp, datalen); | ||
| 171 | cp += datalen; | ||
| 172 | } | ||
| 173 | hp->ancount = htons(1); | ||
| 174 | break; | ||
| 175 | |||
| 176 | #ifdef ALLOW_UPDATES | ||
| 177 | /* | ||
| 178 | * For UPDATEM/UPDATEMA, do UPDATED/UPDATEDA followed by UPDATEA | ||
| 179 | * (Record to be modified is followed by its replacement in msg.) | ||
| 180 | */ | ||
| 181 | case UPDATEM: | ||
| 182 | case UPDATEMA: | ||
| 183 | |||
| 184 | case UPDATED: | ||
| 185 | /* | ||
| 186 | * The res code for UPDATED and UPDATEDA is the same; user | ||
| 187 | * calls them differently: specifies data for UPDATED; server | ||
| 188 | * ignores data if specified for UPDATEDA. | ||
| 189 | */ | ||
| 190 | case UPDATEDA: | ||
| 191 | buflen -= RRFIXEDSZ + datalen; | ||
| 192 | if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0) | ||
| 193 | return (-1); | ||
| 194 | cp += n; | ||
| 195 | __putshort(type, cp); | ||
| 196 | cp += sizeof(u_int16_t); | ||
| 197 | __putshort(class, cp); | ||
| 198 | cp += sizeof(u_int16_t); | ||
| 199 | __putlong(0, cp); | ||
| 200 | cp += sizeof(u_int32_t); | ||
| 201 | __putshort(datalen, cp); | ||
| 202 | cp += sizeof(u_int16_t); | ||
| 203 | if (datalen) { | ||
| 204 | bcopy(data, cp, datalen); | ||
| 205 | cp += datalen; | ||
| 206 | } | ||
| 207 | if ( (op == UPDATED) || (op == UPDATEDA) ) { | ||
| 208 | hp->ancount = htons(0); | ||
| 209 | break; | ||
| 210 | } | ||
| 211 | /* Else UPDATEM/UPDATEMA, so drop into code for UPDATEA */ | ||
| 212 | |||
| 213 | case UPDATEA: /* Add new resource record */ | ||
| 214 | buflen -= RRFIXEDSZ + datalen; | ||
| 215 | if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0) | ||
| 216 | return (-1); | ||
| 217 | cp += n; | ||
| 218 | __putshort(newrr->r_type, cp); | ||
| 219 | cp += sizeof(u_int16_t); | ||
| 220 | __putshort(newrr->r_class, cp); | ||
| 221 | cp += sizeof(u_int16_t); | ||
| 222 | __putlong(0, cp); | ||
| 223 | cp += sizeof(u_int32_t); | ||
| 224 | __putshort(newrr->r_size, cp); | ||
| 225 | cp += sizeof(u_int16_t); | ||
| 226 | if (newrr->r_size) { | ||
| 227 | bcopy(newrr->r_data, cp, newrr->r_size); | ||
| 228 | cp += newrr->r_size; | ||
| 229 | } | ||
| 230 | hp->ancount = htons(0); | ||
| 231 | break; | ||
| 232 | |||
| 233 | #endif /* ALLOW_UPDATES */ | ||
| 234 | } | ||
| 235 | return (cp - buf); | ||
| 236 | } | ||
diff --git a/src/lib/libc/net/res_query.c b/src/lib/libc/net/res_query.c deleted file mode 100644 index 7649462e56..0000000000 --- a/src/lib/libc/net/res_query.c +++ /dev/null | |||
| @@ -1,366 +0,0 @@ | |||
| 1 | /* $NetBSD: res_query.c,v 1.9 1995/02/25 06:58:58 cgd 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 | * Portions Copyright (c) 1993 by Digital Equipment Corporation. | ||
| 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, and that | ||
| 40 | * the name of Digital Equipment Corporation not be used in advertising or | ||
| 41 | * publicity pertaining to distribution of the document or software without | ||
| 42 | * specific, written prior permission. | ||
| 43 | * | ||
| 44 | * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL | ||
| 45 | * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES | ||
| 46 | * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT | ||
| 47 | * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | ||
| 48 | * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR | ||
| 49 | * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS | ||
| 50 | * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | ||
| 51 | * SOFTWARE. | ||
| 52 | * - | ||
| 53 | * --Copyright-- | ||
| 54 | */ | ||
| 55 | |||
| 56 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 57 | #if 0 | ||
| 58 | static char sccsid[] = "@(#)res_query.c 8.1 (Berkeley) 6/4/93"; | ||
| 59 | static char rcsid[] = "$Id: res_query.c,v 1.1 1993/06/01 09:42:14 vixie Exp vixie "; | ||
| 60 | #else | ||
| 61 | static char rcsid[] = "$NetBSD: res_query.c,v 1.9 1995/02/25 06:58:58 cgd Exp $"; | ||
| 62 | #endif | ||
| 63 | #endif /* LIBC_SCCS and not lint */ | ||
| 64 | |||
| 65 | #include <sys/param.h> | ||
| 66 | #include <netinet/in.h> | ||
| 67 | #include <arpa/inet.h> | ||
| 68 | #include <arpa/nameser.h> | ||
| 69 | #include <netdb.h> | ||
| 70 | #include <resolv.h> | ||
| 71 | #include <stdio.h> | ||
| 72 | #include <ctype.h> | ||
| 73 | #include <errno.h> | ||
| 74 | #include <stdlib.h> | ||
| 75 | #include <string.h> | ||
| 76 | |||
| 77 | #if PACKETSZ > 1024 | ||
| 78 | #define MAXPACKET PACKETSZ | ||
| 79 | #else | ||
| 80 | #define MAXPACKET 1024 | ||
| 81 | #endif | ||
| 82 | |||
| 83 | char *__hostalias __P((const char *)); | ||
| 84 | int h_errno; | ||
| 85 | |||
| 86 | /* | ||
| 87 | * Formulate a normal query, send, and await answer. | ||
| 88 | * Returned answer is placed in supplied buffer "answer". | ||
| 89 | * Perform preliminary check of answer, returning success only | ||
| 90 | * if no error is indicated and the answer count is nonzero. | ||
| 91 | * Return the size of the response on success, -1 on error. | ||
| 92 | * Error number is left in h_errno. | ||
| 93 | * Caller must parse answer and determine whether it answers the question. | ||
| 94 | */ | ||
| 95 | res_query(name, class, type, answer, anslen) | ||
| 96 | char *name; /* domain name */ | ||
| 97 | int class, type; /* class and type of query */ | ||
| 98 | u_char *answer; /* buffer to put answer */ | ||
| 99 | int anslen; /* size of answer buffer */ | ||
| 100 | { | ||
| 101 | char buf[MAXPACKET]; | ||
| 102 | HEADER *hp; | ||
| 103 | int n; | ||
| 104 | |||
| 105 | if ((_res.options & RES_INIT) == 0 && res_init() == -1) | ||
| 106 | return (-1); | ||
| 107 | #ifdef DEBUG | ||
| 108 | if (_res.options & RES_DEBUG) | ||
| 109 | printf(";; res_query(%s, %d, %d)\n", name, class, type); | ||
| 110 | #endif | ||
| 111 | n = res_mkquery(QUERY, name, class, type, (char *)NULL, 0, NULL, | ||
| 112 | buf, sizeof(buf)); | ||
| 113 | |||
| 114 | if (n <= 0) { | ||
| 115 | #ifdef DEBUG | ||
| 116 | if (_res.options & RES_DEBUG) | ||
| 117 | printf(";; res_query: mkquery failed\n"); | ||
| 118 | #endif | ||
| 119 | h_errno = NO_RECOVERY; | ||
| 120 | return (n); | ||
| 121 | } | ||
| 122 | n = res_send(buf, n, (char *)answer, anslen); | ||
| 123 | if (n < 0) { | ||
| 124 | #ifdef DEBUG | ||
| 125 | if (_res.options & RES_DEBUG) | ||
| 126 | printf(";; res_query: send error\n"); | ||
| 127 | #endif | ||
| 128 | h_errno = TRY_AGAIN; | ||
| 129 | return (n); | ||
| 130 | } | ||
| 131 | |||
| 132 | hp = (HEADER *) answer; | ||
| 133 | if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) { | ||
| 134 | #ifdef DEBUG | ||
| 135 | if (_res.options & RES_DEBUG) | ||
| 136 | printf(";; rcode = %d, ancount=%d\n", hp->rcode, | ||
| 137 | ntohs(hp->ancount)); | ||
| 138 | #endif | ||
| 139 | switch (hp->rcode) { | ||
| 140 | case NXDOMAIN: | ||
| 141 | h_errno = HOST_NOT_FOUND; | ||
| 142 | break; | ||
| 143 | case SERVFAIL: | ||
| 144 | h_errno = TRY_AGAIN; | ||
| 145 | break; | ||
| 146 | case NOERROR: | ||
| 147 | h_errno = NO_DATA; | ||
| 148 | break; | ||
| 149 | case FORMERR: | ||
| 150 | case NOTIMP: | ||
| 151 | case REFUSED: | ||
| 152 | default: | ||
| 153 | h_errno = NO_RECOVERY; | ||
| 154 | break; | ||
| 155 | } | ||
| 156 | return (-1); | ||
| 157 | } | ||
| 158 | return (n); | ||
| 159 | } | ||
| 160 | |||
| 161 | /* | ||
| 162 | * Formulate a normal query, send, and retrieve answer in supplied buffer. | ||
| 163 | * Return the size of the response on success, -1 on error. | ||
| 164 | * If enabled, implement search rules until answer or unrecoverable failure | ||
| 165 | * is detected. Error number is left in h_errno. | ||
| 166 | * Only useful for queries in the same name hierarchy as the local host | ||
| 167 | * (not, for example, for host address-to-name lookups in domain in-addr.arpa). | ||
| 168 | */ | ||
| 169 | int | ||
| 170 | res_search(name, class, type, answer, anslen) | ||
| 171 | const char *name; /* domain name */ | ||
| 172 | int class, type; /* class and type of query */ | ||
| 173 | u_char *answer; /* buffer to put answer */ | ||
| 174 | int anslen; /* size of answer */ | ||
| 175 | { | ||
| 176 | register char *cp, **domain; | ||
| 177 | int dots, trailing_dot, ret, got_nodata, saved_herrno, tried_as_is; | ||
| 178 | |||
| 179 | if ((_res.options & RES_INIT) == 0 && res_init() == -1) | ||
| 180 | return (-1); | ||
| 181 | |||
| 182 | got_nodata = 0; | ||
| 183 | errno = 0; | ||
| 184 | h_errno = HOST_NOT_FOUND; /* default, if we never query */ | ||
| 185 | dots = 0; | ||
| 186 | for (cp = (char *)name; *cp; cp++) { | ||
| 187 | if (*cp == '.') | ||
| 188 | dots++; | ||
| 189 | } | ||
| 190 | trailing_dot = 0; | ||
| 191 | if ((cp > name) && (*--cp == '.')) | ||
| 192 | trailing_dot++; | ||
| 193 | |||
| 194 | /* | ||
| 195 | * if there aren't any dots, it could be a user-level alias | ||
| 196 | */ | ||
| 197 | if (!dots && (cp = __hostalias(name))) | ||
| 198 | return (res_query(cp, class, type, answer, anslen)); | ||
| 199 | |||
| 200 | /* | ||
| 201 | * If there are dots in the name already, let's just give it a try | ||
| 202 | * 'as is'. The threshold can be set with the "ndots" option. | ||
| 203 | */ | ||
| 204 | saved_herrno = -1; | ||
| 205 | tried_as_is = 0; | ||
| 206 | if (dots >= _res.ndots) { | ||
| 207 | ret = res_querydomain(name, NULL, class, type, answer, anslen); | ||
| 208 | if (ret > 0) | ||
| 209 | return (ret); | ||
| 210 | saved_herrno = h_errno; | ||
| 211 | tried_as_is++; | ||
| 212 | } | ||
| 213 | |||
| 214 | /* | ||
| 215 | * We do at least one level of search if | ||
| 216 | * - there is no dot and RES_DEFNAME is set, or | ||
| 217 | * - there is at least one dot, there is no trailing dot, | ||
| 218 | * and RES_DNSRCH is set. | ||
| 219 | */ | ||
| 220 | if ((!dots && (_res.options & RES_DEFNAMES)) || | ||
| 221 | (dots && !trailing_dot && (_res.options & RES_DNSRCH))) { | ||
| 222 | for (domain = _res.dnsrch; *domain; domain++) { | ||
| 223 | int done = 0; | ||
| 224 | |||
| 225 | ret = res_querydomain(name, *domain, class, type, | ||
| 226 | answer, anslen); | ||
| 227 | if (ret > 0) | ||
| 228 | return (ret); | ||
| 229 | /* | ||
| 230 | * If no server present, give up. | ||
| 231 | * If name isn't found in this domain, | ||
| 232 | * keep trying higher domains in the search list | ||
| 233 | * (if that's enabled). | ||
| 234 | * On a NO_DATA error, keep trying, otherwise | ||
| 235 | * a wildcard entry of another type could keep us | ||
| 236 | * from finding this entry higher in the domain. | ||
| 237 | * If we get some other error (negative answer or | ||
| 238 | * server failure), then stop searching up, | ||
| 239 | * but try the input name below in case it's | ||
| 240 | * fully-qualified. | ||
| 241 | */ | ||
| 242 | if (errno == ECONNREFUSED) { | ||
| 243 | h_errno = TRY_AGAIN; | ||
| 244 | return (-1); | ||
| 245 | } | ||
| 246 | |||
| 247 | switch (h_errno) { | ||
| 248 | case NO_DATA: | ||
| 249 | got_nodata++; | ||
| 250 | /* FALLTHROUGH */ | ||
| 251 | case HOST_NOT_FOUND: | ||
| 252 | /* keep trying */ | ||
| 253 | break; | ||
| 254 | default: | ||
| 255 | /* anything else implies that we're done */ | ||
| 256 | done++; | ||
| 257 | } | ||
| 258 | /* | ||
| 259 | * if we got here for some reason other than DNSRCH, | ||
| 260 | * we only wanted one iteration of the loop, so stop. | ||
| 261 | */ | ||
| 262 | if (!(_res.options & RES_DNSRCH)) | ||
| 263 | done++; | ||
| 264 | |||
| 265 | if (done) | ||
| 266 | break; | ||
| 267 | } | ||
| 268 | } | ||
| 269 | |||
| 270 | /* | ||
| 271 | * if we have not already tried the name "as is", do that now. | ||
| 272 | * note that we do this regardless of how many dots were in the | ||
| 273 | * name or whether it ends with a dot. | ||
| 274 | */ | ||
| 275 | if (!tried_as_is) { | ||
| 276 | ret = res_querydomain(name, NULL, class, type, answer, anslen); | ||
| 277 | if (ret > 0) | ||
| 278 | return (ret); | ||
| 279 | saved_herrno = h_errno; | ||
| 280 | } | ||
| 281 | |||
| 282 | /* | ||
| 283 | * if we got here, we didn't satisfy the search. | ||
| 284 | * if we did an initial full query, return that query's h_errno | ||
| 285 | * (note that we wouldn't be here if that query had succeeded). | ||
| 286 | * else if we ever got a nodata, send that back as the reason. | ||
| 287 | * else send back meaningless h_errno, that being the one from | ||
| 288 | * the last DNSRCH we did. | ||
| 289 | */ | ||
| 290 | if (saved_herrno != -1) | ||
| 291 | h_errno = saved_herrno; | ||
| 292 | else if (got_nodata) | ||
| 293 | h_errno = NO_DATA; | ||
| 294 | return (-1); | ||
| 295 | } | ||
| 296 | |||
| 297 | /* | ||
| 298 | * Perform a call on res_query on the concatenation of name and domain, | ||
| 299 | * removing a trailing dot from name if domain is NULL. | ||
| 300 | */ | ||
| 301 | res_querydomain(name, domain, class, type, answer, anslen) | ||
| 302 | char *name, *domain; | ||
| 303 | int class, type; /* class and type of query */ | ||
| 304 | u_char *answer; /* buffer to put answer */ | ||
| 305 | int anslen; /* size of answer */ | ||
| 306 | { | ||
| 307 | char nbuf[2*MAXDNAME+2]; | ||
| 308 | char *longname = nbuf; | ||
| 309 | int n; | ||
| 310 | |||
| 311 | #ifdef DEBUG | ||
| 312 | if (_res.options & RES_DEBUG) | ||
| 313 | printf(";; res_querydomain(%s, %s, %d, %d)\n", | ||
| 314 | name, domain, class, type); | ||
| 315 | #endif | ||
| 316 | if (domain == NULL) { | ||
| 317 | /* | ||
| 318 | * Check for trailing '.'; | ||
| 319 | * copy without '.' if present. | ||
| 320 | */ | ||
| 321 | n = strlen(name) - 1; | ||
| 322 | if (n != (0 - 1) && name[n] == '.' && n < sizeof(nbuf) - 1) { | ||
| 323 | bcopy(name, nbuf, n); | ||
| 324 | nbuf[n] = '\0'; | ||
| 325 | } else | ||
| 326 | longname = name; | ||
| 327 | } else | ||
| 328 | (void)sprintf(nbuf, "%.*s.%.*s", | ||
| 329 | MAXDNAME, name, MAXDNAME, domain); | ||
| 330 | |||
| 331 | return (res_query(longname, class, type, answer, anslen)); | ||
| 332 | } | ||
| 333 | |||
| 334 | char * | ||
| 335 | __hostalias(name) | ||
| 336 | register const char *name; | ||
| 337 | { | ||
| 338 | register char *cp1, *cp2; | ||
| 339 | FILE *fp; | ||
| 340 | char *file, *getenv(), *strcpy(), *strncpy(); | ||
| 341 | char buf[BUFSIZ]; | ||
| 342 | static char abuf[MAXDNAME]; | ||
| 343 | |||
| 344 | file = getenv("HOSTALIASES"); | ||
| 345 | if (file == NULL || (fp = fopen(file, "r")) == NULL) | ||
| 346 | return (NULL); | ||
| 347 | buf[sizeof(buf) - 1] = '\0'; | ||
| 348 | while (fgets(buf, sizeof(buf), fp)) { | ||
| 349 | for (cp1 = buf; *cp1 && !isspace(*cp1); ++cp1); | ||
| 350 | if (!*cp1) | ||
| 351 | break; | ||
| 352 | *cp1 = '\0'; | ||
| 353 | if (!strcasecmp(buf, name)) { | ||
| 354 | while (isspace(*++cp1)); | ||
| 355 | if (!*cp1) | ||
| 356 | break; | ||
| 357 | for (cp2 = cp1 + 1; *cp2 && !isspace(*cp2); ++cp2); | ||
| 358 | abuf[sizeof(abuf) - 1] = *cp2 = '\0'; | ||
| 359 | (void)strncpy(abuf, cp1, sizeof(abuf) - 1); | ||
| 360 | fclose(fp); | ||
| 361 | return (abuf); | ||
| 362 | } | ||
| 363 | } | ||
| 364 | fclose(fp); | ||
| 365 | return (NULL); | ||
| 366 | } | ||
diff --git a/src/lib/libc/net/res_random.c b/src/lib/libc/net/res_random.c new file mode 100644 index 0000000000..e22771995a --- /dev/null +++ b/src/lib/libc/net/res_random.c | |||
| @@ -0,0 +1,275 @@ | |||
| 1 | /* $OpenBSD: res_random.c,v 1.20 2013/11/12 07:00:24 deraadt Exp $ */ | ||
| 2 | |||
| 3 | /* | ||
| 4 | * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de> | ||
| 5 | * Copyright 2008 Damien Miller <djm@openbsd.org> | ||
| 6 | * All rights reserved. | ||
| 7 | * | ||
| 8 | * Theo de Raadt <deraadt@openbsd.org> came up with the idea of using | ||
| 9 | * such a mathematical system to generate more random (yet non-repeating) | ||
| 10 | * ids to solve the resolver/named problem. But Niels designed the | ||
| 11 | * actual system based on the constraints. | ||
| 12 | * | ||
| 13 | * Later modified by Damien Miller to wrap the LCG output in a 15-bit | ||
| 14 | * permutation generator based on a Luby-Rackoff block cipher. This | ||
| 15 | * ensures the output is non-repeating and preserves the MSB twiddle | ||
| 16 | * trick, but makes it more resistant to LCG prediction. | ||
| 17 | * | ||
| 18 | * Redistribution and use in source and binary forms, with or without | ||
| 19 | * modification, are permitted provided that the following conditions | ||
| 20 | * are met: | ||
| 21 | * 1. Redistributions of source code must retain the above copyright | ||
| 22 | * notice, this list of conditions and the following disclaimer. | ||
| 23 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 24 | * notice, this list of conditions and the following disclaimer in the | ||
| 25 | * documentation and/or other materials provided with the distribution. | ||
| 26 | * | ||
| 27 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | ||
| 28 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
| 29 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
| 30 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 31 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
| 32 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
| 33 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
| 34 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| 35 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
| 36 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 37 | */ | ||
| 38 | |||
| 39 | /* | ||
| 40 | * seed = random 15bit | ||
| 41 | * n = prime, g0 = generator to n, | ||
| 42 | * j = random so that gcd(j,n-1) == 1 | ||
| 43 | * g = g0^j mod n will be a generator again. | ||
| 44 | * | ||
| 45 | * X[0] = random seed. | ||
| 46 | * X[n] = a*X[n-1]+b mod m is a Linear Congruential Generator | ||
| 47 | * with a = 7^(even random) mod m, | ||
| 48 | * b = random with gcd(b,m) == 1 | ||
| 49 | * m = 31104 and a maximal period of m-1. | ||
| 50 | * | ||
| 51 | * The transaction id is determined by: | ||
| 52 | * id[n] = seed xor (g^X[n] mod n) | ||
| 53 | * | ||
| 54 | * Effectivly the id is restricted to the lower 15 bits, thus | ||
| 55 | * yielding two different cycles by toggling the msb on and off. | ||
| 56 | * This avoids reuse issues caused by reseeding. | ||
| 57 | * | ||
| 58 | * The output of this generator is then randomly permuted though a | ||
| 59 | * custom 15 bit Luby-Rackoff block cipher. | ||
| 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 | #include "thread_private.h" | ||
| 72 | |||
| 73 | #define RU_OUT 180 /* Time after wich will be reseeded */ | ||
| 74 | #define RU_MAX 30000 /* Uniq cycle, avoid blackjack prediction */ | ||
| 75 | #define RU_GEN 2 /* Starting generator */ | ||
| 76 | #define RU_N 32749 /* RU_N-1 = 2*2*3*2729 */ | ||
| 77 | #define RU_AGEN 7 /* determine ru_a as RU_AGEN^(2*rand) */ | ||
| 78 | #define RU_M 31104 /* RU_M = 2^7*3^5 - don't change */ | ||
| 79 | #define RU_ROUNDS 11 /* Number of rounds for permute (odd) */ | ||
| 80 | |||
| 81 | struct prf_ctx { | ||
| 82 | /* PRF lookup table for odd rounds (7 bits input to 8 bits output) */ | ||
| 83 | u_char prf7[(RU_ROUNDS / 2) * (1 << 7)]; | ||
| 84 | |||
| 85 | /* PRF lookup table for even rounds (8 bits input to 7 bits output) */ | ||
| 86 | u_char prf8[((RU_ROUNDS + 1) / 2) * (1 << 8)]; | ||
| 87 | }; | ||
| 88 | |||
| 89 | #define PFAC_N 3 | ||
| 90 | const static u_int16_t pfacts[PFAC_N] = { | ||
| 91 | 2, | ||
| 92 | 3, | ||
| 93 | 2729 | ||
| 94 | }; | ||
| 95 | |||
| 96 | static u_int16_t ru_x; | ||
| 97 | static u_int16_t ru_seed, ru_seed2; | ||
| 98 | static u_int16_t ru_a, ru_b; | ||
| 99 | static u_int16_t ru_g; | ||
| 100 | static u_int16_t ru_counter = 0; | ||
| 101 | static u_int16_t ru_msb = 0; | ||
| 102 | static struct prf_ctx *ru_prf = NULL; | ||
| 103 | static time_t ru_reseed; | ||
| 104 | |||
| 105 | static u_int16_t pmod(u_int16_t, u_int16_t, u_int16_t); | ||
| 106 | static void res_initid(void); | ||
| 107 | |||
| 108 | /* | ||
| 109 | * Do a fast modular exponation, returned value will be in the range | ||
| 110 | * of 0 - (mod-1) | ||
| 111 | */ | ||
| 112 | static u_int16_t | ||
| 113 | pmod(u_int16_t gen, u_int16_t exp, u_int16_t mod) | ||
| 114 | { | ||
| 115 | u_int16_t s, t, u; | ||
| 116 | |||
| 117 | s = 1; | ||
| 118 | t = gen; | ||
| 119 | u = exp; | ||
| 120 | |||
| 121 | while (u) { | ||
| 122 | if (u & 1) | ||
| 123 | s = (s * t) % mod; | ||
| 124 | u >>= 1; | ||
| 125 | t = (t * t) % mod; | ||
| 126 | } | ||
| 127 | return (s); | ||
| 128 | } | ||
| 129 | |||
| 130 | /* | ||
| 131 | * 15-bit permutation based on Luby-Rackoff block cipher | ||
| 132 | */ | ||
| 133 | static u_int | ||
| 134 | permute15(u_int in) | ||
| 135 | { | ||
| 136 | int i; | ||
| 137 | u_int left, right, tmp; | ||
| 138 | |||
| 139 | if (ru_prf == NULL) | ||
| 140 | return in; | ||
| 141 | |||
| 142 | left = (in >> 8) & 0x7f; | ||
| 143 | right = in & 0xff; | ||
| 144 | |||
| 145 | /* | ||
| 146 | * Each round swaps the width of left and right. Even rounds have | ||
| 147 | * a 7-bit left, odd rounds have an 8-bit left. Since this uses an | ||
| 148 | * odd number of rounds, left is always 8 bits wide at the end. | ||
| 149 | */ | ||
| 150 | for (i = 0; i < RU_ROUNDS; i++) { | ||
| 151 | if ((i & 1) == 0) | ||
| 152 | tmp = ru_prf->prf8[(i << (8 - 1)) | right] & 0x7f; | ||
| 153 | else | ||
| 154 | tmp = ru_prf->prf7[((i - 1) << (7 - 1)) | right]; | ||
| 155 | tmp ^= left; | ||
| 156 | left = right; | ||
| 157 | right = tmp; | ||
| 158 | } | ||
| 159 | |||
| 160 | return (right << 8) | left; | ||
| 161 | } | ||
| 162 | |||
| 163 | /* | ||
| 164 | * Initializes the seed and chooses a suitable generator. Also toggles | ||
| 165 | * the msb flag. The msb flag is used to generate two distinct | ||
| 166 | * cycles of random numbers and thus avoiding reuse of ids. | ||
| 167 | * | ||
| 168 | * This function is called from res_randomid() when needed, an | ||
| 169 | * application does not have to worry about it. | ||
| 170 | */ | ||
| 171 | static void | ||
| 172 | res_initid(void) | ||
| 173 | { | ||
| 174 | u_int16_t j, i; | ||
| 175 | u_int32_t tmp; | ||
| 176 | int noprime = 1; | ||
| 177 | struct timespec ts; | ||
| 178 | |||
| 179 | ru_x = arc4random_uniform(RU_M); | ||
| 180 | |||
| 181 | /* 15 bits of random seed */ | ||
| 182 | tmp = arc4random(); | ||
| 183 | ru_seed = (tmp >> 16) & 0x7FFF; | ||
| 184 | ru_seed2 = tmp & 0x7FFF; | ||
| 185 | |||
| 186 | /* Determine the LCG we use */ | ||
| 187 | tmp = arc4random(); | ||
| 188 | ru_b = (tmp & 0xfffe) | 1; | ||
| 189 | ru_a = pmod(RU_AGEN, (tmp >> 16) & 0xfffe, RU_M); | ||
| 190 | while (ru_b % 3 == 0) | ||
| 191 | ru_b += 2; | ||
| 192 | |||
| 193 | j = arc4random_uniform(RU_N); | ||
| 194 | |||
| 195 | /* | ||
| 196 | * Do a fast gcd(j,RU_N-1), so we can find a j with | ||
| 197 | * gcd(j, RU_N-1) == 1, giving a new generator for | ||
| 198 | * RU_GEN^j mod RU_N | ||
| 199 | */ | ||
| 200 | |||
| 201 | while (noprime) { | ||
| 202 | for (i = 0; i < PFAC_N; i++) | ||
| 203 | if (j % pfacts[i] == 0) | ||
| 204 | break; | ||
| 205 | |||
| 206 | if (i >= PFAC_N) | ||
| 207 | noprime = 0; | ||
| 208 | else | ||
| 209 | j = (j + 1) % RU_N; | ||
| 210 | } | ||
| 211 | |||
| 212 | ru_g = pmod(RU_GEN, j, RU_N); | ||
| 213 | ru_counter = 0; | ||
| 214 | |||
| 215 | /* Initialise PRF for Luby-Rackoff permutation */ | ||
| 216 | if (ru_prf == NULL) | ||
| 217 | ru_prf = malloc(sizeof(*ru_prf)); | ||
| 218 | if (ru_prf != NULL) | ||
| 219 | arc4random_buf(ru_prf, sizeof(*ru_prf)); | ||
| 220 | |||
| 221 | clock_gettime(CLOCK_MONOTONIC, &ts); | ||
| 222 | ru_reseed = ts.tv_sec + RU_OUT; | ||
| 223 | ru_msb = ru_msb == 0x8000 ? 0 : 0x8000; | ||
| 224 | } | ||
| 225 | |||
| 226 | u_int | ||
| 227 | res_randomid(void) | ||
| 228 | { | ||
| 229 | struct timespec ts; | ||
| 230 | u_int r; | ||
| 231 | _THREAD_PRIVATE_MUTEX(random); | ||
| 232 | |||
| 233 | clock_gettime(CLOCK_MONOTONIC, &ts); | ||
| 234 | |||
| 235 | _THREAD_PRIVATE_MUTEX_LOCK(random); | ||
| 236 | |||
| 237 | if (ru_counter >= RU_MAX || ts.tv_sec > ru_reseed) | ||
| 238 | res_initid(); | ||
| 239 | |||
| 240 | /* Linear Congruential Generator */ | ||
| 241 | ru_x = (ru_a * ru_x + ru_b) % RU_M; | ||
| 242 | ru_counter++; | ||
| 243 | |||
| 244 | r = permute15(ru_seed ^ pmod(ru_g, ru_seed2 + ru_x, RU_N)) | ru_msb; | ||
| 245 | |||
| 246 | _THREAD_PRIVATE_MUTEX_UNLOCK(random); | ||
| 247 | |||
| 248 | return (r); | ||
| 249 | } | ||
| 250 | |||
| 251 | #if 0 | ||
| 252 | int | ||
| 253 | main(int argc, char **argv) | ||
| 254 | { | ||
| 255 | int i, n; | ||
| 256 | u_int16_t wert; | ||
| 257 | |||
| 258 | res_initid(); | ||
| 259 | |||
| 260 | printf("Generator: %u\n", ru_g); | ||
| 261 | printf("Seed: %u\n", ru_seed); | ||
| 262 | printf("Reseed at %ld\n", ru_reseed); | ||
| 263 | printf("Ru_X: %u\n", ru_x); | ||
| 264 | printf("Ru_A: %u\n", ru_a); | ||
| 265 | printf("Ru_B: %u\n", ru_b); | ||
| 266 | |||
| 267 | n = argc > 1 ? atoi(argv[1]) : 60001; | ||
| 268 | for (i=0;i<n;i++) { | ||
| 269 | wert = res_randomid(); | ||
| 270 | printf("%u\n", wert); | ||
| 271 | } | ||
| 272 | return 0; | ||
| 273 | } | ||
| 274 | #endif | ||
| 275 | |||
diff --git a/src/lib/libc/net/res_send.c b/src/lib/libc/net/res_send.c deleted file mode 100644 index e608358180..0000000000 --- a/src/lib/libc/net/res_send.c +++ /dev/null | |||
| @@ -1,474 +0,0 @@ | |||
| 1 | /* $NetBSD: res_send.c,v 1.4 1995/02/25 06:21:01 cgd Exp $ */ | ||
| 2 | |||
| 3 | /*- | ||
| 4 | * Copyright (c) 1985, 1989, 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 | * Portions Copyright (c) 1993 by Digital Equipment Corporation. | ||
| 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, and that | ||
| 40 | * the name of Digital Equipment Corporation not be used in advertising or | ||
| 41 | * publicity pertaining to distribution of the document or software without | ||
| 42 | * specific, written prior permission. | ||
| 43 | * | ||
| 44 | * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL | ||
| 45 | * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES | ||
| 46 | * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT | ||
| 47 | * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | ||
| 48 | * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR | ||
| 49 | * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS | ||
| 50 | * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | ||
| 51 | * SOFTWARE. | ||
| 52 | * - | ||
| 53 | * --Copyright-- | ||
| 54 | */ | ||
| 55 | |||
| 56 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 57 | #if 0 | ||
| 58 | static char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93"; | ||
| 59 | static char rcsid[] = "$Id: res_send.c,v 4.9.1.1 1993/05/02 22:43:03 vixie Rel "; | ||
| 60 | #else | ||
| 61 | static char rcsid[] = "$NetBSD: res_send.c,v 1.4 1995/02/25 06:21:01 cgd Exp $"; | ||
| 62 | #endif | ||
| 63 | #endif /* LIBC_SCCS and not lint */ | ||
| 64 | |||
| 65 | /* | ||
| 66 | * Send query to name server and wait for reply. | ||
| 67 | */ | ||
| 68 | |||
| 69 | #include <sys/param.h> | ||
| 70 | #include <sys/time.h> | ||
| 71 | #include <sys/socket.h> | ||
| 72 | #include <sys/uio.h> | ||
| 73 | #include <netinet/in.h> | ||
| 74 | #include <arpa/nameser.h> | ||
| 75 | #include <arpa/inet.h> | ||
| 76 | #include <stdio.h> | ||
| 77 | #include <errno.h> | ||
| 78 | #include <resolv.h> | ||
| 79 | #include <unistd.h> | ||
| 80 | #include <string.h> | ||
| 81 | |||
| 82 | static int s = -1; /* socket used for communications */ | ||
| 83 | static struct sockaddr no_addr; | ||
| 84 | |||
| 85 | #ifndef FD_SET | ||
| 86 | #define NFDBITS 32 | ||
| 87 | #define FD_SETSIZE 32 | ||
| 88 | #define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS))) | ||
| 89 | #define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS))) | ||
| 90 | #define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS))) | ||
| 91 | #define FD_ZERO(p) bzero((char *)(p), sizeof(*(p))) | ||
| 92 | #endif | ||
| 93 | |||
| 94 | res_send(buf, buflen, answer, anslen) | ||
| 95 | const char *buf; | ||
| 96 | int buflen; | ||
| 97 | char *answer; | ||
| 98 | int anslen; | ||
| 99 | { | ||
| 100 | register int n; | ||
| 101 | int try, v_circuit, resplen, ns; | ||
| 102 | int gotsomewhere = 0, connected = 0; | ||
| 103 | int connreset = 0; | ||
| 104 | u_short id, len; | ||
| 105 | char *cp; | ||
| 106 | fd_set dsmask; | ||
| 107 | struct timeval timeout; | ||
| 108 | HEADER *hp = (HEADER *) buf; | ||
| 109 | HEADER *anhp = (HEADER *) answer; | ||
| 110 | u_int badns; /* XXX NSMAX can't exceed #/bits per this */ | ||
| 111 | struct iovec iov[2]; | ||
| 112 | int terrno = ETIMEDOUT; | ||
| 113 | char junk[512]; | ||
| 114 | |||
| 115 | #ifdef DEBUG | ||
| 116 | if ((_res.options & RES_DEBUG) || (_res.pfcode & RES_PRF_QUERY)) { | ||
| 117 | printf(";; res_send()\n"); | ||
| 118 | __p_query(buf); | ||
| 119 | } | ||
| 120 | #endif | ||
| 121 | if (!(_res.options & RES_INIT)) | ||
| 122 | if (res_init() == -1) { | ||
| 123 | return(-1); | ||
| 124 | } | ||
| 125 | v_circuit = (_res.options & RES_USEVC) || buflen > PACKETSZ; | ||
| 126 | id = hp->id; | ||
| 127 | badns = 0; | ||
| 128 | /* | ||
| 129 | * Send request, RETRY times, or until successful | ||
| 130 | */ | ||
| 131 | for (try = 0; try < _res.retry; try++) { | ||
| 132 | for (ns = 0; ns < _res.nscount; ns++) { | ||
| 133 | if (badns & (1<<ns)) | ||
| 134 | continue; | ||
| 135 | #ifdef DEBUG | ||
| 136 | if (_res.options & RES_DEBUG) | ||
| 137 | printf(";; Querying server (# %d) address = %s\n", | ||
| 138 | ns+1, | ||
| 139 | inet_ntoa(_res.nsaddr_list[ns].sin_addr)); | ||
| 140 | #endif | ||
| 141 | usevc: | ||
| 142 | if (v_circuit) { | ||
| 143 | int truncated = 0; | ||
| 144 | |||
| 145 | /* | ||
| 146 | * Use virtual circuit; | ||
| 147 | * at most one attempt per server. | ||
| 148 | */ | ||
| 149 | try = _res.retry; | ||
| 150 | if (s < 0) { | ||
| 151 | s = socket(AF_INET, SOCK_STREAM, 0); | ||
| 152 | if (s < 0) { | ||
| 153 | terrno = errno; | ||
| 154 | #ifdef DEBUG | ||
| 155 | if (_res.options & RES_DEBUG) | ||
| 156 | perror("socket (vc) failed"); | ||
| 157 | #endif | ||
| 158 | continue; | ||
| 159 | } | ||
| 160 | if (connect(s, | ||
| 161 | (struct sockaddr *)&(_res.nsaddr_list[ns]), | ||
| 162 | sizeof(struct sockaddr)) < 0) { | ||
| 163 | terrno = errno; | ||
| 164 | #ifdef DEBUG | ||
| 165 | if (_res.options & RES_DEBUG) | ||
| 166 | perror("connect failed"); | ||
| 167 | #endif | ||
| 168 | (void) close(s); | ||
| 169 | s = -1; | ||
| 170 | continue; | ||
| 171 | } | ||
| 172 | } | ||
| 173 | /* | ||
| 174 | * Send length & message | ||
| 175 | */ | ||
| 176 | len = htons((u_short)buflen); | ||
| 177 | iov[0].iov_base = (caddr_t)&len; | ||
| 178 | iov[0].iov_len = sizeof(len); | ||
| 179 | iov[1].iov_base = (char *)buf; | ||
| 180 | iov[1].iov_len = buflen; | ||
| 181 | if (writev(s, iov, 2) != sizeof(len) + buflen) { | ||
| 182 | terrno = errno; | ||
| 183 | #ifdef DEBUG | ||
| 184 | if (_res.options & RES_DEBUG) | ||
| 185 | perror("write failed"); | ||
| 186 | #endif | ||
| 187 | (void) close(s); | ||
| 188 | s = -1; | ||
| 189 | continue; | ||
| 190 | } | ||
| 191 | /* | ||
| 192 | * Receive length & response | ||
| 193 | */ | ||
| 194 | cp = answer; | ||
| 195 | len = sizeof(short); | ||
| 196 | while (len != 0 && | ||
| 197 | (n = read(s, (char *)cp, (int)len)) > 0) { | ||
| 198 | cp += n; | ||
| 199 | len -= n; | ||
| 200 | } | ||
| 201 | if (n <= 0) { | ||
| 202 | terrno = errno; | ||
| 203 | #ifdef DEBUG | ||
| 204 | if (_res.options & RES_DEBUG) | ||
| 205 | perror("read failed"); | ||
| 206 | #endif | ||
| 207 | (void) close(s); | ||
| 208 | s = -1; | ||
| 209 | /* | ||
| 210 | * A long running process might get its TCP | ||
| 211 | * connection reset if the remote server was | ||
| 212 | * restarted. Requery the server instead of | ||
| 213 | * trying a new one. When there is only one | ||
| 214 | * server, this means that a query might work | ||
| 215 | * instead of failing. We only allow one reset | ||
| 216 | * per query to prevent looping. | ||
| 217 | */ | ||
| 218 | if (terrno == ECONNRESET && !connreset) { | ||
| 219 | connreset = 1; | ||
| 220 | ns--; | ||
| 221 | } | ||
| 222 | continue; | ||
| 223 | } | ||
| 224 | cp = answer; | ||
| 225 | if ((resplen = ntohs(*(u_short *)cp)) > anslen) { | ||
| 226 | #ifdef DEBUG | ||
| 227 | if (_res.options & RES_DEBUG) | ||
| 228 | fprintf(stderr, | ||
| 229 | ";; response truncated\n"); | ||
| 230 | #endif | ||
| 231 | len = anslen; | ||
| 232 | truncated = 1; | ||
| 233 | } else | ||
| 234 | len = resplen; | ||
| 235 | while (len != 0 && | ||
| 236 | (n = read(s, (char *)cp, (int)len)) > 0) { | ||
| 237 | cp += n; | ||
| 238 | len -= n; | ||
| 239 | } | ||
| 240 | if (n <= 0) { | ||
| 241 | terrno = errno; | ||
| 242 | #ifdef DEBUG | ||
| 243 | if (_res.options & RES_DEBUG) | ||
| 244 | perror("read failed"); | ||
| 245 | #endif | ||
| 246 | (void) close(s); | ||
| 247 | s = -1; | ||
| 248 | continue; | ||
| 249 | } | ||
| 250 | if (truncated) { | ||
| 251 | /* | ||
| 252 | * Flush rest of answer | ||
| 253 | * so connection stays in synch. | ||
| 254 | */ | ||
| 255 | anhp->tc = 1; | ||
| 256 | len = resplen - anslen; | ||
| 257 | while (len != 0) { | ||
| 258 | n = (len > sizeof(junk) ? | ||
| 259 | sizeof(junk) : len); | ||
| 260 | if ((n = read(s, junk, n)) > 0) | ||
| 261 | len -= n; | ||
| 262 | else | ||
| 263 | break; | ||
| 264 | } | ||
| 265 | } | ||
| 266 | } else { | ||
| 267 | /* | ||
| 268 | * Use datagrams. | ||
| 269 | */ | ||
| 270 | if (s < 0) { | ||
| 271 | s = socket(AF_INET, SOCK_DGRAM, 0); | ||
| 272 | if (s < 0) { | ||
| 273 | terrno = errno; | ||
| 274 | #ifdef DEBUG | ||
| 275 | if (_res.options & RES_DEBUG) | ||
| 276 | perror("socket (dg) failed"); | ||
| 277 | #endif | ||
| 278 | continue; | ||
| 279 | } | ||
| 280 | } | ||
| 281 | /* | ||
| 282 | * I'm tired of answering this question, so: | ||
| 283 | * On a 4.3BSD+ machine (client and server, | ||
| 284 | * actually), sending to a nameserver datagram | ||
| 285 | * port with no nameserver will cause an | ||
| 286 | * ICMP port unreachable message to be returned. | ||
| 287 | * If our datagram socket is "connected" to the | ||
| 288 | * server, we get an ECONNREFUSED error on the next | ||
| 289 | * socket operation, and select returns if the | ||
| 290 | * error message is received. We can thus detect | ||
| 291 | * the absence of a nameserver without timing out. | ||
| 292 | * If we have sent queries to at least two servers, | ||
| 293 | * however, we don't want to remain connected, | ||
| 294 | * as we wish to receive answers from the first | ||
| 295 | * server to respond. | ||
| 296 | */ | ||
| 297 | if (_res.nscount == 1 || (try == 0 && ns == 0)) { | ||
| 298 | /* | ||
| 299 | * Don't use connect if we might | ||
| 300 | * still receive a response | ||
| 301 | * from another server. | ||
| 302 | */ | ||
| 303 | if (connected == 0) { | ||
| 304 | if (connect(s, | ||
| 305 | (struct sockaddr *) | ||
| 306 | &_res.nsaddr_list[ns], | ||
| 307 | sizeof(struct sockaddr)) < 0) { | ||
| 308 | #ifdef DEBUG | ||
| 309 | if (_res.options & RES_DEBUG) | ||
| 310 | perror("connect"); | ||
| 311 | #endif | ||
| 312 | continue; | ||
| 313 | } | ||
| 314 | connected = 1; | ||
| 315 | } | ||
| 316 | if (send(s, buf, buflen, 0) != buflen) { | ||
| 317 | #ifdef DEBUG | ||
| 318 | if (_res.options & RES_DEBUG) | ||
| 319 | perror("send"); | ||
| 320 | #endif | ||
| 321 | continue; | ||
| 322 | } | ||
| 323 | } else { | ||
| 324 | /* | ||
| 325 | * Disconnect if we want to listen | ||
| 326 | * for responses from more than one server. | ||
| 327 | */ | ||
| 328 | if (connected) { | ||
| 329 | (void) connect(s, &no_addr, | ||
| 330 | sizeof(no_addr)); | ||
| 331 | connected = 0; | ||
| 332 | } | ||
| 333 | if (sendto(s, buf, buflen, 0, | ||
| 334 | (struct sockaddr *)&_res.nsaddr_list[ns], | ||
| 335 | sizeof(struct sockaddr)) != buflen) { | ||
| 336 | #ifdef DEBUG | ||
| 337 | if (_res.options & RES_DEBUG) | ||
| 338 | perror("sendto"); | ||
| 339 | #endif | ||
| 340 | continue; | ||
| 341 | } | ||
| 342 | } | ||
| 343 | |||
| 344 | /* | ||
| 345 | * Wait for reply | ||
| 346 | */ | ||
| 347 | timeout.tv_sec = (_res.retrans << try); | ||
| 348 | if (try > 0) | ||
| 349 | timeout.tv_sec /= _res.nscount; | ||
| 350 | if ((long) timeout.tv_sec <= 0) | ||
| 351 | timeout.tv_sec = 1; | ||
| 352 | timeout.tv_usec = 0; | ||
| 353 | wait: | ||
| 354 | FD_ZERO(&dsmask); | ||
| 355 | FD_SET(s, &dsmask); | ||
| 356 | n = select(s+1, &dsmask, (fd_set *)NULL, | ||
| 357 | (fd_set *)NULL, &timeout); | ||
| 358 | if (n < 0) { | ||
| 359 | #ifdef DEBUG | ||
| 360 | if (_res.options & RES_DEBUG) | ||
| 361 | perror("select"); | ||
| 362 | #endif | ||
| 363 | continue; | ||
| 364 | } | ||
| 365 | if (n == 0) { | ||
| 366 | /* | ||
| 367 | * timeout | ||
| 368 | */ | ||
| 369 | #ifdef DEBUG | ||
| 370 | if (_res.options & RES_DEBUG) | ||
| 371 | printf(";; timeout\n"); | ||
| 372 | #endif | ||
| 373 | gotsomewhere = 1; | ||
| 374 | continue; | ||
| 375 | } | ||
| 376 | if ((resplen = recv(s, answer, anslen, 0)) <= 0) { | ||
| 377 | #ifdef DEBUG | ||
| 378 | if (_res.options & RES_DEBUG) | ||
| 379 | perror("recvfrom"); | ||
| 380 | #endif | ||
| 381 | continue; | ||
| 382 | } | ||
| 383 | gotsomewhere = 1; | ||
| 384 | if (id != anhp->id) { | ||
| 385 | /* | ||
| 386 | * response from old query, ignore it | ||
| 387 | */ | ||
| 388 | #ifdef DEBUG | ||
| 389 | if ((_res.options & RES_DEBUG) || | ||
| 390 | (_res.pfcode & RES_PRF_REPLY)) { | ||
| 391 | printf(";; old answer:\n"); | ||
| 392 | __p_query(answer); | ||
| 393 | } | ||
| 394 | #endif | ||
| 395 | goto wait; | ||
| 396 | } | ||
| 397 | if (anhp->rcode == SERVFAIL || anhp->rcode == NOTIMP || | ||
| 398 | anhp->rcode == REFUSED) { | ||
| 399 | #ifdef DEBUG | ||
| 400 | if (_res.options & RES_DEBUG) { | ||
| 401 | printf("server rejected query:\n"); | ||
| 402 | __p_query(answer); | ||
| 403 | } | ||
| 404 | #endif | ||
| 405 | badns |= (1<<ns); | ||
| 406 | continue; | ||
| 407 | } | ||
| 408 | if (!(_res.options & RES_IGNTC) && anhp->tc) { | ||
| 409 | /* | ||
| 410 | * get rest of answer; | ||
| 411 | * use TCP with same server. | ||
| 412 | */ | ||
| 413 | #ifdef DEBUG | ||
| 414 | if (_res.options & RES_DEBUG) | ||
| 415 | printf(";; truncated answer\n"); | ||
| 416 | #endif | ||
| 417 | (void) close(s); | ||
| 418 | s = -1; | ||
| 419 | v_circuit = 1; | ||
| 420 | goto usevc; | ||
| 421 | } | ||
| 422 | } | ||
| 423 | #ifdef DEBUG | ||
| 424 | if (_res.options & RES_DEBUG) | ||
| 425 | printf(";; got answer:\n"); | ||
| 426 | if ((_res.options & RES_DEBUG) || | ||
| 427 | (_res.pfcode & RES_PRF_REPLY)) | ||
| 428 | __p_query(answer); | ||
| 429 | #endif | ||
| 430 | /* | ||
| 431 | * If using virtual circuits, we assume that the first server | ||
| 432 | * is preferred * over the rest (i.e. it is on the local | ||
| 433 | * machine) and only keep that one open. | ||
| 434 | * If we have temporarily opened a virtual circuit, | ||
| 435 | * or if we haven't been asked to keep a socket open, | ||
| 436 | * close the socket. | ||
| 437 | */ | ||
| 438 | if ((v_circuit && | ||
| 439 | ((_res.options & RES_USEVC) == 0 || ns != 0)) || | ||
| 440 | (_res.options & RES_STAYOPEN) == 0) { | ||
| 441 | (void) close(s); | ||
| 442 | s = -1; | ||
| 443 | } | ||
| 444 | return (resplen); | ||
| 445 | } | ||
| 446 | } | ||
| 447 | if (s >= 0) { | ||
| 448 | (void) close(s); | ||
| 449 | s = -1; | ||
| 450 | } | ||
| 451 | if (v_circuit == 0) | ||
| 452 | if (gotsomewhere == 0) | ||
| 453 | errno = ECONNREFUSED; /* no nameservers found */ | ||
| 454 | else | ||
| 455 | errno = ETIMEDOUT; /* no answer obtained */ | ||
| 456 | else | ||
| 457 | errno = terrno; | ||
| 458 | return (-1); | ||
| 459 | } | ||
| 460 | |||
| 461 | /* | ||
| 462 | * This routine is for closing the socket if a virtual circuit is used and | ||
| 463 | * the program wants to close it. This provides support for endhostent() | ||
| 464 | * which expects to close the socket. | ||
| 465 | * | ||
| 466 | * This routine is not expected to be user visible. | ||
| 467 | */ | ||
| 468 | _res_close() | ||
| 469 | { | ||
| 470 | if (s != -1) { | ||
| 471 | (void) close(s); | ||
| 472 | s = -1; | ||
| 473 | } | ||
| 474 | } | ||
diff --git a/src/lib/libc/net/resolver.3 b/src/lib/libc/net/resolver.3 index 99abe17f03..93b365a619 100644 --- a/src/lib/libc/net/resolver.3 +++ b/src/lib/libc/net/resolver.3 | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | .\" $NetBSD: resolver.3,v 1.5 1995/02/25 06:21:02 cgd Exp $ | 1 | .\" $OpenBSD: resolver.3,v 1.29 2014/01/21 03:15:45 schwarze Exp $ |
| 2 | .\" | 2 | .\" |
| 3 | .\" Copyright (c) 1985, 1991, 1993 | 3 | .\" Copyright (c) 1985, 1991, 1993 |
| 4 | .\" The Regents of the University of California. All rights reserved. | 4 | .\" The Regents of the University of California. All rights reserved. |
| @@ -11,11 +11,7 @@ | |||
| 11 | .\" 2. Redistributions in binary form must reproduce the above copyright | 11 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 12 | .\" notice, this list of conditions and the following disclaimer in the | 12 | .\" notice, this list of conditions and the following disclaimer in the |
| 13 | .\" documentation and/or other materials provided with the distribution. | 13 | .\" documentation and/or other materials provided with the distribution. |
| 14 | .\" 3. All advertising materials mentioning features or use of this software | 14 | .\" 3. Neither the name of the University nor the names of its contributors |
| 15 | .\" must display the following acknowledgement: | ||
| 16 | .\" This product includes software developed by the University of | ||
| 17 | .\" California, Berkeley and its contributors. | ||
| 18 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 19 | .\" may be used to endorse or promote products derived from this software | 15 | .\" may be used to endorse or promote products derived from this software |
| 20 | .\" without specific prior written permission. | 16 | .\" without specific prior written permission. |
| 21 | .\" | 17 | .\" |
| @@ -31,11 +27,9 @@ | |||
| 31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 27 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 32 | .\" SUCH DAMAGE. | 28 | .\" SUCH DAMAGE. |
| 33 | .\" | 29 | .\" |
| 34 | .\" @(#)resolver.3 8.1 (Berkeley) 6/4/93 | 30 | .Dd $Mdocdate: January 21 2014 $ |
| 35 | .\" | ||
| 36 | .Dd June 4, 1993 | ||
| 37 | .Dt RESOLVER 3 | 31 | .Dt RESOLVER 3 |
| 38 | .Os BSD 4.3 | 32 | .Os |
| 39 | .Sh NAME | 33 | .Sh NAME |
| 40 | .Nm res_query , | 34 | .Nm res_query , |
| 41 | .Nm res_search , | 35 | .Nm res_search , |
| @@ -46,80 +40,91 @@ | |||
| 46 | .Nm dn_expand | 40 | .Nm dn_expand |
| 47 | .Nd resolver routines | 41 | .Nd resolver routines |
| 48 | .Sh SYNOPSIS | 42 | .Sh SYNOPSIS |
| 49 | .Fd #include <sys/types.h> | 43 | .In sys/types.h |
| 50 | .Fd #include <netinet/in.h> | 44 | .In netinet/in.h |
| 51 | .Fd #include <arpa/nameser.h> | 45 | .In arpa/nameser.h |
| 52 | .Fd #include <resolv.h> | 46 | .In resolv.h |
| 47 | .Ft int | ||
| 53 | .Fo res_query | 48 | .Fo res_query |
| 54 | .Fa "char *dname" | 49 | .Fa "const char *dname" |
| 55 | .Fa "int class" | 50 | .Fa "int class" |
| 56 | .Fa "int type" | 51 | .Fa "int type" |
| 57 | .Fa "u_char *answer" | 52 | .Fa "unsigned char *answer" |
| 58 | .Fa "int anslen" | 53 | .Fa "int anslen" |
| 59 | .Fc | 54 | .Fc |
| 55 | .Ft int | ||
| 60 | .Fo res_search | 56 | .Fo res_search |
| 61 | .Fa "char *dname" | 57 | .Fa "const char *dname" |
| 62 | .Fa "int class" | 58 | .Fa "int class" |
| 63 | .Fa "int type" | 59 | .Fa "int type" |
| 64 | .Fa "u_char *answer" | 60 | .Fa "unsigned char *answer" |
| 65 | .Fa "int anslen" | 61 | .Fa "int anslen" |
| 66 | .Fc | 62 | .Fc |
| 63 | .Ft int | ||
| 67 | .Fo res_mkquery | 64 | .Fo res_mkquery |
| 68 | .Fa "int op" | 65 | .Fa "int op" |
| 69 | .Fa "char *dname" | 66 | .Fa "const char *dname" |
| 70 | .Fa "int class" | 67 | .Fa "int class" |
| 71 | .Fa "int type" | 68 | .Fa "int type" |
| 72 | .Fa "char *data" | 69 | .Fa "const unsigned char *data" |
| 73 | .Fa "int datalen" | 70 | .Fa "int datalen" |
| 74 | .Fa "struct rrec *newrr" | 71 | .Fa "const unsigned char *newrr" |
| 75 | .Fa "char *buf" | 72 | .Fa "unsigned char *buf" |
| 76 | .Fa "int buflen" | 73 | .Fa "int buflen" |
| 77 | .Fc | 74 | .Fc |
| 75 | .Ft int | ||
| 78 | .Fo res_send | 76 | .Fo res_send |
| 79 | .Fa "char *msg" | 77 | .Fa "const unsigned char *msg" |
| 80 | .Fa "int msglen" | 78 | .Fa "int msglen" |
| 81 | .Fa "char *answer" | 79 | .Fa "unsigned char *answer" |
| 82 | .Fa "int anslen" | 80 | .Fa "int anslen" |
| 83 | .Fc | 81 | .Fc |
| 84 | .Fn res_init | 82 | .Ft int |
| 83 | .Fn res_init "void" | ||
| 84 | .Ft int | ||
| 85 | .Fo dn_comp | 85 | .Fo dn_comp |
| 86 | .Fa "char *exp_dn" | 86 | .Fa "const char *exp_dn" |
| 87 | .Fa "char *comp_dn" | 87 | .Fa "unsigned char *comp_dn" |
| 88 | .Fa "int length" | 88 | .Fa "int length" |
| 89 | .Fa "char **dnptrs" | 89 | .Fa "unsigned char **dnptrs" |
| 90 | .Fa "char **lastdnptr" | 90 | .Fa "unsigned char **lastdnptr" |
| 91 | .Fc | 91 | .Fc |
| 92 | .Ft int | ||
| 92 | .Fo dn_expand | 93 | .Fo dn_expand |
| 93 | .Fa "u_char *msg" | 94 | .Fa "const unsigned char *msg" |
| 94 | .Fa "u_char *eomorig" | 95 | .Fa "const unsigned char *eomorig" |
| 95 | .Fa "u_char *comp_dn" | 96 | .Fa "const unsigned char *comp_dn" |
| 96 | .Fa "u_char *exp_dn" | 97 | .Fa "char *exp_dn" |
| 97 | .Fa "int length" | 98 | .Fa "int length" |
| 98 | .Fc | 99 | .Fc |
| 99 | .Sh DESCRIPTION | 100 | .Sh DESCRIPTION |
| 100 | These routines are used for making, sending and interpreting | 101 | These routines are used for making, sending, and interpreting |
| 101 | query and reply messages with Internet domain name servers. | 102 | query and reply messages with Internet domain name servers. |
| 102 | .Pp | 103 | .Pp |
| 103 | Global configuration and state information that is used by the | 104 | Global configuration and state information that is used by the |
| 104 | resolver routines is kept in the structure | 105 | resolver routines is kept in the structure |
| 105 | .Em _res . | 106 | .Li _res . |
| 106 | Most of the values have reasonable defaults and can be ignored. | 107 | Most of the values have reasonable defaults and can be ignored. |
| 107 | Options | 108 | Options stored in |
| 108 | stored in | 109 | .Li _res.options |
| 109 | .Em _res.options | ||
| 110 | are defined in | 110 | are defined in |
| 111 | .Pa resolv.h | 111 | .In resolv.h |
| 112 | and are as follows. | 112 | and are as follows. |
| 113 | Options are stored as a simple bit mask containing the bitwise ``or'' | 113 | Options are stored as a simple bit mask containing the bitwise OR |
| 114 | of the options enabled. | 114 | of the options enabled. |
| 115 | .Bl -tag -width RES_DEFNAMES | 115 | .Bl -tag -width RES_USE_DNSSEC |
| 116 | .It Dv RES_INIT | 116 | .It Dv RES_INIT |
| 117 | True if the initial name server address and default domain name are | 117 | True if the initial name server address and default domain name are |
| 118 | initialized (i.e., | 118 | initialized (i.e.\& |
| 119 | .Fn res_init | 119 | .Fn res_init |
| 120 | has been called). | 120 | has been called). |
| 121 | .It Dv RES_DEBUG | 121 | .It Dv RES_DEBUG |
| 122 | Print debugging messages. | 122 | Print debugging messages, |
| 123 | if libc is compiled with | ||
| 124 | .Dv DEBUG . | ||
| 125 | By default on | ||
| 126 | .Ox | ||
| 127 | this option does nothing. | ||
| 123 | .It Dv RES_AAONLY | 128 | .It Dv RES_AAONLY |
| 124 | Accept authoritative answers only. | 129 | Accept authoritative answers only. |
| 125 | With this option, | 130 | With this option, |
| @@ -127,36 +132,30 @@ With this option, | |||
| 127 | should continue until it finds an authoritative answer or finds an error. | 132 | should continue until it finds an authoritative answer or finds an error. |
| 128 | Currently this is not implemented. | 133 | Currently this is not implemented. |
| 129 | .It Dv RES_USEVC | 134 | .It Dv RES_USEVC |
| 130 | Use | 135 | Use TCP connections for queries instead of UDP datagrams. |
| 131 | .Tn TCP | 136 | .It Dv RES_PRIMARY |
| 132 | connections for queries instead of | 137 | Query the primary name server only. |
| 133 | .Tn UDP | 138 | Currently this is not implemented. |
| 134 | datagrams. | ||
| 135 | .It Dv RES_STAYOPEN | ||
| 136 | Used with | ||
| 137 | .Dv RES_USEVC | ||
| 138 | to keep the | ||
| 139 | .Tn TCP | ||
| 140 | connection open between | ||
| 141 | queries. | ||
| 142 | This is useful only in programs that regularly do many queries. | ||
| 143 | .Tn UDP | ||
| 144 | should be the normal mode used. | ||
| 145 | .It Dv RES_IGNTC | 139 | .It Dv RES_IGNTC |
| 146 | Unused currently (ignore truncation errors, i.e., don't retry with | 140 | Ignore truncation errors, i.e. don't retry with TCP. |
| 147 | .Tn TCP ) . | ||
| 148 | .It Dv RES_RECURSE | 141 | .It Dv RES_RECURSE |
| 149 | Set the recursion-desired bit in queries. | 142 | Set the recursion-desired bit in queries. |
| 150 | This is the default. | ||
| 151 | .Pf ( Fn res_send | 143 | .Pf ( Fn res_send |
| 152 | does not do iterative queries and expects the name server | 144 | does not do iterative queries and expects the name server |
| 153 | to handle recursion.) | 145 | to handle recursion.) |
| 146 | This option is enabled by default. | ||
| 154 | .It Dv RES_DEFNAMES | 147 | .It Dv RES_DEFNAMES |
| 155 | If set, | 148 | If set, |
| 156 | .Fn res_search | 149 | .Fn res_search |
| 157 | will append the default domain name to single-component names | 150 | will append the default domain name to single-component names |
| 158 | (those that do not contain a dot). | 151 | (those that do not contain a dot). |
| 159 | This option is enabled by default. | 152 | This option is enabled by default. |
| 153 | .It Dv RES_STAYOPEN | ||
| 154 | Used with | ||
| 155 | .Dv RES_USEVC | ||
| 156 | to keep the TCP connection open between queries. | ||
| 157 | This is useful only in programs that regularly do many queries. | ||
| 158 | UDP should be the normal mode used. | ||
| 160 | .It Dv RES_DNSRCH | 159 | .It Dv RES_DNSRCH |
| 161 | If this option is set, | 160 | If this option is set, |
| 162 | .Fn res_search | 161 | .Fn res_search |
| @@ -165,16 +164,45 @@ will search for host names in the current domain and in parent domains; see | |||
| 165 | This is used by the standard host lookup routine | 164 | This is used by the standard host lookup routine |
| 166 | .Xr gethostbyname 3 . | 165 | .Xr gethostbyname 3 . |
| 167 | This option is enabled by default. | 166 | This option is enabled by default. |
| 167 | .It Dv RES_INSECURE_1 | ||
| 168 | Do not require the IP source address on the reply packet | ||
| 169 | to be equal to the server's address. | ||
| 170 | .It Dv RES_INSECURE_2 | ||
| 171 | Do not check if the query section of the reply packet | ||
| 172 | is equal to that of the query packet. | ||
| 173 | .It Dv RES_NOALIASES | ||
| 174 | Turn off the | ||
| 175 | .Ev HOSTALIASES | ||
| 176 | feature. | ||
| 177 | See | ||
| 178 | .Xr hostname 7 | ||
| 179 | for more information. | ||
| 180 | .It Dv RES_USE_INET6 | ||
| 181 | Enables support for IPv6-only applications. | ||
| 182 | This causes IPv4 addresses to be returned as an IPv4 mapped address. | ||
| 183 | For example, 10.1.1.1 will be returned as ::ffff:10.1.1.1. | ||
| 184 | The option is not meaningful on | ||
| 185 | .Ox . | ||
| 186 | .It Dv RES_USE_EDNS0 | ||
| 187 | Attach an OPT pseudo-RR for the EDNS0 extension, | ||
| 188 | as specified in RFC 2671. | ||
| 189 | This informs DNS servers of a client's receive buffer size, | ||
| 190 | allowing them to take advantage of a non-default receive buffer size, | ||
| 191 | and thus to send larger replies. | ||
| 192 | DNS query packets with the EDNS0 extension are not compatible with | ||
| 193 | non-EDNS0 DNS servers. | ||
| 194 | .It Dv RES_USE_DNSSEC | ||
| 195 | Request that the resolver uses | ||
| 196 | Domain Name System Security Extensions (DNSSEC), | ||
| 197 | as defined in RFCs 4033, 4034, and 4035. | ||
| 168 | .El | 198 | .El |
| 169 | .Pp | 199 | .Pp |
| 170 | The | 200 | The |
| 171 | .Fn res_init | 201 | .Fn res_init |
| 172 | routine | 202 | routine reads the configuration file (if any; see |
| 173 | reads the configuration file (if any; see | ||
| 174 | .Xr resolv.conf 5 ) | 203 | .Xr resolv.conf 5 ) |
| 175 | to get the default domain name, | 204 | to get the default domain name, search list, and the Internet address |
| 176 | search list and | 205 | of the local name server(s). |
| 177 | the Internet address of the local name server(s). | ||
| 178 | If no server is configured, the host running | 206 | If no server is configured, the host running |
| 179 | the resolver is tried. | 207 | the resolver is tried. |
| 180 | The current domain name is defined by the hostname | 208 | The current domain name is defined by the hostname |
| @@ -212,20 +240,26 @@ The query requests information of the specified | |||
| 212 | .Fa type | 240 | .Fa type |
| 213 | and | 241 | and |
| 214 | .Fa class | 242 | .Fa class |
| 215 | for the specified fully-qualified domain name | 243 | for the specified fully qualified domain name |
| 216 | .Fa dname . | 244 | .Fa dname . |
| 217 | The reply message is left in the | 245 | The reply message is left in the |
| 218 | .Fa answer | 246 | .Fa answer |
| 219 | buffer with length | 247 | buffer with length |
| 220 | .Fa anslen | 248 | .Fa anslen |
| 221 | supplied by the caller. | 249 | supplied by the caller. |
| 250 | Values for the | ||
| 251 | .Fa class | ||
| 252 | and | ||
| 253 | .Fa type | ||
| 254 | fields | ||
| 255 | are defined in | ||
| 256 | .In arpa/nameser.h . | ||
| 222 | .Pp | 257 | .Pp |
| 223 | The | 258 | The |
| 224 | .Fn res_search | 259 | .Fn res_search |
| 225 | routine makes a query and awaits a response like | 260 | routine makes a query and awaits a response like |
| 226 | .Fn res_query , | 261 | .Fn res_query , |
| 227 | but in addition, it implements the default and search rules | 262 | but in addition, it implements the default and search rules controlled by the |
| 228 | controlled by the | ||
| 229 | .Dv RES_DEFNAMES | 263 | .Dv RES_DEFNAMES |
| 230 | and | 264 | and |
| 231 | .Dv RES_DNSRCH | 265 | .Dv RES_DNSRCH |
| @@ -236,40 +270,35 @@ The remaining routines are lower-level routines used by | |||
| 236 | .Fn res_query . | 270 | .Fn res_query . |
| 237 | The | 271 | The |
| 238 | .Fn res_mkquery | 272 | .Fn res_mkquery |
| 239 | function | 273 | function constructs a standard query message and places it in |
| 240 | constructs a standard query message and places it in | ||
| 241 | .Fa buf . | 274 | .Fa buf . |
| 242 | It returns the size of the query, or \-1 if the query is | 275 | It returns the size of the query, or \-1 if the query is larger than |
| 243 | larger than | ||
| 244 | .Fa buflen . | 276 | .Fa buflen . |
| 245 | The query type | 277 | The query type |
| 246 | .Fa op | 278 | .Fa op |
| 247 | is usually | 279 | is usually |
| 248 | .Dv QUERY , | 280 | .Dv QUERY , |
| 249 | but can be any of the query types defined in | 281 | but can be any of the query types defined in |
| 250 | .Aq Pa arpa/nameser.h . | 282 | .In arpa/nameser.h . |
| 251 | The domain name for the query is given by | 283 | The domain name for the query is given by |
| 252 | .Fa dname . | 284 | .Fa dname . |
| 253 | .Fa Newrr | 285 | .Fa newrr |
| 254 | is currently unused but is intended for making update messages. | 286 | is currently unused but is intended for making update messages. |
| 255 | .Pp | 287 | .Pp |
| 256 | The | 288 | The |
| 257 | .Fn res_send | 289 | .Fn res_send |
| 258 | routine | 290 | routine sends a pre-formatted query and returns an answer. |
| 259 | sends a pre-formatted query and returns an answer. | ||
| 260 | It will call | 291 | It will call |
| 261 | .Fn res_init | 292 | .Fn res_init |
| 262 | if | 293 | if |
| 263 | .Dv RES_INIT | 294 | .Dv RES_INIT |
| 264 | is not set, send the query to the local name server, and | 295 | is not set, send the query to the local name server, and |
| 265 | handle timeouts and retries. | 296 | handle timeouts and retries. |
| 266 | The length of the reply message is returned, or | 297 | The length of the reply message is returned, or \-1 if there were errors. |
| 267 | \-1 if there were errors. | ||
| 268 | .Pp | 298 | .Pp |
| 269 | The | 299 | The |
| 270 | .Fn dn_comp | 300 | .Fn dn_comp |
| 271 | function | 301 | function compresses the domain name |
| 272 | compresses the domain name | ||
| 273 | .Fa exp_dn | 302 | .Fa exp_dn |
| 274 | and stores it in | 303 | and stores it in |
| 275 | .Fa comp_dn . | 304 | .Fa comp_dn . |
| @@ -278,24 +307,23 @@ The size of the array pointed to by | |||
| 278 | .Fa comp_dn | 307 | .Fa comp_dn |
| 279 | is given by | 308 | is given by |
| 280 | .Fa length . | 309 | .Fa length . |
| 281 | The compression uses | 310 | The compression uses an array of pointers |
| 282 | an array of pointers | ||
| 283 | .Fa dnptrs | 311 | .Fa dnptrs |
| 284 | to previously-compressed names in the current message. | 312 | to previously compressed names in the current message. |
| 285 | The first pointer points to | 313 | The first pointer points |
| 286 | to the beginning of the message and the list ends with | 314 | to the beginning of the message and the list ends with |
| 287 | .Dv NULL . | 315 | .Dv NULL . |
| 288 | The limit to the array is specified by | 316 | The limit to the array is specified by |
| 289 | .Fa lastdnptr . | 317 | .Fa lastdnptr . |
| 290 | A side effect of | 318 | A side effect of |
| 291 | .Fn dn_comp | 319 | .Fn dn_comp |
| 292 | is to update the list of pointers for | 320 | is to update the list of pointers for labels inserted into the message |
| 293 | labels inserted into the message | ||
| 294 | as the name is compressed. | 321 | as the name is compressed. |
| 295 | If | 322 | If |
| 296 | .Em dnptr | 323 | .Fa dnptrs |
| 297 | is | 324 | is |
| 298 | .Dv NULL, names are not compressed. | 325 | .Dv NULL , |
| 326 | names are not compressed. | ||
| 299 | If | 327 | If |
| 300 | .Fa lastdnptr | 328 | .Fa lastdnptr |
| 301 | is | 329 | is |
| @@ -304,10 +332,9 @@ the list of labels is not updated. | |||
| 304 | .Pp | 332 | .Pp |
| 305 | The | 333 | The |
| 306 | .Fn dn_expand | 334 | .Fn dn_expand |
| 307 | entry | 335 | entry expands the compressed domain name |
| 308 | expands the compressed domain name | ||
| 309 | .Fa comp_dn | 336 | .Fa comp_dn |
| 310 | to a full domain name | 337 | to a full domain name. |
| 311 | The compressed name is contained in a query or reply message; | 338 | The compressed name is contained in a query or reply message; |
| 312 | .Fa msg | 339 | .Fa msg |
| 313 | is a pointer to the beginning of the message. | 340 | is a pointer to the beginning of the message. |
| @@ -317,28 +344,55 @@ which is of size | |||
| 317 | .Fa length . | 344 | .Fa length . |
| 318 | The size of compressed name is returned or \-1 if there was an error. | 345 | The size of compressed name is returned or \-1 if there was an error. |
| 319 | .Sh FILES | 346 | .Sh FILES |
| 320 | .Bl -tag -width Pa | 347 | .Bl -tag -width "/etc/resolv.confXX" |
| 321 | /etc/resolv.conf | 348 | .It Pa /etc/resolv.conf |
| 322 | The configuration file | 349 | The configuration file. |
| 323 | see | ||
| 324 | .Xr resolv.conf 5 . | ||
| 325 | .El | 350 | .El |
| 326 | .Sh SEE ALSO | 351 | .Sh SEE ALSO |
| 327 | .Xr gethostbyname 3 , | 352 | .Xr gethostbyname 3 , |
| 328 | .Xr named 8 , | ||
| 329 | .Xr resolv.conf 5 , | 353 | .Xr resolv.conf 5 , |
| 330 | .Xr hostname 7 , | 354 | .Xr hostname 7 , |
| 355 | .Xr named 8 | ||
| 356 | .Rs | ||
| 357 | .%T Name Server Operations Guide for BIND | ||
| 358 | .Re | ||
| 359 | .Sh STANDARDS | ||
| 360 | .Rs | ||
| 361 | .%A M. Stahl | ||
| 362 | .%D November 1987 | ||
| 363 | .%R RFC 1032 | ||
| 364 | .%T Domain Administrators Guide | ||
| 365 | .Re | ||
| 366 | .Pp | ||
| 367 | .Rs | ||
| 368 | .%A M. Lottor | ||
| 369 | .%D November 1987 | ||
| 370 | .%R RFC 1033 | ||
| 371 | .%T Domain Administrators Operations Guide | ||
| 372 | .Re | ||
| 373 | .Pp | ||
| 374 | .Rs | ||
| 375 | .%A P. Mockapetris | ||
| 376 | .%D November 1987 | ||
| 377 | .%R RFC 1034 | ||
| 378 | .%T Domain Names \(en Concepts and Facilities | ||
| 379 | .Re | ||
| 380 | .Pp | ||
| 381 | .Rs | ||
| 382 | .%A P. Mockapetris | ||
| 383 | .%D November 1987 | ||
| 384 | .%R RFC 1035 | ||
| 385 | .%T Domain Names \(en Implementation and Specification | ||
| 386 | .Re | ||
| 331 | .Pp | 387 | .Pp |
| 332 | .%T RFC1032 , | ||
| 333 | .%T RFC1033 , | ||
| 334 | .%T RFC1034 , | ||
| 335 | .%T RFC1035 , | ||
| 336 | .%T RFC974 | ||
| 337 | .Rs | 388 | .Rs |
| 338 | .%T "Name Server Operations Guide for BIND" | 389 | .%A J. Klensin |
| 390 | .%D October 2008 | ||
| 391 | .%R RFC 5321 | ||
| 392 | .%T Simple Mail Transfer Protocol | ||
| 339 | .Re | 393 | .Re |
| 340 | .Sh HISTORY | 394 | .Sh HISTORY |
| 341 | The | 395 | The |
| 342 | .Nm | 396 | .Nm |
| 343 | function appeared in | 397 | function appeared in |
| 344 | .Bx 4.3 . | 398 | .Bx 4.3 . |
diff --git a/src/lib/libc/net/rresvport.c b/src/lib/libc/net/rresvport.c new file mode 100644 index 0000000000..ccc411500b --- /dev/null +++ b/src/lib/libc/net/rresvport.c | |||
| @@ -0,0 +1,107 @@ | |||
| 1 | /* $OpenBSD: rresvport.c,v 1.9 2005/11/10 10:00:17 espie Exp $ */ | ||
| 2 | /* | ||
| 3 | * Copyright (c) 1995, 1996, 1998 Theo de Raadt. All rights reserved. | ||
| 4 | * Copyright (c) 1983, 1993, 1994 | ||
| 5 | * The Regents of the University of California. All rights reserved. | ||
| 6 | * | ||
| 7 | * Redistribution and use in source and binary forms, with or without | ||
| 8 | * modification, are permitted provided that the following conditions | ||
| 9 | * are met: | ||
| 10 | * 1. Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 13 | * notice, this list of conditions and the following disclaimer in the | ||
| 14 | * documentation and/or other materials provided with the distribution. | ||
| 15 | * 3. Neither the name of the University nor the names of its contributors | ||
| 16 | * may be used to endorse or promote products derived from this software | ||
| 17 | * without specific prior written permission. | ||
| 18 | * | ||
| 19 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
| 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
| 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 29 | * SUCH DAMAGE. | ||
| 30 | */ | ||
| 31 | |||
| 32 | #include <sys/param.h> | ||
| 33 | #include <sys/socket.h> | ||
| 34 | #include <sys/stat.h> | ||
| 35 | |||
| 36 | #include <netinet/in.h> | ||
| 37 | #include <arpa/inet.h> | ||
| 38 | |||
| 39 | #include <signal.h> | ||
| 40 | #include <fcntl.h> | ||
| 41 | #include <netdb.h> | ||
| 42 | #include <unistd.h> | ||
| 43 | #include <pwd.h> | ||
| 44 | #include <errno.h> | ||
| 45 | #include <stdio.h> | ||
| 46 | #include <ctype.h> | ||
| 47 | #include <string.h> | ||
| 48 | #include <syslog.h> | ||
| 49 | #include <stdlib.h> | ||
| 50 | #include <netgroup.h> | ||
| 51 | |||
| 52 | int | ||
| 53 | rresvport(int *alport) | ||
| 54 | { | ||
| 55 | return rresvport_af(alport, AF_INET); | ||
| 56 | } | ||
| 57 | |||
| 58 | |||
| 59 | int | ||
| 60 | rresvport_af(int *alport, int af) | ||
| 61 | { | ||
| 62 | struct sockaddr_storage ss; | ||
| 63 | struct sockaddr *sa; | ||
| 64 | u_int16_t *portp; | ||
| 65 | int s; | ||
| 66 | |||
| 67 | bzero(&ss, sizeof ss); | ||
| 68 | sa = (struct sockaddr *)&ss; | ||
| 69 | |||
| 70 | switch (af) { | ||
| 71 | case AF_INET: | ||
| 72 | sa->sa_len = sizeof(struct sockaddr_in); | ||
| 73 | portp = &((struct sockaddr_in *)sa)->sin_port; | ||
| 74 | break; | ||
| 75 | case AF_INET6: | ||
| 76 | sa->sa_len = sizeof(struct sockaddr_in6); | ||
| 77 | portp = &((struct sockaddr_in6 *)sa)->sin6_port; | ||
| 78 | break; | ||
| 79 | default: | ||
| 80 | errno = EPFNOSUPPORT; | ||
| 81 | return (-1); | ||
| 82 | } | ||
| 83 | sa->sa_family = af; | ||
| 84 | |||
| 85 | s = socket(af, SOCK_STREAM, 0); | ||
| 86 | if (s < 0) | ||
| 87 | return (-1); | ||
| 88 | |||
| 89 | *portp = htons(*alport); | ||
| 90 | if (*alport < IPPORT_RESERVED - 1) { | ||
| 91 | if (bind(s, sa, sa->sa_len) >= 0) | ||
| 92 | return (s); | ||
| 93 | if (errno != EADDRINUSE) { | ||
| 94 | (void)close(s); | ||
| 95 | return (-1); | ||
| 96 | } | ||
| 97 | } | ||
| 98 | |||
| 99 | *portp = 0; | ||
| 100 | sa->sa_family = af; | ||
| 101 | if (bindresvport_sa(s, sa) == -1) { | ||
| 102 | (void)close(s); | ||
| 103 | return (-1); | ||
| 104 | } | ||
| 105 | *alport = ntohs(*portp); | ||
| 106 | return (s); | ||
| 107 | } | ||
diff --git a/src/lib/libc/net/rthdr.c b/src/lib/libc/net/rthdr.c new file mode 100644 index 0000000000..d10334e027 --- /dev/null +++ b/src/lib/libc/net/rthdr.c | |||
| @@ -0,0 +1,378 @@ | |||
| 1 | /* $OpenBSD: rthdr.c,v 1.8 2006/12/09 01:12:28 itojun Exp $ */ | ||
| 2 | /* $KAME: rthdr.c,v 1.22 2006/02/09 08:18:58 keiichi Exp $ */ | ||
| 3 | |||
| 4 | /* | ||
| 5 | * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. | ||
| 6 | * All rights reserved. | ||
| 7 | * | ||
| 8 | * Redistribution and use in source and binary forms, with or without | ||
| 9 | * modification, are permitted provided that the following conditions | ||
| 10 | * are met: | ||
| 11 | * 1. Redistributions of source code must retain the above copyright | ||
| 12 | * notice, this list of conditions and the following disclaimer. | ||
| 13 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in the | ||
| 15 | * documentation and/or other materials provided with the distribution. | ||
| 16 | * 3. Neither the name of the project nor the names of its contributors | ||
| 17 | * may be used to endorse or promote products derived from this software | ||
| 18 | * without specific prior written permission. | ||
| 19 | * | ||
| 20 | * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND | ||
| 21 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 22 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 23 | * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE | ||
| 24 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 25 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 26 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 27 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 28 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 29 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 30 | * SUCH DAMAGE. | ||
| 31 | */ | ||
| 32 | |||
| 33 | #include <sys/param.h> | ||
| 34 | #include <sys/types.h> | ||
| 35 | #include <sys/socket.h> | ||
| 36 | |||
| 37 | #include <netinet/in.h> | ||
| 38 | #include <netinet/ip6.h> | ||
| 39 | |||
| 40 | #include <string.h> | ||
| 41 | #include <stdio.h> | ||
| 42 | |||
| 43 | /* | ||
| 44 | * RFC2292 API | ||
| 45 | */ | ||
| 46 | |||
| 47 | size_t | ||
| 48 | inet6_rthdr_space(int type, int seg) | ||
| 49 | { | ||
| 50 | switch (type) { | ||
| 51 | case IPV6_RTHDR_TYPE_0: | ||
| 52 | if (seg < 1 || seg > 23) | ||
| 53 | return (0); | ||
| 54 | return (CMSG_SPACE(sizeof(struct in6_addr) * seg + | ||
| 55 | sizeof(struct ip6_rthdr0))); | ||
| 56 | default: | ||
| 57 | return (0); | ||
| 58 | } | ||
| 59 | } | ||
| 60 | |||
| 61 | struct cmsghdr * | ||
| 62 | inet6_rthdr_init(void *bp, int type) | ||
| 63 | { | ||
| 64 | struct cmsghdr *ch = (struct cmsghdr *)bp; | ||
| 65 | struct ip6_rthdr *rthdr; | ||
| 66 | |||
| 67 | rthdr = (struct ip6_rthdr *)CMSG_DATA(ch); | ||
| 68 | |||
| 69 | ch->cmsg_level = IPPROTO_IPV6; | ||
| 70 | ch->cmsg_type = IPV6_RTHDR; | ||
| 71 | |||
| 72 | switch (type) { | ||
| 73 | case IPV6_RTHDR_TYPE_0: | ||
| 74 | ch->cmsg_len = CMSG_LEN(sizeof(struct ip6_rthdr0)); | ||
| 75 | bzero(rthdr, sizeof(struct ip6_rthdr0)); | ||
| 76 | rthdr->ip6r_type = IPV6_RTHDR_TYPE_0; | ||
| 77 | return (ch); | ||
| 78 | default: | ||
| 79 | return (NULL); | ||
| 80 | } | ||
| 81 | } | ||
| 82 | |||
| 83 | int | ||
| 84 | inet6_rthdr_add(struct cmsghdr *cmsg, const struct in6_addr *addr, u_int flags) | ||
| 85 | { | ||
| 86 | struct ip6_rthdr *rthdr; | ||
| 87 | |||
| 88 | rthdr = (struct ip6_rthdr *)CMSG_DATA(cmsg); | ||
| 89 | |||
| 90 | switch (rthdr->ip6r_type) { | ||
| 91 | case IPV6_RTHDR_TYPE_0: | ||
| 92 | { | ||
| 93 | struct ip6_rthdr0 *rt0 = (struct ip6_rthdr0 *)rthdr; | ||
| 94 | if (flags != IPV6_RTHDR_LOOSE) | ||
| 95 | return (-1); | ||
| 96 | if (rt0->ip6r0_segleft == 23) | ||
| 97 | return (-1); | ||
| 98 | rt0->ip6r0_segleft++; | ||
| 99 | bcopy(addr, (caddr_t)rt0 + ((rt0->ip6r0_len + 1) << 3), | ||
| 100 | sizeof(struct in6_addr)); | ||
| 101 | rt0->ip6r0_len += sizeof(struct in6_addr) >> 3; | ||
| 102 | cmsg->cmsg_len = CMSG_LEN((rt0->ip6r0_len + 1) << 3); | ||
| 103 | break; | ||
| 104 | } | ||
| 105 | default: | ||
| 106 | return (-1); | ||
| 107 | } | ||
| 108 | |||
| 109 | return (0); | ||
| 110 | } | ||
| 111 | |||
| 112 | int | ||
| 113 | inet6_rthdr_lasthop(struct cmsghdr *cmsg, unsigned int flags) | ||
| 114 | { | ||
| 115 | struct ip6_rthdr *rthdr; | ||
| 116 | |||
| 117 | rthdr = (struct ip6_rthdr *)CMSG_DATA(cmsg); | ||
| 118 | |||
| 119 | switch (rthdr->ip6r_type) { | ||
| 120 | case IPV6_RTHDR_TYPE_0: | ||
| 121 | { | ||
| 122 | struct ip6_rthdr0 *rt0 = (struct ip6_rthdr0 *)rthdr; | ||
| 123 | if (flags != IPV6_RTHDR_LOOSE) | ||
| 124 | return (-1); | ||
| 125 | if (rt0->ip6r0_segleft > 23) | ||
| 126 | return (-1); | ||
| 127 | break; | ||
| 128 | } | ||
| 129 | default: | ||
| 130 | return (-1); | ||
| 131 | } | ||
| 132 | |||
| 133 | return (0); | ||
| 134 | } | ||
| 135 | |||
| 136 | #if 0 | ||
| 137 | int | ||
| 138 | inet6_rthdr_reverse(in, out) | ||
| 139 | const struct cmsghdr *in; | ||
| 140 | struct cmsghdr *out; | ||
| 141 | { | ||
| 142 | |||
| 143 | return (-1); | ||
| 144 | } | ||
| 145 | #endif | ||
| 146 | |||
| 147 | int | ||
| 148 | inet6_rthdr_segments(const struct cmsghdr *cmsg) | ||
| 149 | { | ||
| 150 | struct ip6_rthdr *rthdr; | ||
| 151 | |||
| 152 | rthdr = (struct ip6_rthdr *)CMSG_DATA(cmsg); | ||
| 153 | |||
| 154 | switch (rthdr->ip6r_type) { | ||
| 155 | case IPV6_RTHDR_TYPE_0: | ||
| 156 | { | ||
| 157 | struct ip6_rthdr0 *rt0 = (struct ip6_rthdr0 *)rthdr; | ||
| 158 | |||
| 159 | if (rt0->ip6r0_len % 2 || 46 < rt0->ip6r0_len) | ||
| 160 | return (-1); | ||
| 161 | |||
| 162 | return (rt0->ip6r0_len * 8) / sizeof(struct in6_addr); | ||
| 163 | } | ||
| 164 | |||
| 165 | default: | ||
| 166 | return (-1); | ||
| 167 | } | ||
| 168 | } | ||
| 169 | |||
| 170 | struct in6_addr * | ||
| 171 | inet6_rthdr_getaddr(struct cmsghdr *cmsg, int index) | ||
| 172 | { | ||
| 173 | struct ip6_rthdr *rthdr; | ||
| 174 | |||
| 175 | rthdr = (struct ip6_rthdr *)CMSG_DATA(cmsg); | ||
| 176 | |||
| 177 | switch (rthdr->ip6r_type) { | ||
| 178 | case IPV6_RTHDR_TYPE_0: | ||
| 179 | { | ||
| 180 | struct ip6_rthdr0 *rt0 = (struct ip6_rthdr0 *)rthdr; | ||
| 181 | int naddr; | ||
| 182 | |||
| 183 | if (rt0->ip6r0_len % 2 || 46 < rt0->ip6r0_len) | ||
| 184 | return NULL; | ||
| 185 | naddr = (rt0->ip6r0_len * 8) / sizeof(struct in6_addr); | ||
| 186 | if (index <= 0 || naddr < index) | ||
| 187 | return NULL; | ||
| 188 | return ((struct in6_addr *)(rt0 + 1)) + index; | ||
| 189 | } | ||
| 190 | |||
| 191 | default: | ||
| 192 | return NULL; | ||
| 193 | } | ||
| 194 | } | ||
| 195 | |||
| 196 | int | ||
| 197 | inet6_rthdr_getflags(const struct cmsghdr *cmsg, int index) | ||
| 198 | { | ||
| 199 | struct ip6_rthdr *rthdr; | ||
| 200 | |||
| 201 | rthdr = (struct ip6_rthdr *)CMSG_DATA(cmsg); | ||
| 202 | |||
| 203 | switch (rthdr->ip6r_type) { | ||
| 204 | case IPV6_RTHDR_TYPE_0: | ||
| 205 | { | ||
| 206 | struct ip6_rthdr0 *rt0 = (struct ip6_rthdr0 *)rthdr; | ||
| 207 | int naddr; | ||
| 208 | |||
| 209 | if (rt0->ip6r0_len % 2 || 46 < rt0->ip6r0_len) | ||
| 210 | return (-1); | ||
| 211 | naddr = (rt0->ip6r0_len * 8) / sizeof(struct in6_addr); | ||
| 212 | if (index < 0 || naddr < index) | ||
| 213 | return (-1); | ||
| 214 | return IPV6_RTHDR_LOOSE; | ||
| 215 | } | ||
| 216 | |||
| 217 | default: | ||
| 218 | return (-1); | ||
| 219 | } | ||
| 220 | } | ||
| 221 | |||
| 222 | /* | ||
| 223 | * RFC3542 (2292bis) API | ||
| 224 | */ | ||
| 225 | |||
| 226 | socklen_t | ||
| 227 | inet6_rth_space(int type, int segments) | ||
| 228 | { | ||
| 229 | switch (type) { | ||
| 230 | case IPV6_RTHDR_TYPE_0: | ||
| 231 | return (((segments * 2) + 1) << 3); | ||
| 232 | default: | ||
| 233 | return (0); /* type not suppported */ | ||
| 234 | } | ||
| 235 | } | ||
| 236 | |||
| 237 | void * | ||
| 238 | inet6_rth_init(void *bp, socklen_t bp_len, int type, int segments) | ||
| 239 | { | ||
| 240 | struct ip6_rthdr *rth = (struct ip6_rthdr *)bp; | ||
| 241 | struct ip6_rthdr0 *rth0; | ||
| 242 | |||
| 243 | switch (type) { | ||
| 244 | case IPV6_RTHDR_TYPE_0: | ||
| 245 | /* length validation */ | ||
| 246 | if (bp_len < inet6_rth_space(IPV6_RTHDR_TYPE_0, segments)) | ||
| 247 | return (NULL); | ||
| 248 | |||
| 249 | memset(bp, 0, bp_len); | ||
| 250 | rth0 = (struct ip6_rthdr0 *)rth; | ||
| 251 | rth0->ip6r0_len = segments * 2; | ||
| 252 | rth0->ip6r0_type = IPV6_RTHDR_TYPE_0; | ||
| 253 | rth0->ip6r0_segleft = 0; | ||
| 254 | rth0->ip6r0_reserved = 0; | ||
| 255 | break; | ||
| 256 | default: | ||
| 257 | return (NULL); /* type not supported */ | ||
| 258 | } | ||
| 259 | |||
| 260 | return (bp); | ||
| 261 | } | ||
| 262 | |||
| 263 | int | ||
| 264 | inet6_rth_add(void *bp, const struct in6_addr *addr) | ||
| 265 | { | ||
| 266 | struct ip6_rthdr *rth = (struct ip6_rthdr *)bp; | ||
| 267 | struct ip6_rthdr0 *rth0; | ||
| 268 | struct in6_addr *nextaddr; | ||
| 269 | |||
| 270 | switch (rth->ip6r_type) { | ||
| 271 | case IPV6_RTHDR_TYPE_0: | ||
| 272 | rth0 = (struct ip6_rthdr0 *)rth; | ||
| 273 | nextaddr = (struct in6_addr *)(rth0 + 1) + rth0->ip6r0_segleft; | ||
| 274 | *nextaddr = *addr; | ||
| 275 | rth0->ip6r0_segleft++; | ||
| 276 | break; | ||
| 277 | default: | ||
| 278 | return (-1); /* type not supported */ | ||
| 279 | } | ||
| 280 | |||
| 281 | return (0); | ||
| 282 | } | ||
| 283 | |||
| 284 | int | ||
| 285 | inet6_rth_reverse(const void *in, void *out) | ||
| 286 | { | ||
| 287 | struct ip6_rthdr *rth_in = (struct ip6_rthdr *)in; | ||
| 288 | struct ip6_rthdr0 *rth0_in, *rth0_out; | ||
| 289 | int i, segments; | ||
| 290 | |||
| 291 | switch (rth_in->ip6r_type) { | ||
| 292 | case IPV6_RTHDR_TYPE_0: | ||
| 293 | rth0_in = (struct ip6_rthdr0 *)in; | ||
| 294 | rth0_out = (struct ip6_rthdr0 *)out; | ||
| 295 | |||
| 296 | /* parameter validation XXX too paranoid? */ | ||
| 297 | if (rth0_in->ip6r0_len % 2) | ||
| 298 | return (-1); | ||
| 299 | segments = rth0_in->ip6r0_len / 2; | ||
| 300 | |||
| 301 | /* we can't use memcpy here, since in and out may overlap */ | ||
| 302 | memmove((void *)rth0_out, (void *)rth0_in, | ||
| 303 | ((rth0_in->ip6r0_len) + 1) << 3); | ||
| 304 | rth0_out->ip6r0_segleft = segments; | ||
| 305 | |||
| 306 | /* reverse the addresses */ | ||
| 307 | for (i = 0; i < segments / 2; i++) { | ||
| 308 | struct in6_addr addr_tmp, *addr1, *addr2; | ||
| 309 | |||
| 310 | addr1 = (struct in6_addr *)(rth0_out + 1) + i; | ||
| 311 | addr2 = (struct in6_addr *)(rth0_out + 1) + | ||
| 312 | (segments - i - 1); | ||
| 313 | addr_tmp = *addr1; | ||
| 314 | *addr1 = *addr2; | ||
| 315 | *addr2 = addr_tmp; | ||
| 316 | } | ||
| 317 | |||
| 318 | break; | ||
| 319 | default: | ||
| 320 | return (-1); /* type not supported */ | ||
| 321 | } | ||
| 322 | |||
| 323 | return (0); | ||
| 324 | } | ||
| 325 | |||
| 326 | int | ||
| 327 | inet6_rth_segments(const void *bp) | ||
| 328 | { | ||
| 329 | struct ip6_rthdr *rh = (struct ip6_rthdr *)bp; | ||
| 330 | struct ip6_rthdr0 *rh0; | ||
| 331 | int addrs; | ||
| 332 | |||
| 333 | switch (rh->ip6r_type) { | ||
| 334 | case IPV6_RTHDR_TYPE_0: | ||
| 335 | rh0 = (struct ip6_rthdr0 *)bp; | ||
| 336 | |||
| 337 | /* | ||
| 338 | * Validation for a type-0 routing header. | ||
| 339 | * Is this too strict? | ||
| 340 | */ | ||
| 341 | if ((rh0->ip6r0_len % 2) != 0 || | ||
| 342 | (addrs = (rh0->ip6r0_len >> 1)) < rh0->ip6r0_segleft) | ||
| 343 | return (-1); | ||
| 344 | |||
| 345 | return (addrs); | ||
| 346 | default: | ||
| 347 | return (-1); /* unknown type */ | ||
| 348 | } | ||
| 349 | } | ||
| 350 | |||
| 351 | struct in6_addr * | ||
| 352 | inet6_rth_getaddr(const void *bp, int idx) | ||
| 353 | { | ||
| 354 | struct ip6_rthdr *rh = (struct ip6_rthdr *)bp; | ||
| 355 | struct ip6_rthdr0 *rh0; | ||
| 356 | int addrs; | ||
| 357 | |||
| 358 | switch (rh->ip6r_type) { | ||
| 359 | case IPV6_RTHDR_TYPE_0: | ||
| 360 | rh0 = (struct ip6_rthdr0 *)bp; | ||
| 361 | |||
| 362 | /* | ||
| 363 | * Validation for a type-0 routing header. | ||
| 364 | * Is this too strict? | ||
| 365 | */ | ||
| 366 | if ((rh0->ip6r0_len % 2) != 0 || | ||
| 367 | (addrs = (rh0->ip6r0_len >> 1)) < rh0->ip6r0_segleft) | ||
| 368 | return (NULL); | ||
| 369 | |||
| 370 | if (idx < 0 || addrs <= idx) | ||
| 371 | return (NULL); | ||
| 372 | |||
| 373 | return (((struct in6_addr *)(rh0 + 1)) + idx); | ||
| 374 | default: | ||
| 375 | return (NULL); /* unknown type */ | ||
| 376 | break; | ||
| 377 | } | ||
| 378 | } | ||
diff --git a/src/lib/libc/net/ruserok.c b/src/lib/libc/net/ruserok.c new file mode 100644 index 0000000000..21646c156b --- /dev/null +++ b/src/lib/libc/net/ruserok.c | |||
| @@ -0,0 +1,438 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1995, 1996, 1998 Theo de Raadt. All rights reserved. | ||
| 3 | * Copyright (c) 1983, 1993, 1994 | ||
| 4 | * The Regents of the University of California. All rights reserved. | ||
| 5 | * | ||
| 6 | * Redistribution and use in source and binary forms, with or without | ||
| 7 | * modification, are permitted provided that the following conditions | ||
| 8 | * are met: | ||
| 9 | * 1. Redistributions of source code must retain the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer. | ||
| 11 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 12 | * notice, this list of conditions and the following disclaimer in the | ||
| 13 | * documentation and/or other materials provided with the distribution. | ||
| 14 | * 3. Neither the name of the University nor the names of its contributors | ||
| 15 | * may be used to endorse or promote products derived from this software | ||
| 16 | * without specific prior written permission. | ||
| 17 | * | ||
| 18 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
| 19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
| 22 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 23 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 24 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 26 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 27 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 28 | * SUCH DAMAGE. | ||
| 29 | */ | ||
| 30 | |||
| 31 | #include <sys/socket.h> | ||
| 32 | #include <sys/stat.h> | ||
| 33 | |||
| 34 | #include <netinet/in.h> | ||
| 35 | #include <arpa/inet.h> | ||
| 36 | |||
| 37 | #include <ctype.h> | ||
| 38 | #include <errno.h> | ||
| 39 | #include <fcntl.h> | ||
| 40 | #include <limits.h> | ||
| 41 | #include <netdb.h> | ||
| 42 | #include <netgroup.h> | ||
| 43 | #include <pwd.h> | ||
| 44 | #include <signal.h> | ||
| 45 | #include <stdio.h> | ||
| 46 | #include <stdlib.h> | ||
| 47 | #include <string.h> | ||
| 48 | #include <syslog.h> | ||
| 49 | #include <unistd.h> | ||
| 50 | |||
| 51 | int __ivaliduser(FILE *, in_addr_t, const char *, const char *); | ||
| 52 | int __ivaliduser_sa(FILE *, struct sockaddr *, socklen_t, | ||
| 53 | const char *, const char *); | ||
| 54 | static int __icheckhost(struct sockaddr *, socklen_t, const char *); | ||
| 55 | static char *__gethostloop(struct sockaddr *, socklen_t); | ||
| 56 | |||
| 57 | int __check_rhosts_file = 1; | ||
| 58 | char *__rcmd_errstr; | ||
| 59 | |||
| 60 | int | ||
| 61 | ruserok(const char *rhost, int superuser, const char *ruser, const char *luser) | ||
| 62 | { | ||
| 63 | struct addrinfo hints, *res, *r; | ||
| 64 | int error; | ||
| 65 | |||
| 66 | memset(&hints, 0, sizeof(hints)); | ||
| 67 | hints.ai_family = PF_UNSPEC; | ||
| 68 | hints.ai_socktype = SOCK_DGRAM; /*dummy*/ | ||
| 69 | error = getaddrinfo(rhost, "0", &hints, &res); | ||
| 70 | if (error) | ||
| 71 | return (-1); | ||
| 72 | |||
| 73 | for (r = res; r; r = r->ai_next) { | ||
| 74 | if (iruserok_sa(r->ai_addr, r->ai_addrlen, superuser, ruser, | ||
| 75 | luser) == 0) { | ||
| 76 | freeaddrinfo(res); | ||
| 77 | return (0); | ||
| 78 | } | ||
| 79 | } | ||
| 80 | freeaddrinfo(res); | ||
| 81 | return (-1); | ||
| 82 | } | ||
| 83 | |||
| 84 | /* | ||
| 85 | * New .rhosts strategy: We are passed an ip address. We spin through | ||
| 86 | * hosts.equiv and .rhosts looking for a match. When the .rhosts only | ||
| 87 | * has ip addresses, we don't have to trust a nameserver. When it | ||
| 88 | * contains hostnames, we spin through the list of addresses the nameserver | ||
| 89 | * gives us and look for a match. | ||
| 90 | * | ||
| 91 | * Returns 0 if ok, -1 if not ok. | ||
| 92 | */ | ||
| 93 | int | ||
| 94 | iruserok(u_int32_t raddr, int superuser, const char *ruser, const char *luser) | ||
| 95 | { | ||
| 96 | struct sockaddr_in sin; | ||
| 97 | |||
| 98 | memset(&sin, 0, sizeof(sin)); | ||
| 99 | sin.sin_family = AF_INET; | ||
| 100 | sin.sin_len = sizeof(struct sockaddr_in); | ||
| 101 | memcpy(&sin.sin_addr, &raddr, sizeof(sin.sin_addr)); | ||
| 102 | return iruserok_sa(&sin, sizeof(struct sockaddr_in), superuser, ruser, | ||
| 103 | luser); | ||
| 104 | } | ||
| 105 | |||
| 106 | int | ||
| 107 | iruserok_sa(const void *raddr, int rlen, int superuser, const char *ruser, | ||
| 108 | const char *luser) | ||
| 109 | { | ||
| 110 | struct sockaddr *sa; | ||
| 111 | char *cp; | ||
| 112 | struct stat sbuf; | ||
| 113 | struct passwd *pwd; | ||
| 114 | FILE *hostf; | ||
| 115 | uid_t uid; | ||
| 116 | int first; | ||
| 117 | char pbuf[PATH_MAX]; | ||
| 118 | |||
| 119 | sa = (struct sockaddr *)raddr; | ||
| 120 | first = 1; | ||
| 121 | hostf = superuser ? NULL : fopen(_PATH_HEQUIV, "r"); | ||
| 122 | again: | ||
| 123 | if (hostf) { | ||
| 124 | if (__ivaliduser_sa(hostf, sa, rlen, luser, ruser) == 0) { | ||
| 125 | (void)fclose(hostf); | ||
| 126 | return (0); | ||
| 127 | } | ||
| 128 | (void)fclose(hostf); | ||
| 129 | } | ||
| 130 | if (first == 1 && (__check_rhosts_file || superuser)) { | ||
| 131 | int len; | ||
| 132 | |||
| 133 | first = 0; | ||
| 134 | if ((pwd = getpwnam(luser)) == NULL) | ||
| 135 | return (-1); | ||
| 136 | len = snprintf(pbuf, sizeof pbuf, "%s/.rhosts", pwd->pw_dir); | ||
| 137 | if (len < 0 || len >= sizeof pbuf) | ||
| 138 | return (-1); | ||
| 139 | |||
| 140 | /* | ||
| 141 | * Change effective uid while opening .rhosts. If root and | ||
| 142 | * reading an NFS mounted file system, can't read files that | ||
| 143 | * are protected read/write owner only. | ||
| 144 | */ | ||
| 145 | uid = geteuid(); | ||
| 146 | (void)seteuid(pwd->pw_uid); | ||
| 147 | hostf = fopen(pbuf, "r"); | ||
| 148 | (void)seteuid(uid); | ||
| 149 | |||
| 150 | if (hostf == NULL) | ||
| 151 | return (-1); | ||
| 152 | /* | ||
| 153 | * If not a regular file, or is owned by someone other than | ||
| 154 | * user or root or if writeable by anyone but the owner, quit. | ||
| 155 | */ | ||
| 156 | cp = NULL; | ||
| 157 | if (lstat(pbuf, &sbuf) < 0) | ||
| 158 | cp = ".rhosts lstat failed"; | ||
| 159 | else if (!S_ISREG(sbuf.st_mode)) | ||
| 160 | cp = ".rhosts not regular file"; | ||
| 161 | else if (fstat(fileno(hostf), &sbuf) < 0) | ||
| 162 | cp = ".rhosts fstat failed"; | ||
| 163 | else if (sbuf.st_uid && sbuf.st_uid != pwd->pw_uid) | ||
| 164 | cp = "bad .rhosts owner"; | ||
| 165 | else if (sbuf.st_mode & (S_IWGRP|S_IWOTH)) | ||
| 166 | cp = ".rhosts writable by other than owner"; | ||
| 167 | /* If there were any problems, quit. */ | ||
| 168 | if (cp) { | ||
| 169 | __rcmd_errstr = cp; | ||
| 170 | (void)fclose(hostf); | ||
| 171 | return (-1); | ||
| 172 | } | ||
| 173 | goto again; | ||
| 174 | } | ||
| 175 | return (-1); | ||
| 176 | } | ||
| 177 | |||
| 178 | /* | ||
| 179 | * XXX | ||
| 180 | * Don't make static, used by lpd(8). | ||
| 181 | * | ||
| 182 | * Returns 0 if ok, -1 if not ok. | ||
| 183 | */ | ||
| 184 | int | ||
| 185 | __ivaliduser(FILE *hostf, in_addr_t raddrl, const char *luser, | ||
| 186 | const char *ruser) | ||
| 187 | { | ||
| 188 | struct sockaddr_in sin; | ||
| 189 | |||
| 190 | memset(&sin, 0, sizeof(sin)); | ||
| 191 | sin.sin_family = AF_INET; | ||
| 192 | sin.sin_len = sizeof(struct sockaddr_in); | ||
| 193 | memcpy(&sin.sin_addr, &raddrl, sizeof(sin.sin_addr)); | ||
| 194 | return __ivaliduser_sa(hostf, (struct sockaddr *)&sin, sin.sin_len, | ||
| 195 | luser, ruser); | ||
| 196 | } | ||
| 197 | |||
| 198 | int | ||
| 199 | __ivaliduser_sa(FILE *hostf, struct sockaddr *raddr, socklen_t salen, | ||
| 200 | const char *luser, const char *ruser) | ||
| 201 | { | ||
| 202 | char *user, *p; | ||
| 203 | char *buf; | ||
| 204 | const char *auser, *ahost; | ||
| 205 | int hostok, userok; | ||
| 206 | char *rhost = (char *)-1; | ||
| 207 | char domain[MAXHOSTNAMELEN]; | ||
| 208 | size_t buflen; | ||
| 209 | |||
| 210 | getdomainname(domain, sizeof(domain)); | ||
| 211 | |||
| 212 | while ((buf = fgetln(hostf, &buflen))) { | ||
| 213 | p = buf; | ||
| 214 | if (*p == '#') | ||
| 215 | continue; | ||
| 216 | while (p < buf + buflen && *p != '\n' && *p != ' ' && *p != '\t') { | ||
| 217 | if (!isprint((unsigned char)*p)) | ||
| 218 | goto bail; | ||
| 219 | *p = isupper((unsigned char)*p) ? | ||
| 220 | tolower((unsigned char)*p) : *p; | ||
| 221 | p++; | ||
| 222 | } | ||
| 223 | if (p >= buf + buflen) | ||
| 224 | continue; | ||
| 225 | if (*p == ' ' || *p == '\t') { | ||
| 226 | *p++ = '\0'; | ||
| 227 | while (p < buf + buflen && (*p == ' ' || *p == '\t')) | ||
| 228 | p++; | ||
| 229 | if (p >= buf + buflen) | ||
| 230 | continue; | ||
| 231 | user = p; | ||
| 232 | while (p < buf + buflen && *p != '\n' && *p != ' ' && | ||
| 233 | *p != '\t') { | ||
| 234 | if (!isprint((unsigned char)*p)) | ||
| 235 | goto bail; | ||
| 236 | p++; | ||
| 237 | } | ||
| 238 | } else | ||
| 239 | user = p; | ||
| 240 | *p = '\0'; | ||
| 241 | |||
| 242 | if (p == buf) | ||
| 243 | continue; | ||
| 244 | |||
| 245 | auser = *user ? user : luser; | ||
| 246 | ahost = buf; | ||
| 247 | |||
| 248 | if (strlen(ahost) >= MAXHOSTNAMELEN) | ||
| 249 | continue; | ||
| 250 | |||
| 251 | /* | ||
| 252 | * innetgr() must lookup a hostname (we do not attempt | ||
| 253 | * to change the semantics so that netgroups may have | ||
| 254 | * #.#.#.# addresses in the list.) | ||
| 255 | */ | ||
| 256 | if (ahost[0] == '+') | ||
| 257 | switch (ahost[1]) { | ||
| 258 | case '\0': | ||
| 259 | hostok = 1; | ||
| 260 | break; | ||
| 261 | case '@': | ||
| 262 | if (rhost == (char *)-1) | ||
| 263 | rhost = __gethostloop(raddr, salen); | ||
| 264 | hostok = 0; | ||
| 265 | if (rhost) | ||
| 266 | hostok = innetgr(&ahost[2], rhost, | ||
| 267 | NULL, domain); | ||
| 268 | break; | ||
| 269 | default: | ||
| 270 | hostok = __icheckhost(raddr, salen, &ahost[1]); | ||
| 271 | break; | ||
| 272 | } | ||
| 273 | else if (ahost[0] == '-') | ||
| 274 | switch (ahost[1]) { | ||
| 275 | case '\0': | ||
| 276 | hostok = -1; | ||
| 277 | break; | ||
| 278 | case '@': | ||
| 279 | if (rhost == (char *)-1) | ||
| 280 | rhost = __gethostloop(raddr, salen); | ||
| 281 | hostok = 0; | ||
| 282 | if (rhost) | ||
| 283 | hostok = -innetgr(&ahost[2], rhost, | ||
| 284 | NULL, domain); | ||
| 285 | break; | ||
| 286 | default: | ||
| 287 | hostok = -__icheckhost(raddr, salen, &ahost[1]); | ||
| 288 | break; | ||
| 289 | } | ||
| 290 | else | ||
| 291 | hostok = __icheckhost(raddr, salen, ahost); | ||
| 292 | |||
| 293 | |||
| 294 | if (auser[0] == '+') | ||
| 295 | switch (auser[1]) { | ||
| 296 | case '\0': | ||
| 297 | userok = 1; | ||
| 298 | break; | ||
| 299 | case '@': | ||
| 300 | userok = innetgr(&auser[2], NULL, ruser, | ||
| 301 | domain); | ||
| 302 | break; | ||
| 303 | default: | ||
| 304 | userok = strcmp(ruser, &auser[1]) ? 0 : 1; | ||
| 305 | break; | ||
| 306 | } | ||
| 307 | else if (auser[0] == '-') | ||
| 308 | switch (auser[1]) { | ||
| 309 | case '\0': | ||
| 310 | userok = -1; | ||
| 311 | break; | ||
| 312 | case '@': | ||
| 313 | userok = -innetgr(&auser[2], NULL, ruser, | ||
| 314 | domain); | ||
| 315 | break; | ||
| 316 | default: | ||
| 317 | userok = strcmp(ruser, &auser[1]) ? 0 : -1; | ||
| 318 | break; | ||
| 319 | } | ||
| 320 | else | ||
| 321 | userok = strcmp(ruser, auser) ? 0 : 1; | ||
| 322 | |||
| 323 | /* Check if one component did not match */ | ||
| 324 | if (hostok == 0 || userok == 0) | ||
| 325 | continue; | ||
| 326 | |||
| 327 | /* Check if we got a forbidden pair */ | ||
| 328 | if (userok <= -1 || hostok <= -1) | ||
| 329 | return (-1); | ||
| 330 | |||
| 331 | /* Check if we got a valid pair */ | ||
| 332 | if (hostok >= 1 && userok >= 1) | ||
| 333 | return (0); | ||
| 334 | } | ||
| 335 | bail: | ||
| 336 | return (-1); | ||
| 337 | } | ||
| 338 | |||
| 339 | /* | ||
| 340 | * Returns "true" if match, 0 if no match. If we do not find any | ||
| 341 | * semblance of an A->PTR->A loop, allow a simple #.#.#.# match to work. | ||
| 342 | */ | ||
| 343 | static int | ||
| 344 | __icheckhost(struct sockaddr *raddr, socklen_t salen, const char *lhost) | ||
| 345 | { | ||
| 346 | struct addrinfo hints, *res, *r; | ||
| 347 | char h1[NI_MAXHOST], h2[NI_MAXHOST]; | ||
| 348 | int error; | ||
| 349 | const int niflags = NI_NUMERICHOST; | ||
| 350 | |||
| 351 | h1[0] = '\0'; | ||
| 352 | if (getnameinfo(raddr, salen, h1, sizeof(h1), NULL, 0, | ||
| 353 | niflags) != 0) | ||
| 354 | return (0); | ||
| 355 | |||
| 356 | /* Resolve laddr into sockaddr */ | ||
| 357 | memset(&hints, 0, sizeof(hints)); | ||
| 358 | hints.ai_family = raddr->sa_family; | ||
| 359 | hints.ai_socktype = SOCK_DGRAM; /*dummy*/ | ||
| 360 | res = NULL; | ||
| 361 | error = getaddrinfo(lhost, "0", &hints, &res); | ||
| 362 | if (error) | ||
| 363 | return (0); | ||
| 364 | |||
| 365 | /* | ||
| 366 | * Try string comparisons between raddr and laddr. | ||
| 367 | */ | ||
| 368 | for (r = res; r; r = r->ai_next) { | ||
| 369 | h2[0] = '\0'; | ||
| 370 | if (getnameinfo(r->ai_addr, r->ai_addrlen, h2, sizeof(h2), | ||
| 371 | NULL, 0, niflags) != 0) | ||
| 372 | continue; | ||
| 373 | if (strcmp(h1, h2) == 0) { | ||
| 374 | freeaddrinfo(res); | ||
| 375 | return (1); | ||
| 376 | } | ||
| 377 | } | ||
| 378 | |||
| 379 | /* No match. */ | ||
| 380 | freeaddrinfo(res); | ||
| 381 | return (0); | ||
| 382 | } | ||
| 383 | |||
| 384 | /* | ||
| 385 | * Return the hostname associated with the supplied address. | ||
| 386 | * Do a reverse lookup as well for security. If a loop cannot | ||
| 387 | * be found, pack the result of inet_ntoa() into the string. | ||
| 388 | */ | ||
| 389 | static char * | ||
| 390 | __gethostloop(struct sockaddr *raddr, socklen_t salen) | ||
| 391 | { | ||
| 392 | static char remotehost[NI_MAXHOST]; | ||
| 393 | char h1[NI_MAXHOST], h2[NI_MAXHOST]; | ||
| 394 | struct addrinfo hints, *res, *r; | ||
| 395 | int error; | ||
| 396 | const int niflags = NI_NUMERICHOST; | ||
| 397 | |||
| 398 | h1[0] = remotehost[0] = '\0'; | ||
| 399 | if (getnameinfo(raddr, salen, remotehost, sizeof(remotehost), | ||
| 400 | NULL, 0, NI_NAMEREQD) != 0) | ||
| 401 | return (NULL); | ||
| 402 | if (getnameinfo(raddr, salen, h1, sizeof(h1), NULL, 0, | ||
| 403 | niflags) != 0) | ||
| 404 | return (NULL); | ||
| 405 | |||
| 406 | /* | ||
| 407 | * Look up the name and check that the supplied | ||
| 408 | * address is in the list | ||
| 409 | */ | ||
| 410 | memset(&hints, 0, sizeof(hints)); | ||
| 411 | hints.ai_family = raddr->sa_family; | ||
| 412 | hints.ai_socktype = SOCK_DGRAM; /*dummy*/ | ||
| 413 | hints.ai_flags = AI_CANONNAME; | ||
| 414 | res = NULL; | ||
| 415 | error = getaddrinfo(remotehost, "0", &hints, &res); | ||
| 416 | if (error) | ||
| 417 | return (NULL); | ||
| 418 | |||
| 419 | for (r = res; r; r = r->ai_next) { | ||
| 420 | h2[0] = '\0'; | ||
| 421 | if (getnameinfo(r->ai_addr, r->ai_addrlen, h2, sizeof(h2), | ||
| 422 | NULL, 0, niflags) != 0) | ||
| 423 | continue; | ||
| 424 | if (strcmp(h1, h2) == 0) { | ||
| 425 | freeaddrinfo(res); | ||
| 426 | return (remotehost); | ||
| 427 | } | ||
| 428 | } | ||
| 429 | |||
| 430 | /* | ||
| 431 | * either the DNS adminstrator has made a configuration | ||
| 432 | * mistake, or someone has attempted to spoof us | ||
| 433 | */ | ||
| 434 | syslog(LOG_NOTICE, "rcmd: address %s not listed for host %s", | ||
| 435 | h1, res->ai_canonname ? res->ai_canonname : remotehost); | ||
| 436 | freeaddrinfo(res); | ||
| 437 | return (NULL); | ||
| 438 | } | ||
diff --git a/src/lib/libc/net/send.c b/src/lib/libc/net/send.c index 88f3550ec6..1bfc80b87a 100644 --- a/src/lib/libc/net/send.c +++ b/src/lib/libc/net/send.c | |||
| @@ -1,5 +1,4 @@ | |||
| 1 | /* $NetBSD: send.c,v 1.6 1995/02/25 06:21:02 cgd Exp $ */ | 1 | /* $OpenBSD: send.c,v 1.5 2005/08/06 20:30:04 espie Exp $ */ |
| 2 | |||
| 3 | /* | 2 | /* |
| 4 | * Copyright (c) 1988, 1993 | 3 | * Copyright (c) 1988, 1993 |
| 5 | * The Regents of the University of California. All rights reserved. | 4 | * The Regents of the University of California. All rights reserved. |
| @@ -12,11 +11,7 @@ | |||
| 12 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
| 13 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the |
| 14 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. |
| 15 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. Neither the name of the University nor the names of its contributors |
| 16 | * must display the following acknowledgement: | ||
| 17 | * This product includes software developed by the University of | ||
| 18 | * California, Berkeley and its contributors. | ||
| 19 | * 4. Neither the name of the University nor the names of its contributors | ||
| 20 | * may be used to endorse or promote products derived from this software | 15 | * may be used to endorse or promote products derived from this software |
| 21 | * without specific prior written permission. | 16 | * without specific prior written permission. |
| 22 | * | 17 | * |
| @@ -33,24 +28,13 @@ | |||
| 33 | * SUCH DAMAGE. | 28 | * SUCH DAMAGE. |
| 34 | */ | 29 | */ |
| 35 | 30 | ||
| 36 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 37 | #if 0 | ||
| 38 | static char sccsid[] = "@(#)send.c 8.2 (Berkeley) 2/21/94"; | ||
| 39 | #else | ||
| 40 | static char rcsid[] = "$NetBSD: send.c,v 1.6 1995/02/25 06:21:02 cgd Exp $"; | ||
| 41 | #endif | ||
| 42 | #endif /* LIBC_SCCS and not lint */ | ||
| 43 | |||
| 44 | #include <sys/types.h> | 31 | #include <sys/types.h> |
| 45 | #include <sys/socket.h> | 32 | #include <sys/socket.h> |
| 46 | 33 | ||
| 47 | #include <stddef.h> | 34 | #include <stddef.h> |
| 48 | 35 | ||
| 49 | ssize_t | 36 | ssize_t |
| 50 | send(s, msg, len, flags) | 37 | send(int s, const void *msg, size_t len, int flags) |
| 51 | int s, flags; | ||
| 52 | size_t len; | ||
| 53 | const void *msg; | ||
| 54 | { | 38 | { |
| 55 | return (sendto(s, msg, len, flags, NULL, 0)); | 39 | return (sendto(s, msg, len, flags, NULL, 0)); |
| 56 | } | 40 | } |
diff --git a/src/lib/libc/net/vars6.c b/src/lib/libc/net/vars6.c new file mode 100644 index 0000000000..a22d49d047 --- /dev/null +++ b/src/lib/libc/net/vars6.c | |||
| @@ -0,0 +1,42 @@ | |||
| 1 | /* $OpenBSD: vars6.c,v 1.2 2003/05/10 10:56:47 jmc Exp $ */ | ||
| 2 | |||
| 3 | /* | ||
| 4 | * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. | ||
| 5 | * All rights reserved. | ||
| 6 | * | ||
| 7 | * Redistribution and use in source and binary forms, with or without | ||
| 8 | * modification, are permitted provided that the following conditions | ||
| 9 | * are met: | ||
| 10 | * 1. Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 13 | * notice, this list of conditions and the following disclaimer in the | ||
| 14 | * documentation and/or other materials provided with the distribution. | ||
| 15 | * 3. Neither the name of the project nor the names of its contributors | ||
| 16 | * may be used to endorse or promote products derived from this software | ||
| 17 | * without specific prior written permission. | ||
| 18 | * | ||
| 19 | * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND | ||
| 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE | ||
| 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 29 | * SUCH DAMAGE. | ||
| 30 | */ | ||
| 31 | |||
| 32 | #include <sys/types.h> | ||
| 33 | #include <netinet/in.h> | ||
| 34 | |||
| 35 | /* | ||
| 36 | * Definitions of some constant IPv6 addresses. | ||
| 37 | */ | ||
| 38 | const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT; | ||
| 39 | const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT; | ||
| 40 | const struct in6_addr in6addr_nodelocal_allnodes = IN6ADDR_NODELOCAL_ALLNODES_INIT; | ||
| 41 | const struct in6_addr in6addr_linklocal_allnodes = IN6ADDR_LINKLOCAL_ALLNODES_INIT; | ||
| 42 | |||
diff --git a/src/lib/libc/stdlib/Makefile.inc b/src/lib/libc/stdlib/Makefile.inc index 782a4ab022..953c53382f 100644 --- a/src/lib/libc/stdlib/Makefile.inc +++ b/src/lib/libc/stdlib/Makefile.inc | |||
| @@ -1,45 +1,63 @@ | |||
| 1 | # from: @(#)Makefile.inc 5.6 (Berkeley) 6/4/91 | 1 | # $OpenBSD: Makefile.inc,v 1.49 2014/03/18 22:36:29 miod Exp $ |
| 2 | # $Id: Makefile.inc,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $ | ||
| 3 | 2 | ||
| 4 | # stdlib sources | 3 | # stdlib sources |
| 5 | .PATH: ${.CURDIR}/arch/${MACHINE_ARCH}/stdlib ${.CURDIR}/stdlib | 4 | .PATH: ${LIBCSRCDIR}/arch/${MACHINE_CPU}/stdlib ${LIBCSRCDIR}/stdlib |
| 6 | 5 | ||
| 7 | SRCS+= a64l.c abort.c atexit.c atoi.c atof.c atol.c bsearch.c calloc.c \ | 6 | SRCS+= a64l.c abort.c atexit.c atoi.c atof.c atol.c atoll.c bsearch.c \ |
| 8 | exit.c getenv.c getopt.c heapsort.c l64a.c malloc.c merge.c \ | 7 | cfree.c exit.c ecvt.c gcvt.c getenv.c getopt_long.c \ |
| 9 | multibyte.c putenv.c qsort.c radixsort.c rand.c random.c realpath.c \ | 8 | getsubopt.c hcreate.c heapsort.c imaxabs.c imaxdiv.c l64a.c llabs.c \ |
| 10 | setenv.c strtod.c strtol.c strtoq.c strtoul.c strtouq.c system.c \ | 9 | lldiv.c lsearch.c malloc.c merge.c posix_pty.c qsort.c radixsort.c \ |
| 11 | _rand48.c drand48.c erand48.c jrand48.c lcong48.c lrand48.c \ | 10 | rand.c random.c realpath.c setenv.c strtoimax.c strtol.c \ |
| 12 | mrand48.c nrand48.c seed48.c srand48.c qabs.c qdiv.c | 11 | strtoll.c strtonum.c strtoul.c strtoull.c strtoumax.c system.c \ |
| 12 | tfind.c tsearch.c _rand48.c drand48.c erand48.c jrand48.c lcong48.c \ | ||
| 13 | lrand48.c mrand48.c nrand48.c seed48.c srand48.c qabs.c qdiv.c _Exit.c | ||
| 13 | 14 | ||
| 14 | .if (${MACHINE_ARCH} == "m68k") | 15 | .if (${MACHINE_CPU} == "i386") |
| 15 | SRCS+= abs.S div.c labs.c ldiv.c | ||
| 16 | .elif (${MACHINE_ARCH} == "i386") | ||
| 17 | SRCS+= abs.S div.S labs.S ldiv.S | 16 | SRCS+= abs.S div.S labs.S ldiv.S |
| 18 | .elif (${MACHINE_ARCH} == "ns32k") | 17 | .elif (${MACHINE_CPU} == "vax") |
| 19 | SRCS+= abs.S div.c labs.c ldiv.c | ||
| 20 | .elif (${MACHINE_ARCH} == "tahoe") | ||
| 21 | SRCS+= abs.S div.c labs.c ldiv.c | ||
| 22 | .elif (${MACHINE_ARCH} == "vax") | ||
| 23 | SRCS+= abs.c div.c labs.c ldiv.c | 18 | SRCS+= abs.c div.c labs.c ldiv.c |
| 24 | .elif (${MACHINE_ARCH} == "alpha") | 19 | .elif (${MACHINE_CPU} == "alpha") |
| 25 | # XXX should be .S's | 20 | # XXX should be .S's |
| 26 | SRCS+= abs.c div.c labs.c ldiv.c | 21 | SRCS+= abs.c div.c labs.c ldiv.c |
| 27 | .else | 22 | .else |
| 28 | SRCS+= abs.c div.c labs.c ldiv.c | 23 | SRCS+= abs.c div.c labs.c ldiv.c |
| 29 | .endif | 24 | .endif |
| 30 | 25 | ||
| 31 | MAN+= abort.3 abs.3 alloca.3 atexit.3 atof.3 atoi.3 atol.3 bsearch.3 \ | 26 | .if (${MACHINE_CPU} == "vax") |
| 32 | calloc.3 div.3 exit.3 free.3 getenv.3 getopt.3 labs.3 ldiv.3 \ | 27 | SRCS+= insque.S remque.S |
| 33 | malloc.3 memory.3 qabs.3 qdiv.3 qsort.3 radixsort.3 rand48.3 \ | 28 | .else |
| 34 | rand.3 random.3 realloc.3 realpath.3 strtod.3 strtol.3 strtoul.3 \ | 29 | SRCS+= insque.c remque.c |
| 35 | system.3 | 30 | .endif |
| 31 | |||
| 32 | MAN+= a64l.3 abort.3 abs.3 alloca.3 atexit.3 atof.3 atoi.3 atol.3 atoll.3 \ | ||
| 33 | bsearch.3 div.3 ecvt.3 exit.3 getenv.3 getopt.3 getopt_long.3 \ | ||
| 34 | getsubopt.3 hcreate.3 imaxabs.3 imaxdiv.3 insque.3 labs.3 ldiv.3 \ | ||
| 35 | lldiv.3 lsearch.3 malloc.3 posix_memalign.3 posix_openpt.3 ptsname.3 \ | ||
| 36 | qabs.3 qdiv.3 qsort.3 radixsort.3 rand48.3 rand.3 random.3 realpath.3 \ | ||
| 37 | strtod.3 strtonum.3 strtol.3 strtoul.3 system.3 tsearch.3 | ||
| 36 | 38 | ||
| 39 | MLINKS+=ecvt.3 fcvt.3 ecvt.3 gcvt.3 | ||
| 37 | MLINKS+=getenv.3 setenv.3 getenv.3 unsetenv.3 getenv.3 putenv.3 | 40 | MLINKS+=getenv.3 setenv.3 getenv.3 unsetenv.3 getenv.3 putenv.3 |
| 41 | MLINKS+=getopt_long.3 getopt_long_only.3 | ||
| 42 | MLINKS+=hcreate.3 hdestroy.3 hcreate.3 hsearch.3 | ||
| 43 | MLINKS+=insque.3 remque.3 | ||
| 44 | MLINKS+=labs.3 llabs.3 | ||
| 45 | MLINKS+=lsearch.3 lfind.3 | ||
| 46 | MLINKS+=malloc.3 free.3 malloc.3 realloc.3 malloc.3 calloc.3 | ||
| 47 | MLINKS+=malloc.3 cfree.3 malloc.3 malloc.conf.5 | ||
| 38 | MLINKS+=qsort.3 heapsort.3 qsort.3 mergesort.3 | 48 | MLINKS+=qsort.3 heapsort.3 qsort.3 mergesort.3 |
| 39 | MLINKS+=rand.3 srand.3 | 49 | MLINKS+=radixsort.3 sradixsort.3 |
| 40 | MLINKS+=strtol.3 strtoq.3 | 50 | MLINKS+=rand.3 srand.3 rand.3 rand_r.3 |
| 41 | MLINKS+=strtoul.3 strtouq.3 | 51 | MLINKS+=random.3 initstate.3 random.3 setstate.3 |
| 42 | MLINKS+=random.3 initstate.3 random.3 setstate.3 random.3 srandom.3 | 52 | MLINKS+=random.3 srandom.3 random.3 srandomdev.3 |
| 43 | MLINKS+=rand48.3 drand48.3 rand48.3 erand48.3 rand48.3 lrand48.3 | 53 | MLINKS+=rand48.3 drand48.3 rand48.3 erand48.3 rand48.3 lrand48.3 |
| 44 | MLINKS+=rand48.3 mrand48.3 rand48.3 nrand48.3 rand48.3 jrand48.3 | 54 | MLINKS+=rand48.3 mrand48.3 rand48.3 nrand48.3 rand48.3 jrand48.3 |
| 45 | MLINKS+=rand48.3 srand48.3 rand48.3 seed48.3 rand48.3 lcong48.3 | 55 | MLINKS+=rand48.3 srand48.3 rand48.3 seed48.3 rand48.3 lcong48.3 |
| 56 | MLINKS+=ptsname.3 grantpt.3 ptsname.3 unlockpt.3 | ||
| 57 | MLINKS+=strtod.3 strtof.3 strtod.3 strtold.3 | ||
| 58 | MLINKS+=strtol.3 strtoll.3 strtol.3 strtoq.3 strtol.3 strtoimax.3 | ||
| 59 | MLINKS+=strtoul.3 strtoull.3 strtoul.3 strtouq.3 strtoul.3 strtoumax.3 | ||
| 60 | MLINKS+=tsearch.3 tfind.3 | ||
| 61 | MLINKS+=tsearch.3 tdelete.3 | ||
| 62 | MLINKS+=tsearch.3 twalk.3 | ||
| 63 | MLINKS+=a64l.3 l64a.3 | ||
diff --git a/src/lib/libc/stdlib/_Exit.c b/src/lib/libc/stdlib/_Exit.c new file mode 100644 index 0000000000..ccf64c2e87 --- /dev/null +++ b/src/lib/libc/stdlib/_Exit.c | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | /* $OpenBSD: _Exit.c,v 1.3 2013/04/03 03:39:29 guenther Exp $ */ | ||
| 2 | |||
| 3 | /* | ||
| 4 | * Placed in the public domain by Todd C. Miller on January 21, 2004. | ||
| 5 | */ | ||
| 6 | |||
| 7 | #include <stdlib.h> | ||
| 8 | #include <unistd.h> | ||
| 9 | |||
| 10 | /* | ||
| 11 | * _Exit() is the ISO/ANSI C99 equivalent of the POSIX _exit() function. | ||
| 12 | * No atexit() handlers are called and no signal handlers are run. | ||
| 13 | * Whether or not stdio buffers are flushed or temporary files are removed | ||
| 14 | * is implementation-dependent in C99. Indeed, POSIX specifies that | ||
| 15 | * _Exit() must *not* flush stdio buffers or remove temporary files, but | ||
| 16 | * rather must behave exactly like _exit() | ||
| 17 | */ | ||
| 18 | void | ||
| 19 | _Exit(int status) | ||
| 20 | { | ||
| 21 | _exit(status); | ||
| 22 | } | ||
diff --git a/src/lib/libc/stdlib/_rand48.c b/src/lib/libc/stdlib/_rand48.c index 83ade4645a..7c950f7cee 100644 --- a/src/lib/libc/stdlib/_rand48.c +++ b/src/lib/libc/stdlib/_rand48.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: _rand48.c,v 1.3 2005/08/08 08:05:36 espie Exp $ */ | ||
| 1 | /* | 2 | /* |
| 2 | * Copyright (c) 1993 Martin Birgmeier | 3 | * Copyright (c) 1993 Martin Birgmeier |
| 3 | * All rights reserved. | 4 | * All rights reserved. |
diff --git a/src/lib/libc/stdlib/a64l.3 b/src/lib/libc/stdlib/a64l.3 new file mode 100644 index 0000000000..11a74604ac --- /dev/null +++ b/src/lib/libc/stdlib/a64l.3 | |||
| @@ -0,0 +1,133 @@ | |||
| 1 | .\" $OpenBSD: a64l.3,v 1.12 2013/06/05 03:39:23 tedu Exp $ | ||
| 2 | .\" | ||
| 3 | .\" Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com> | ||
| 4 | .\" | ||
| 5 | .\" Permission to use, copy, modify, and distribute this software for any | ||
| 6 | .\" purpose with or without fee is hereby granted, provided that the above | ||
| 7 | .\" copyright notice and this permission notice appear in all copies. | ||
| 8 | .\" | ||
| 9 | .\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 10 | .\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 11 | .\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 12 | .\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 13 | .\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 14 | .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 15 | .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 16 | .\" | ||
| 17 | .Dd $Mdocdate: June 5 2013 $ | ||
| 18 | .Dt A64L 3 | ||
| 19 | .Os | ||
| 20 | .Sh NAME | ||
| 21 | .Nm a64l , | ||
| 22 | .Nm l64a | ||
| 23 | .Nd convert between 32-bit integer and radix-64 ASCII string | ||
| 24 | .Sh SYNOPSIS | ||
| 25 | .In stdlib.h | ||
| 26 | .Ft long | ||
| 27 | .Fn a64l "const char *s" | ||
| 28 | .Ft char * | ||
| 29 | .Fn l64a "long l" | ||
| 30 | .Sh DESCRIPTION | ||
| 31 | The | ||
| 32 | .Fn a64l | ||
| 33 | and | ||
| 34 | .Fn l64a | ||
| 35 | functions are used to maintain numbers stored in radix-64 | ||
| 36 | .Tn ASCII | ||
| 37 | characters. | ||
| 38 | This is a notation by which 32-bit integers | ||
| 39 | can be represented by up to six characters; each character represents a | ||
| 40 | .Dq digit | ||
| 41 | in a radix-64 notation. | ||
| 42 | .Pp | ||
| 43 | The characters used to represent digits are | ||
| 44 | .Ql \&. | ||
| 45 | for 0, | ||
| 46 | .Ql / | ||
| 47 | for 1, | ||
| 48 | .Ql 0 | ||
| 49 | through | ||
| 50 | .Ql 9 | ||
| 51 | for 2-11, | ||
| 52 | .Ql A | ||
| 53 | through | ||
| 54 | .Ql Z | ||
| 55 | for 12-37, and | ||
| 56 | .Ql a | ||
| 57 | through | ||
| 58 | .Ql z | ||
| 59 | for 38-63. | ||
| 60 | .Pp | ||
| 61 | The | ||
| 62 | .Fn a64l | ||
| 63 | function takes a pointer to a NUL-terminated radix-64 representation | ||
| 64 | and returns a corresponding 32-bit value. | ||
| 65 | If the string pointed to by | ||
| 66 | .Fa s | ||
| 67 | contains more than six characters, | ||
| 68 | .Fn a64l | ||
| 69 | will use the first six. | ||
| 70 | .Fn a64l | ||
| 71 | scans the character string from left to right, decoding | ||
| 72 | each character as a 6-bit radix-64 number. | ||
| 73 | If a long integer is | ||
| 74 | larger than 32 bits, the return value will be sign-extended. | ||
| 75 | .Pp | ||
| 76 | .Fn l64a | ||
| 77 | takes a long integer argument | ||
| 78 | .Fa l | ||
| 79 | and returns a pointer to the corresponding radix-64 representation. | ||
| 80 | .Sh RETURN VALUES | ||
| 81 | On success, | ||
| 82 | .Fn a64l | ||
| 83 | returns a 32-bit representation of | ||
| 84 | .Fa s . | ||
| 85 | If | ||
| 86 | .Fa s | ||
| 87 | is a null pointer or if it contains digits other than those described above, | ||
| 88 | .Fn a64l | ||
| 89 | returns \-1 and sets the global variable | ||
| 90 | .Va errno | ||
| 91 | to | ||
| 92 | .Er EINVAL . | ||
| 93 | .Pp | ||
| 94 | On success, | ||
| 95 | .Fn l64a | ||
| 96 | returns a pointer to a string containing the radix-64 representation of | ||
| 97 | .Fa l . | ||
| 98 | If | ||
| 99 | .Fa l | ||
| 100 | is 0, | ||
| 101 | .Fn l64a | ||
| 102 | returns a pointer to the empty string. | ||
| 103 | If | ||
| 104 | .Fa l | ||
| 105 | is negative, | ||
| 106 | .Fn l64a | ||
| 107 | returns a null pointer and sets the global variable | ||
| 108 | .Va errno | ||
| 109 | to | ||
| 110 | .Er EINVAL . | ||
| 111 | .Sh STANDARDS | ||
| 112 | The | ||
| 113 | .Fn a64l | ||
| 114 | and | ||
| 115 | .Fn l64a | ||
| 116 | functions conform to | ||
| 117 | .St -xpg4.2 . | ||
| 118 | .Sh CAVEATS | ||
| 119 | The value returned by | ||
| 120 | .Fn l64a | ||
| 121 | is a pointer into a static buffer, the contents of which | ||
| 122 | will be overwritten by subsequent calls. | ||
| 123 | .Pp | ||
| 124 | The value returned by | ||
| 125 | .Fn a64l | ||
| 126 | may be incorrect if the value is too large; for that reason, only strings | ||
| 127 | that resulted from a call to | ||
| 128 | .Fn l64a | ||
| 129 | should be used to call | ||
| 130 | .Fn a64l . | ||
| 131 | .Pp | ||
| 132 | If a long integer is larger than 32 bits, only the low-order | ||
| 133 | 32 bits are used. | ||
diff --git a/src/lib/libc/stdlib/a64l.c b/src/lib/libc/stdlib/a64l.c index 03fc77e034..5312929c6f 100644 --- a/src/lib/libc/stdlib/a64l.c +++ b/src/lib/libc/stdlib/a64l.c | |||
| @@ -1,34 +1,42 @@ | |||
| 1 | /* $OpenBSD: a64l.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */ | ||
| 1 | /* | 2 | /* |
| 2 | * Written by J.T. Conklin <jtc@netbsd.org>. | 3 | * Written by J.T. Conklin <jtc@netbsd.org>. |
| 3 | * Public domain. | 4 | * Public domain. |
| 4 | */ | 5 | */ |
| 5 | 6 | ||
| 6 | #if defined(LIBC_SCCS) && !defined(lint) | 7 | #include <errno.h> |
| 7 | static char *rcsid = "$NetBSD: a64l.c,v 1.3 1995/05/11 23:04:47 jtc Exp $"; | 8 | #include <stdlib.h> |
| 8 | #endif | ||
| 9 | 9 | ||
| 10 | long | 10 | long |
| 11 | a64l(s) | 11 | a64l(const char *s) |
| 12 | const char *s; | ||
| 13 | { | 12 | { |
| 14 | long value, digit, shift; | 13 | long value, digit, shift; |
| 15 | int i; | 14 | int i; |
| 16 | 15 | ||
| 16 | if (s == NULL) { | ||
| 17 | errno = EINVAL; | ||
| 18 | return(-1L); | ||
| 19 | } | ||
| 20 | |||
| 17 | value = 0; | 21 | value = 0; |
| 18 | shift = 0; | 22 | shift = 0; |
| 19 | for (i = 0; *s && i < 6; i++, s++) { | 23 | for (i = 0; *s && i < 6; i++, s++) { |
| 20 | if (*s <= '/') | 24 | if (*s >= '.' && *s <= '/') |
| 21 | digit = *s - '.'; | 25 | digit = *s - '.'; |
| 22 | else if (*s <= '9') | 26 | else if (*s >= '0' && *s <= '9') |
| 23 | digit = *s - '0' + 2; | 27 | digit = *s - '0' + 2; |
| 24 | else if (*s <= 'Z') | 28 | else if (*s >= 'A' && *s <= 'Z') |
| 25 | digit = *s - 'A' + 12; | 29 | digit = *s - 'A' + 12; |
| 26 | else | 30 | else if (*s >= 'a' && *s <= 'z') |
| 27 | digit = *s - 'a' + 38; | 31 | digit = *s - 'a' + 38; |
| 32 | else { | ||
| 33 | errno = EINVAL; | ||
| 34 | return(-1L); | ||
| 35 | } | ||
| 28 | 36 | ||
| 29 | value |= digit << shift; | 37 | value |= digit << shift; |
| 30 | shift += 6; | 38 | shift += 6; |
| 31 | } | 39 | } |
| 32 | 40 | ||
| 33 | return (long) value; | 41 | return(value); |
| 34 | } | 42 | } |
diff --git a/src/lib/libc/stdlib/abort.3 b/src/lib/libc/stdlib/abort.3 index ab57327585..322d629930 100644 --- a/src/lib/libc/stdlib/abort.3 +++ b/src/lib/libc/stdlib/abort.3 | |||
| @@ -13,11 +13,7 @@ | |||
| 13 | .\" 2. Redistributions in binary form must reproduce the above copyright | 13 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 14 | .\" notice, this list of conditions and the following disclaimer in the | 14 | .\" notice, this list of conditions and the following disclaimer in the |
| 15 | .\" documentation and/or other materials provided with the distribution. | 15 | .\" documentation and/or other materials provided with the distribution. |
| 16 | .\" 3. All advertising materials mentioning features or use of this software | 16 | .\" 3. Neither the name of the University nor the names of its contributors |
| 17 | .\" must display the following acknowledgement: | ||
| 18 | .\" This product includes software developed by the University of | ||
| 19 | .\" California, Berkeley and its contributors. | ||
| 20 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 21 | .\" may be used to endorse or promote products derived from this software | 17 | .\" may be used to endorse or promote products derived from this software |
| 22 | .\" without specific prior written permission. | 18 | .\" without specific prior written permission. |
| 23 | .\" | 19 | .\" |
| @@ -33,39 +29,40 @@ | |||
| 33 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 29 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 34 | .\" SUCH DAMAGE. | 30 | .\" SUCH DAMAGE. |
| 35 | .\" | 31 | .\" |
| 36 | .\" from: @(#)abort.3 6.7 (Berkeley) 6/29/91 | 32 | .\" $OpenBSD: abort.3,v 1.10 2013/07/17 05:42:11 schwarze Exp $ |
| 37 | .\" $Id: abort.3,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $ | ||
| 38 | .\" | 33 | .\" |
| 39 | .Dd June 29, 1991 | 34 | .Dd $Mdocdate: July 17 2013 $ |
| 40 | .Dt ABORT 3 | 35 | .Dt ABORT 3 |
| 41 | .Os | 36 | .Os |
| 42 | .Sh NAME | 37 | .Sh NAME |
| 43 | .Nm abort | 38 | .Nm abort |
| 44 | .Nd cause abnormal program termination | 39 | .Nd cause abnormal program termination |
| 45 | .Sh SYNOPSIS | 40 | .Sh SYNOPSIS |
| 46 | .Fd #include <stdlib.h> | 41 | .In stdlib.h |
| 47 | .Ft void | 42 | .Ft void |
| 48 | .Fn abort void | 43 | .Fn abort void |
| 49 | .Sh DESCRIPTION | 44 | .Sh DESCRIPTION |
| 50 | The | 45 | The |
| 51 | .Fn abort | 46 | .Fn abort |
| 52 | function causes abnormal program termination to occur, unless the | 47 | function causes abnormal program termination to occur, unless the signal |
| 53 | signal | ||
| 54 | .Dv SIGABRT | 48 | .Dv SIGABRT |
| 55 | is being caught and the signal handler does not return. | 49 | is being caught and the signal handler does not return. |
| 56 | .Pp | 50 | .Pp |
| 57 | No open streams are closed or flushed. | 51 | Any open streams are flushed and closed. |
| 58 | .Sh RETURN VALUES | 52 | .Sh RETURN VALUES |
| 59 | The | 53 | The |
| 60 | .Nm abort | 54 | .Fn abort |
| 61 | function | 55 | function never returns. |
| 62 | never returns. | ||
| 63 | .Sh SEE ALSO | 56 | .Sh SEE ALSO |
| 64 | .Xr sigaction 2 , | 57 | .Xr sigaction 2 , |
| 65 | .Xr exit 2 | 58 | .Xr exit 3 |
| 66 | .Sh STANDARDS | 59 | .Sh STANDARDS |
| 67 | The | 60 | The |
| 68 | .Fn abort | 61 | .Fn abort |
| 69 | function | 62 | function conforms to |
| 70 | conforms to | 63 | .St -p1003.1-90 . |
| 71 | .St -ansiC . | 64 | .Sh HISTORY |
| 65 | The | ||
| 66 | .Fn abort | ||
| 67 | function first appeared in | ||
| 68 | .At v5 . | ||
diff --git a/src/lib/libc/stdlib/abort.c b/src/lib/libc/stdlib/abort.c index c298e016b4..4c8dc70a1d 100644 --- a/src/lib/libc/stdlib/abort.c +++ b/src/lib/libc/stdlib/abort.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: abort.c,v 1.16 2012/11/10 03:46:11 guenther Exp $ */ | ||
| 1 | /* | 2 | /* |
| 2 | * Copyright (c) 1985 Regents of the University of California. | 3 | * Copyright (c) 1985 Regents of the University of California. |
| 3 | * All rights reserved. | 4 | * All rights reserved. |
| @@ -10,11 +11,7 @@ | |||
| 10 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the |
| 12 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. Neither the name of the University nor the names of its contributors |
| 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 | 15 | * may be used to endorse or promote products derived from this software |
| 19 | * without specific prior written permission. | 16 | * without specific prior written permission. |
| 20 | * | 17 | * |
| @@ -31,35 +28,53 @@ | |||
| 31 | * SUCH DAMAGE. | 28 | * SUCH DAMAGE. |
| 32 | */ | 29 | */ |
| 33 | 30 | ||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 35 | /*static char *sccsid = "from: @(#)abort.c 5.11 (Berkeley) 2/23/91";*/ | ||
| 36 | static char *rcsid = "$Id: abort.c,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $"; | ||
| 37 | #endif /* LIBC_SCCS and not lint */ | ||
| 38 | |||
| 39 | #include <signal.h> | 31 | #include <signal.h> |
| 40 | #include <stdlib.h> | 32 | #include <stdlib.h> |
| 41 | #include <unistd.h> | 33 | #include <unistd.h> |
| 34 | #include "thread_private.h" | ||
| 35 | #include "atexit.h" | ||
| 36 | |||
| 37 | int _thread_sys_sigprocmask(int, const sigset_t *, sigset_t *); | ||
| 42 | 38 | ||
| 43 | void | 39 | void |
| 44 | abort() | 40 | abort(void) |
| 45 | { | 41 | { |
| 42 | struct atexit *p = __atexit; | ||
| 43 | static int cleanup_called = 0; | ||
| 46 | sigset_t mask; | 44 | sigset_t mask; |
| 47 | 45 | ||
| 46 | |||
| 48 | sigfillset(&mask); | 47 | sigfillset(&mask); |
| 49 | /* | 48 | /* |
| 50 | * don't block SIGABRT to give any handler a chance; we ignore | 49 | * don't block SIGABRT to give any handler a chance; we ignore |
| 51 | * any errors -- X311J doesn't allow abort to return anyway. | 50 | * any errors -- X311J doesn't allow abort to return anyway. |
| 52 | */ | 51 | */ |
| 53 | sigdelset(&mask, SIGABRT); | 52 | sigdelset(&mask, SIGABRT); |
| 54 | (void)sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL); | 53 | (void)_thread_sys_sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL); |
| 55 | (void)kill(getpid(), SIGABRT); | 54 | |
| 55 | /* | ||
| 56 | * POSIX requires we flush stdio buffers on abort | ||
| 57 | */ | ||
| 58 | if (cleanup_called == 0) { | ||
| 59 | /* the cleanup routine lives in fns[0] on the last page */ | ||
| 60 | while (p != NULL && p->next != NULL) | ||
| 61 | p = p->next; | ||
| 62 | /* the check for fn_dso == NULL is mostly paranoia */ | ||
| 63 | if (p != NULL && p->fns[0].fn_dso == NULL && | ||
| 64 | p->fns[0].fn_ptr.std_func != NULL) { | ||
| 65 | cleanup_called = 1; | ||
| 66 | (*p->fns[0].fn_ptr.std_func)(); | ||
| 67 | } | ||
| 68 | } | ||
| 69 | |||
| 70 | (void)raise(SIGABRT); | ||
| 56 | 71 | ||
| 57 | /* | 72 | /* |
| 58 | * if SIGABRT ignored, or caught and the handler returns, do | 73 | * if SIGABRT ignored, or caught and the handler returns, do |
| 59 | * it again, only harder. | 74 | * it again, only harder. |
| 60 | */ | 75 | */ |
| 61 | (void)signal(SIGABRT, SIG_DFL); | 76 | (void)signal(SIGABRT, SIG_DFL); |
| 62 | (void)sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL); | 77 | (void)_thread_sys_sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL); |
| 63 | (void)kill(getpid(), SIGABRT); | 78 | (void)raise(SIGABRT); |
| 64 | exit(1); | 79 | _exit(1); |
| 65 | } | 80 | } |
diff --git a/src/lib/libc/stdlib/abs.3 b/src/lib/libc/stdlib/abs.3 index 4748d89e77..420bdf6fdf 100644 --- a/src/lib/libc/stdlib/abs.3 +++ b/src/lib/libc/stdlib/abs.3 | |||
| @@ -13,11 +13,7 @@ | |||
| 13 | .\" 2. Redistributions in binary form must reproduce the above copyright | 13 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 14 | .\" notice, this list of conditions and the following disclaimer in the | 14 | .\" notice, this list of conditions and the following disclaimer in the |
| 15 | .\" documentation and/or other materials provided with the distribution. | 15 | .\" documentation and/or other materials provided with the distribution. |
| 16 | .\" 3. All advertising materials mentioning features or use of this software | 16 | .\" 3. Neither the name of the University nor the names of its contributors |
| 17 | .\" must display the following acknowledgement: | ||
| 18 | .\" This product includes software developed by the University of | ||
| 19 | .\" California, Berkeley and its contributors. | ||
| 20 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 21 | .\" may be used to endorse or promote products derived from this software | 17 | .\" may be used to endorse or promote products derived from this software |
| 22 | .\" without specific prior written permission. | 18 | .\" without specific prior written permission. |
| 23 | .\" | 19 | .\" |
| @@ -33,42 +29,42 @@ | |||
| 33 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 29 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 34 | .\" SUCH DAMAGE. | 30 | .\" SUCH DAMAGE. |
| 35 | .\" | 31 | .\" |
| 36 | .\" from: @(#)abs.3 6.4 (Berkeley) 6/29/91 | 32 | .\" $OpenBSD: abs.3,v 1.11 2013/07/17 05:42:11 schwarze Exp $ |
| 37 | .\" $Id: abs.3,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $ | ||
| 38 | .\" | 33 | .\" |
| 39 | .Dd June 29, 1991 | 34 | .Dd $Mdocdate: July 17 2013 $ |
| 40 | .Dt ABS 3 | 35 | .Dt ABS 3 |
| 41 | .Os | 36 | .Os |
| 42 | .Sh NAME | 37 | .Sh NAME |
| 43 | .Nm abs | 38 | .Nm abs |
| 44 | .Nd integer absolute value function | 39 | .Nd integer absolute value function |
| 45 | .Sh SYNOPSIS | 40 | .Sh SYNOPSIS |
| 46 | .Fd #include <stdlib.h> | 41 | .In stdlib.h |
| 47 | .Ft int | 42 | .Ft int |
| 48 | .Fn abs "int j" | 43 | .Fn abs "int j" |
| 49 | .Sh DESCRIPTION | 44 | .Sh DESCRIPTION |
| 50 | The | 45 | The |
| 51 | .Fn abs | 46 | .Fn abs |
| 52 | function | 47 | function computes the absolute value of the integer |
| 53 | computes | 48 | .Fa j . |
| 54 | the absolute value of the integer | ||
| 55 | .Ar j . | ||
| 56 | .Sh RETURN VALUES | 49 | .Sh RETURN VALUES |
| 57 | The | 50 | The |
| 58 | .Fn abs | 51 | .Fn abs |
| 59 | function | 52 | function returns the absolute value. |
| 60 | returns | ||
| 61 | the absolute value. | ||
| 62 | .Sh SEE ALSO | 53 | .Sh SEE ALSO |
| 63 | .Xr floor 3 , | ||
| 64 | .Xr labs 3 , | ||
| 65 | .Xr cabs 3 , | 54 | .Xr cabs 3 , |
| 55 | .Xr floor 3 , | ||
| 66 | .Xr hypot 3 , | 56 | .Xr hypot 3 , |
| 67 | .Xr math 3 | 57 | .Xr imaxabs 3 , |
| 58 | .Xr labs 3 | ||
| 68 | .Sh STANDARDS | 59 | .Sh STANDARDS |
| 69 | The | 60 | The |
| 70 | .Fn abs | 61 | .Fn abs |
| 71 | function conforms to | 62 | function conforms to |
| 72 | .St -ansiC . | 63 | .St -ansiC . |
| 64 | .Sh HISTORY | ||
| 65 | The | ||
| 66 | .Fn abs | ||
| 67 | function first appeared in | ||
| 68 | .At v6 . | ||
| 73 | .Sh BUGS | 69 | .Sh BUGS |
| 74 | The absolute value of the most negative integer remains negative. | 70 | The 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 index 64468e0224..5d2fbae69f 100644 --- a/src/lib/libc/stdlib/abs.c +++ b/src/lib/libc/stdlib/abs.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: abs.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */ | ||
| 1 | /*- | 2 | /*- |
| 2 | * Copyright (c) 1990 The Regents of the University of California. | 3 | * Copyright (c) 1990 The Regents of the University of California. |
| 3 | * All rights reserved. | 4 | * All rights reserved. |
| @@ -10,11 +11,7 @@ | |||
| 10 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the |
| 12 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. Neither the name of the University nor the names of its contributors |
| 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 | 15 | * may be used to endorse or promote products derived from this software |
| 19 | * without specific prior written permission. | 16 | * without specific prior written permission. |
| 20 | * | 17 | * |
| @@ -31,16 +28,10 @@ | |||
| 31 | * SUCH DAMAGE. | 28 | * SUCH DAMAGE. |
| 32 | */ | 29 | */ |
| 33 | 30 | ||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 35 | /*static char *sccsid = "from: @(#)abs.c 5.2 (Berkeley) 5/17/90";*/ | ||
| 36 | static char *rcsid = "$Id: abs.c,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $"; | ||
| 37 | #endif /* LIBC_SCCS and not lint */ | ||
| 38 | |||
| 39 | #include <stdlib.h> | 31 | #include <stdlib.h> |
| 40 | 32 | ||
| 41 | int | 33 | int |
| 42 | abs(j) | 34 | abs(int j) |
| 43 | int j; | ||
| 44 | { | 35 | { |
| 45 | return(j < 0 ? -j : j); | 36 | return(j < 0 ? -j : j); |
| 46 | } | 37 | } |
diff --git a/src/lib/libc/stdlib/alloca.3 b/src/lib/libc/stdlib/alloca.3 index dcb97ab11c..47e9b97143 100644 --- a/src/lib/libc/stdlib/alloca.3 +++ b/src/lib/libc/stdlib/alloca.3 | |||
| @@ -9,11 +9,7 @@ | |||
| 9 | .\" 2. Redistributions in binary form must reproduce the above copyright | 9 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 10 | .\" notice, this list of conditions and the following disclaimer in the | 10 | .\" notice, this list of conditions and the following disclaimer in the |
| 11 | .\" documentation and/or other materials provided with the distribution. | 11 | .\" documentation and/or other materials provided with the distribution. |
| 12 | .\" 3. All advertising materials mentioning features or use of this software | 12 | .\" 3. Neither the name of the University nor the names of its contributors |
| 13 | .\" must display the following acknowledgement: | ||
| 14 | .\" This product includes software developed by the University of | ||
| 15 | .\" California, Berkeley and its contributors. | ||
| 16 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 17 | .\" may be used to endorse or promote products derived from this software | 13 | .\" may be used to endorse or promote products derived from this software |
| 18 | .\" without specific prior written permission. | 14 | .\" without specific prior written permission. |
| 19 | .\" | 15 | .\" |
| @@ -29,51 +25,52 @@ | |||
| 29 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 25 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 30 | .\" SUCH DAMAGE. | 26 | .\" SUCH DAMAGE. |
| 31 | .\" | 27 | .\" |
| 32 | .\" from: @(#)alloca.3 5.1 (Berkeley) 5/2/91 | 28 | .\" $OpenBSD: alloca.3,v 1.13 2013/06/05 03:39:23 tedu Exp $ |
| 33 | .\" $Id: alloca.3,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $ | ||
| 34 | .\" | 29 | .\" |
| 35 | .Dd May 2, 1991 | 30 | .Dd $Mdocdate: June 5 2013 $ |
| 36 | .Dt ALLOCA 3 | 31 | .Dt ALLOCA 3 |
| 37 | .Os BSD 4 | 32 | .Os |
| 38 | .Sh NAME | 33 | .Sh NAME |
| 39 | .Nm alloca | 34 | .Nm alloca |
| 40 | .Nd memory allocator | 35 | .Nd memory allocator |
| 41 | .Sh SYNOPSIS | 36 | .Sh SYNOPSIS |
| 42 | .Fd #include <stdlib.h> | 37 | .In stdlib.h |
| 43 | .Ft void * | 38 | .Ft void * |
| 44 | .Fn alloca "size_t size" | 39 | .Fn alloca "size_t size" |
| 45 | .Sh DESCRIPTION | 40 | .Sh DESCRIPTION |
| 46 | The | 41 | The |
| 47 | .Fn alloca | 42 | .Fn alloca |
| 48 | function | 43 | function allocates |
| 49 | allocates | ||
| 50 | .Fa size | 44 | .Fa size |
| 51 | bytes of space in the stack frame of the caller. | 45 | bytes of space in the stack frame of the caller. |
| 52 | This temporary space is automatically freed on | 46 | This temporary space is automatically freed on return. |
| 53 | return. | ||
| 54 | .Sh RETURN VALUES | 47 | .Sh RETURN VALUES |
| 55 | The | 48 | The |
| 56 | .Fn alloca | 49 | .Fn alloca |
| 57 | function returns a pointer to the beginning of the allocated space. | 50 | function returns a pointer to the beginning of the allocated space. |
| 58 | If the allocation failed, a | ||
| 59 | .Dv NULL | ||
| 60 | pointer is returned. | ||
| 61 | .Sh SEE ALSO | 51 | .Sh SEE ALSO |
| 52 | .Xr pagesize 1 , | ||
| 62 | .Xr brk 2 , | 53 | .Xr brk 2 , |
| 63 | .Xr pagesize 2 | ||
| 64 | .Xr calloc 3 , | 54 | .Xr calloc 3 , |
| 65 | .Xr malloc 3 , | 55 | .Xr malloc 3 , |
| 66 | .Xr realloc 3 , | 56 | .Xr realloc 3 |
| 67 | .Sh BUGS | ||
| 68 | The | ||
| 69 | .Fn alloca | ||
| 70 | function | ||
| 71 | is machine dependent; its use is discouraged. | ||
| 72 | .\" .Sh HISTORY | 57 | .\" .Sh HISTORY |
| 73 | .\" The | 58 | .\" The |
| 74 | .\" .Fn alloca | 59 | .\" .Fn alloca |
| 75 | .\" function appeared in | 60 | .\" function appeared in |
| 76 | .\" .Bx ?? . | 61 | .\" .Bx ?? . |
| 77 | .\" The function appeared in 32v, pwb and pwb.2 and in 3bsd 4bsd | 62 | .\" The function appeared in 32v, pwb and pwb.2 and in 3bsd 4bsd |
| 78 | .\" The first man page (or link to a man page that I can find at the | 63 | .\" The first man page (or link to a man page that I can find at the |
| 79 | .\" moment is 4.3... | 64 | .\" moment is 4.3... |
| 65 | .Sh BUGS | ||
| 66 | The | ||
| 67 | .Fn alloca | ||
| 68 | function is slightly unsafe because it cannot ensure that the pointer | ||
| 69 | returned points to a valid and usable block of memory. | ||
| 70 | The allocation made may exceed the bounds of the stack, or even go | ||
| 71 | further into other objects in memory, and | ||
| 72 | .Fn alloca | ||
| 73 | cannot determine such an error. | ||
| 74 | Avoid | ||
| 75 | .Fn alloca | ||
| 76 | with large unbounded allocations. | ||
diff --git a/src/lib/libc/stdlib/atexit.3 b/src/lib/libc/stdlib/atexit.3 index 07de054d3c..8e3ac3e60f 100644 --- a/src/lib/libc/stdlib/atexit.3 +++ b/src/lib/libc/stdlib/atexit.3 | |||
| @@ -13,11 +13,7 @@ | |||
| 13 | .\" 2. Redistributions in binary form must reproduce the above copyright | 13 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 14 | .\" notice, this list of conditions and the following disclaimer in the | 14 | .\" notice, this list of conditions and the following disclaimer in the |
| 15 | .\" documentation and/or other materials provided with the distribution. | 15 | .\" documentation and/or other materials provided with the distribution. |
| 16 | .\" 3. All advertising materials mentioning features or use of this software | 16 | .\" 3. Neither the name of the University nor the names of its contributors |
| 17 | .\" must display the following acknowledgement: | ||
| 18 | .\" This product includes software developed by the University of | ||
| 19 | .\" California, Berkeley and its contributors. | ||
| 20 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 21 | .\" may be used to endorse or promote products derived from this software | 17 | .\" may be used to endorse or promote products derived from this software |
| 22 | .\" without specific prior written permission. | 18 | .\" without specific prior written permission. |
| 23 | .\" | 19 | .\" |
| @@ -33,33 +29,37 @@ | |||
| 33 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 29 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 34 | .\" SUCH DAMAGE. | 30 | .\" SUCH DAMAGE. |
| 35 | .\" | 31 | .\" |
| 36 | .\" from: @(#)atexit.3 5.3 (Berkeley) 6/29/91 | 32 | .\" $OpenBSD: atexit.3,v 1.9 2013/06/05 03:39:23 tedu Exp $ |
| 37 | .\" $Id: atexit.3,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $ | ||
| 38 | .\" | 33 | .\" |
| 39 | .Dd June 29, 1991 | 34 | .Dd $Mdocdate: June 5 2013 $ |
| 40 | .Dt ATEXIT 3 | 35 | .Dt ATEXIT 3 |
| 41 | .Os | 36 | .Os |
| 42 | .Sh NAME | 37 | .Sh NAME |
| 43 | .Nm atexit | 38 | .Nm atexit |
| 44 | .Nd register a function to be called on exit | 39 | .Nd register a function to be called on exit |
| 45 | .Sh SYNOPSIS | 40 | .Sh SYNOPSIS |
| 46 | .Fd #include <stdlib.h> | 41 | .In stdlib.h |
| 47 | .Ft int | 42 | .Ft int |
| 48 | .Fn atexit "void (*function)(void)" | 43 | .Fn atexit "void (*function)(void)" |
| 49 | .Sh DESCRIPTION | 44 | .Sh DESCRIPTION |
| 50 | The | 45 | The |
| 51 | .Fn atexit | 46 | .Fn atexit |
| 52 | function | 47 | function registers the given |
| 53 | registers the given | 48 | .Fa function |
| 54 | .Ar function | ||
| 55 | to be called at program exit, whether via | 49 | to be called at program exit, whether via |
| 56 | .Xr exit 3 | 50 | .Xr exit 3 |
| 57 | or via return from the program's | 51 | or via return from the program's |
| 58 | .Em main . | 52 | .Fn main . |
| 59 | Functions so registered are called in reverse order; | 53 | Functions so registered are called in reverse order; |
| 60 | no arguments are passed. | 54 | no arguments are passed. |
| 61 | At least 32 functions can always be registered, | 55 | At least 32 functions can always be registered, |
| 62 | and more are allowed as long as sufficient memory can be allocated. | 56 | and more are allowed as long as sufficient memory can be allocated. |
| 57 | .Pp | ||
| 58 | .Fn atexit | ||
| 59 | is very difficult to use correctly without creating | ||
| 60 | .Xr exit 3 Ns -time | ||
| 61 | races. | ||
| 62 | Unless absolutely necessary, please avoid using it. | ||
| 63 | .Sh RETURN VALUES | 63 | .Sh RETURN VALUES |
| 64 | .Rv -std atexit | 64 | .Rv -std atexit |
| 65 | .Sh ERRORS | 65 | .Sh ERRORS |
| @@ -73,6 +73,5 @@ The existing list of functions is unmodified. | |||
| 73 | .Sh STANDARDS | 73 | .Sh STANDARDS |
| 74 | The | 74 | The |
| 75 | .Fn atexit | 75 | .Fn atexit |
| 76 | function | 76 | function conforms to |
| 77 | conforms to | ||
| 78 | .St -ansiC . | 77 | .St -ansiC . |
diff --git a/src/lib/libc/stdlib/atexit.c b/src/lib/libc/stdlib/atexit.c index 4da1eb0d9c..049da3261d 100644 --- a/src/lib/libc/stdlib/atexit.c +++ b/src/lib/libc/stdlib/atexit.c | |||
| @@ -1,68 +1,194 @@ | |||
| 1 | /*- | 1 | /* $OpenBSD: atexit.c,v 1.17 2013/12/28 18:38:42 kettenis Exp $ */ |
| 2 | * Copyright (c) 1990 The Regents of the University of California. | 2 | /* |
| 3 | * Copyright (c) 2002 Daniel Hartmeier | ||
| 3 | * All rights reserved. | 4 | * All rights reserved. |
| 4 | * | 5 | * |
| 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 | 6 | * Redistribution and use in source and binary forms, with or without |
| 9 | * modification, are permitted provided that the following conditions | 7 | * modification, are permitted provided that the following conditions |
| 10 | * are met: | 8 | * 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 | * | 9 | * |
| 24 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | 10 | * - Redistributions of source code must retain the above copyright |
| 25 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 11 | * notice, this list of conditions and the following disclaimer. |
| 26 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 12 | * - Redistributions in binary form must reproduce the above |
| 27 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 13 | * copyright notice, this list of conditions and the following |
| 28 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 14 | * disclaimer in the documentation and/or other materials provided |
| 29 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 15 | * with the distribution. |
| 30 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 16 | * |
| 31 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 32 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 18 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 33 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 19 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
| 34 | * SUCH DAMAGE. | 20 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
| 21 | * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 22 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
| 23 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 24 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 25 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 26 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 27 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 28 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 29 | * | ||
| 35 | */ | 30 | */ |
| 36 | 31 | ||
| 37 | #if defined(LIBC_SCCS) && !defined(lint) | 32 | #include <sys/types.h> |
| 38 | /*static char *sccsid = "from: @(#)atexit.c 5.2 (Berkeley) 11/14/90";*/ | 33 | #include <sys/mman.h> |
| 39 | static char *rcsid = "$Id: atexit.c,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $"; | ||
| 40 | #endif /* LIBC_SCCS and not lint */ | ||
| 41 | |||
| 42 | #include <stdlib.h> | 34 | #include <stdlib.h> |
| 35 | #include <string.h> | ||
| 36 | #include <unistd.h> | ||
| 43 | #include "atexit.h" | 37 | #include "atexit.h" |
| 38 | #include "thread_private.h" | ||
| 44 | 39 | ||
| 45 | struct atexit *__atexit; | 40 | struct atexit *__atexit; |
| 46 | 41 | ||
| 47 | /* | 42 | /* |
| 48 | * Register a function to be performed at exit. | 43 | * Function pointers are stored in a linked list of pages. The list |
| 44 | * is initially empty, and pages are allocated on demand. The first | ||
| 45 | * function pointer in the first allocated page (the last one in | ||
| 46 | * the linked list) is reserved for the cleanup function. | ||
| 47 | * | ||
| 48 | * Outside the following functions, all pages are mprotect()'ed | ||
| 49 | * to prevent unintentional/malicious corruption. | ||
| 50 | */ | ||
| 51 | |||
| 52 | /* | ||
| 53 | * Register a function to be performed at exit or when a shared object | ||
| 54 | * with the given dso handle is unloaded dynamically. Also used as | ||
| 55 | * the backend for atexit(). For more info on this API, see: | ||
| 56 | * | ||
| 57 | * http://www.codesourcery.com/cxx-abi/abi.html#dso-dtor | ||
| 49 | */ | 58 | */ |
| 50 | int | 59 | int |
| 51 | atexit(fn) | 60 | __cxa_atexit(void (*func)(void *), void *arg, void *dso) |
| 52 | void (*fn)(); | ||
| 53 | { | 61 | { |
| 54 | static struct atexit __atexit0; /* one guaranteed table */ | 62 | struct atexit *p = __atexit; |
| 55 | register struct atexit *p; | 63 | struct atexit_fn *fnp; |
| 64 | int pgsize = getpagesize(); | ||
| 65 | int ret = -1; | ||
| 56 | 66 | ||
| 57 | if ((p = __atexit) == NULL) | 67 | if (pgsize < sizeof(*p)) |
| 58 | __atexit = p = &__atexit0; | 68 | return (-1); |
| 59 | else if (p->ind >= ATEXIT_SIZE) { | 69 | _ATEXIT_LOCK(); |
| 60 | if ((p = malloc(sizeof(*p))) == NULL) | 70 | p = __atexit; |
| 61 | return (-1); | 71 | if (p != NULL) { |
| 62 | p->ind = 0; | 72 | if (p->ind + 1 >= p->max) |
| 73 | p = NULL; | ||
| 74 | else if (mprotect(p, pgsize, PROT_READ | PROT_WRITE)) | ||
| 75 | goto unlock; | ||
| 76 | } | ||
| 77 | if (p == NULL) { | ||
| 78 | p = mmap(NULL, pgsize, PROT_READ | PROT_WRITE, | ||
| 79 | MAP_ANON | MAP_PRIVATE, -1, 0); | ||
| 80 | if (p == MAP_FAILED) | ||
| 81 | goto unlock; | ||
| 82 | if (__atexit == NULL) { | ||
| 83 | memset(&p->fns[0], 0, sizeof(p->fns[0])); | ||
| 84 | p->ind = 1; | ||
| 85 | } else | ||
| 86 | p->ind = 0; | ||
| 87 | p->max = (pgsize - ((char *)&p->fns[0] - (char *)p)) / | ||
| 88 | sizeof(p->fns[0]); | ||
| 63 | p->next = __atexit; | 89 | p->next = __atexit; |
| 64 | __atexit = p; | 90 | __atexit = p; |
| 65 | } | 91 | } |
| 66 | p->fns[p->ind++] = fn; | 92 | fnp = &p->fns[p->ind++]; |
| 67 | return (0); | 93 | fnp->fn_ptr.cxa_func = func; |
| 94 | fnp->fn_arg = arg; | ||
| 95 | fnp->fn_dso = dso; | ||
| 96 | if (mprotect(p, pgsize, PROT_READ)) | ||
| 97 | goto unlock; | ||
| 98 | ret = 0; | ||
| 99 | unlock: | ||
| 100 | _ATEXIT_UNLOCK(); | ||
| 101 | return (ret); | ||
| 102 | } | ||
| 103 | |||
| 104 | /* | ||
| 105 | * Call all handlers registered with __cxa_atexit() for the shared | ||
| 106 | * object owning 'dso'. | ||
| 107 | * Note: if 'dso' is NULL, then all remaining handlers are called. | ||
| 108 | */ | ||
| 109 | void | ||
| 110 | __cxa_finalize(void *dso) | ||
| 111 | { | ||
| 112 | struct atexit *p, *q; | ||
| 113 | struct atexit_fn fn; | ||
| 114 | int n, pgsize = getpagesize(); | ||
| 115 | static int call_depth; | ||
| 116 | |||
| 117 | call_depth++; | ||
| 118 | |||
| 119 | for (p = __atexit; p != NULL; p = p->next) { | ||
| 120 | for (n = p->ind; --n >= 0;) { | ||
| 121 | if (p->fns[n].fn_ptr.cxa_func == NULL) | ||
| 122 | continue; /* already called */ | ||
| 123 | if (dso != NULL && dso != p->fns[n].fn_dso) | ||
| 124 | continue; /* wrong DSO */ | ||
| 125 | |||
| 126 | /* | ||
| 127 | * Mark handler as having been already called to avoid | ||
| 128 | * dupes and loops, then call the appropriate function. | ||
| 129 | */ | ||
| 130 | fn = p->fns[n]; | ||
| 131 | if (mprotect(p, pgsize, PROT_READ | PROT_WRITE) == 0) { | ||
| 132 | p->fns[n].fn_ptr.cxa_func = NULL; | ||
| 133 | mprotect(p, pgsize, PROT_READ); | ||
| 134 | } | ||
| 135 | if (fn.fn_dso != NULL) | ||
| 136 | (*fn.fn_ptr.cxa_func)(fn.fn_arg); | ||
| 137 | else | ||
| 138 | (*fn.fn_ptr.std_func)(); | ||
| 139 | } | ||
| 140 | } | ||
| 141 | |||
| 142 | call_depth--; | ||
| 143 | |||
| 144 | /* | ||
| 145 | * If called via exit(), unmap the pages since we have now run | ||
| 146 | * all the handlers. We defer this until calldepth == 0 so that | ||
| 147 | * we don't unmap things prematurely if called recursively. | ||
| 148 | */ | ||
| 149 | if (dso == NULL && call_depth == 0) { | ||
| 150 | for (p = __atexit; p != NULL; ) { | ||
| 151 | q = p; | ||
| 152 | p = p->next; | ||
| 153 | munmap(q, pgsize); | ||
| 154 | } | ||
| 155 | __atexit = NULL; | ||
| 156 | } | ||
| 157 | } | ||
| 158 | |||
| 159 | /* | ||
| 160 | * Register the cleanup function | ||
| 161 | */ | ||
| 162 | void | ||
| 163 | __atexit_register_cleanup(void (*func)(void)) | ||
| 164 | { | ||
| 165 | struct atexit *p; | ||
| 166 | int pgsize = getpagesize(); | ||
| 167 | |||
| 168 | if (pgsize < sizeof(*p)) | ||
| 169 | return; | ||
| 170 | _ATEXIT_LOCK(); | ||
| 171 | p = __atexit; | ||
| 172 | while (p != NULL && p->next != NULL) | ||
| 173 | p = p->next; | ||
| 174 | if (p == NULL) { | ||
| 175 | p = mmap(NULL, pgsize, PROT_READ | PROT_WRITE, | ||
| 176 | MAP_ANON | MAP_PRIVATE, -1, 0); | ||
| 177 | if (p == MAP_FAILED) | ||
| 178 | goto unlock; | ||
| 179 | p->ind = 1; | ||
| 180 | p->max = (pgsize - ((char *)&p->fns[0] - (char *)p)) / | ||
| 181 | sizeof(p->fns[0]); | ||
| 182 | p->next = NULL; | ||
| 183 | __atexit = p; | ||
| 184 | } else { | ||
| 185 | if (mprotect(p, pgsize, PROT_READ | PROT_WRITE)) | ||
| 186 | goto unlock; | ||
| 187 | } | ||
| 188 | p->fns[0].fn_ptr.std_func = func; | ||
| 189 | p->fns[0].fn_arg = NULL; | ||
| 190 | p->fns[0].fn_dso = NULL; | ||
| 191 | mprotect(p, pgsize, PROT_READ); | ||
| 192 | unlock: | ||
| 193 | _ATEXIT_UNLOCK(); | ||
| 68 | } | 194 | } |
diff --git a/src/lib/libc/stdlib/atexit.h b/src/lib/libc/stdlib/atexit.h index 8b756e8fe2..c44005deda 100644 --- a/src/lib/libc/stdlib/atexit.h +++ b/src/lib/libc/stdlib/atexit.h | |||
| @@ -1,46 +1,50 @@ | |||
| 1 | /*- | 1 | /* $OpenBSD: atexit.h,v 1.8 2013/06/02 21:08:36 matthew Exp $ */ |
| 2 | * Copyright (c) 1990 The Regents of the University of California. | 2 | |
| 3 | /* | ||
| 4 | * Copyright (c) 2002 Daniel Hartmeier | ||
| 3 | * All rights reserved. | 5 | * All rights reserved. |
| 4 | * | 6 | * |
| 5 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without |
| 6 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions |
| 7 | * are met: | 9 | * are met: |
| 8 | * 1. Redistributions of source code must retain the above copyright | ||
| 9 | * notice, this list of conditions and the following disclaimer. | ||
| 10 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer in the | ||
| 12 | * documentation and/or other materials provided with the distribution. | ||
| 13 | * 3. All advertising materials mentioning features or use of this software | ||
| 14 | * must display the following acknowledgement: | ||
| 15 | * This product includes software developed by the University of | ||
| 16 | * California, Berkeley and its contributors. | ||
| 17 | * 4. Neither the name of the University nor the names of its contributors | ||
| 18 | * may be used to endorse or promote products derived from this software | ||
| 19 | * without specific prior written permission. | ||
| 20 | * | 10 | * |
| 21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | 11 | * - Redistributions of source code must retain the above copyright |
| 22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 12 | * notice, this list of conditions and the following disclaimer. |
| 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 13 | * - Redistributions in binary form must reproduce the above |
| 24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 14 | * copyright notice, this list of conditions and the following |
| 25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 15 | * disclaimer in the documentation and/or other materials provided |
| 26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 16 | * with the distribution. |
| 27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 17 | * |
| 28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
| 31 | * SUCH DAMAGE. | 21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
| 22 | * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
| 24 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 28 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 29 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 32 | * | 30 | * |
| 33 | * from: @(#)atexit.h 5.1 (Berkeley) 5/15/90 | ||
| 34 | * $Id: atexit.h,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $ | ||
| 35 | */ | 31 | */ |
| 36 | 32 | ||
| 37 | /* must be at least 32 to guarantee ANSI conformance */ | ||
| 38 | #define ATEXIT_SIZE 32 | ||
| 39 | |||
| 40 | struct atexit { | 33 | struct atexit { |
| 41 | struct atexit *next; /* next in list */ | 34 | struct atexit *next; /* next in list */ |
| 42 | int ind; /* next index in this table */ | 35 | int ind; /* next index in this table */ |
| 43 | void (*fns[ATEXIT_SIZE])(); /* the table itself */ | 36 | int max; /* max entries >= ATEXIT_SIZE */ |
| 37 | struct atexit_fn { | ||
| 38 | union { | ||
| 39 | void (*std_func)(void); | ||
| 40 | void (*cxa_func)(void *); | ||
| 41 | } fn_ptr; | ||
| 42 | void *fn_arg; /* argument for CXA callback */ | ||
| 43 | void *fn_dso; /* shared module handle */ | ||
| 44 | } fns[1]; /* the table itself */ | ||
| 44 | }; | 45 | }; |
| 45 | 46 | ||
| 46 | extern struct atexit *__atexit; /* points to head of LIFO stack */ | 47 | extern struct atexit *__atexit; /* points to head of LIFO stack */ |
| 48 | |||
| 49 | int __cxa_atexit(void (*)(void *), void *, void *); | ||
| 50 | void __cxa_finalize(void *); | ||
diff --git a/src/lib/libc/stdlib/atof.3 b/src/lib/libc/stdlib/atof.3 index 53e04f71c5..53722a6253 100644 --- a/src/lib/libc/stdlib/atof.3 +++ b/src/lib/libc/stdlib/atof.3 | |||
| @@ -13,11 +13,7 @@ | |||
| 13 | .\" 2. Redistributions in binary form must reproduce the above copyright | 13 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 14 | .\" notice, this list of conditions and the following disclaimer in the | 14 | .\" notice, this list of conditions and the following disclaimer in the |
| 15 | .\" documentation and/or other materials provided with the distribution. | 15 | .\" documentation and/or other materials provided with the distribution. |
| 16 | .\" 3. All advertising materials mentioning features or use of this software | 16 | .\" 3. Neither the name of the University nor the names of its contributors |
| 17 | .\" must display the following acknowledgement: | ||
| 18 | .\" This product includes software developed by the University of | ||
| 19 | .\" California, Berkeley and its contributors. | ||
| 20 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 21 | .\" may be used to endorse or promote products derived from this software | 17 | .\" may be used to endorse or promote products derived from this software |
| 22 | .\" without specific prior written permission. | 18 | .\" without specific prior written permission. |
| 23 | .\" | 19 | .\" |
| @@ -33,10 +29,9 @@ | |||
| 33 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 29 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 34 | .\" SUCH DAMAGE. | 30 | .\" SUCH DAMAGE. |
| 35 | .\" | 31 | .\" |
| 36 | .\" from: @(#)atof.3 6.4 (Berkeley) 6/29/91 | 32 | .\" $OpenBSD: atof.3,v 1.7 2013/07/17 05:42:11 schwarze Exp $ |
| 37 | .\" $Id: atof.3,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $ | ||
| 38 | .\" | 33 | .\" |
| 39 | .Dd June 29, 1991 | 34 | .Dd $Mdocdate: July 17 2013 $ |
| 40 | .Dt ATOF 3 | 35 | .Dt ATOF 3 |
| 41 | .Os | 36 | .Os |
| 42 | .Sh NAME | 37 | .Sh NAME |
| @@ -45,16 +40,16 @@ | |||
| 45 | .Tn ASCII | 40 | .Tn ASCII |
| 46 | string to double | 41 | string to double |
| 47 | .Sh SYNOPSIS | 42 | .Sh SYNOPSIS |
| 48 | .Fd #include <stdlib.h> | 43 | .In stdlib.h |
| 49 | .Ft double | 44 | .Ft double |
| 50 | .Fn atof "const char *nptr" | 45 | .Fn atof "const char *nptr" |
| 51 | .Sh DESCRIPTION | 46 | .Sh DESCRIPTION |
| 52 | The | 47 | The |
| 53 | .Fn atof | 48 | .Fn atof |
| 54 | function converts the initial portion of the string pointed to by | 49 | function converts the initial portion of the string pointed to by |
| 55 | .Ar nptr | 50 | .Fa nptr |
| 56 | to | 51 | to |
| 57 | .Ar double | 52 | .Li double |
| 58 | representation. | 53 | representation. |
| 59 | .Pp | 54 | .Pp |
| 60 | It is equivalent to: | 55 | It is equivalent to: |
| @@ -72,3 +67,8 @@ The | |||
| 72 | .Fn atof | 67 | .Fn atof |
| 73 | function conforms to | 68 | function conforms to |
| 74 | .St -ansiC . | 69 | .St -ansiC . |
| 70 | .Sh HISTORY | ||
| 71 | An | ||
| 72 | .Fn atof | ||
| 73 | function first appeared in | ||
| 74 | .At v1 . | ||
diff --git a/src/lib/libc/stdlib/atof.c b/src/lib/libc/stdlib/atof.c index 9202de50bb..d14b58b070 100644 --- a/src/lib/libc/stdlib/atof.c +++ b/src/lib/libc/stdlib/atof.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: atof.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */ | ||
| 1 | /* | 2 | /* |
| 2 | * Copyright (c) 1988 The Regents of the University of California. | 3 | * Copyright (c) 1988 The Regents of the University of California. |
| 3 | * All rights reserved. | 4 | * All rights reserved. |
| @@ -10,11 +11,7 @@ | |||
| 10 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the |
| 12 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. Neither the name of the University nor the names of its contributors |
| 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 | 15 | * may be used to endorse or promote products derived from this software |
| 19 | * without specific prior written permission. | 16 | * without specific prior written permission. |
| 20 | * | 17 | * |
| @@ -31,16 +28,10 @@ | |||
| 31 | * SUCH DAMAGE. | 28 | * SUCH DAMAGE. |
| 32 | */ | 29 | */ |
| 33 | 30 | ||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 35 | /*static char *sccsid = "from: @(#)atof.c 5.3 (Berkeley) 1/8/93";*/ | ||
| 36 | static char *rcsid = "$Id: atof.c,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $"; | ||
| 37 | #endif /* LIBC_SCCS and not lint */ | ||
| 38 | |||
| 39 | #include <stdlib.h> | 31 | #include <stdlib.h> |
| 40 | 32 | ||
| 41 | double | 33 | double |
| 42 | atof(ascii) | 34 | atof(const char *ascii) |
| 43 | const char *ascii; | ||
| 44 | { | 35 | { |
| 45 | return(strtod(ascii, (char **)NULL)); | 36 | return(strtod(ascii, (char **)NULL)); |
| 46 | } | 37 | } |
diff --git a/src/lib/libc/stdlib/atoi.3 b/src/lib/libc/stdlib/atoi.3 index 219ba73c00..fd5c720e02 100644 --- a/src/lib/libc/stdlib/atoi.3 +++ b/src/lib/libc/stdlib/atoi.3 | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. | 1 | .\" Copyright (c) 1990, 1991, 1993 |
| 2 | .\" All rights reserved. | 2 | .\" The Regents of the University of California. All rights reserved. |
| 3 | .\" | 3 | .\" |
| 4 | .\" This code is derived from software contributed to Berkeley by | 4 | .\" This code is derived from software contributed to Berkeley by |
| 5 | .\" the American National Standards Committee X3, on Information | 5 | .\" the American National Standards Committee X3, on Information |
| @@ -13,11 +13,7 @@ | |||
| 13 | .\" 2. Redistributions in binary form must reproduce the above copyright | 13 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 14 | .\" notice, this list of conditions and the following disclaimer in the | 14 | .\" notice, this list of conditions and the following disclaimer in the |
| 15 | .\" documentation and/or other materials provided with the distribution. | 15 | .\" documentation and/or other materials provided with the distribution. |
| 16 | .\" 3. All advertising materials mentioning features or use of this software | 16 | .\" 3. Neither the name of the University nor the names of its contributors |
| 17 | .\" must display the following acknowledgement: | ||
| 18 | .\" This product includes software developed by the University of | ||
| 19 | .\" California, Berkeley and its contributors. | ||
| 20 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 21 | .\" may be used to endorse or promote products derived from this software | 17 | .\" may be used to endorse or promote products derived from this software |
| 22 | .\" without specific prior written permission. | 18 | .\" without specific prior written permission. |
| 23 | .\" | 19 | .\" |
| @@ -33,10 +29,9 @@ | |||
| 33 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 29 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 34 | .\" SUCH DAMAGE. | 30 | .\" SUCH DAMAGE. |
| 35 | .\" | 31 | .\" |
| 36 | .\" from: @(#)atoi.3 5.3 (Berkeley) 6/29/91 | 32 | .\" $OpenBSD: atoi.3,v 1.11 2013/07/17 05:42:11 schwarze Exp $ |
| 37 | .\" $Id: atoi.3,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $ | ||
| 38 | .\" | 33 | .\" |
| 39 | .Dd June 29, 1991 | 34 | .Dd $Mdocdate: July 17 2013 $ |
| 40 | .Dt ATOI 3 | 35 | .Dt ATOI 3 |
| 41 | .Os | 36 | .Os |
| 42 | .Sh NAME | 37 | .Sh NAME |
| @@ -45,20 +40,19 @@ | |||
| 45 | .Tn ASCII | 40 | .Tn ASCII |
| 46 | string to integer | 41 | string to integer |
| 47 | .Sh SYNOPSIS | 42 | .Sh SYNOPSIS |
| 48 | .Fd #include <stdlib.h> | 43 | .In stdlib.h |
| 49 | .Ft int | 44 | .Ft int |
| 50 | .Fn atoi "const char *nptr" | 45 | .Fn atoi "const char *nptr" |
| 51 | .Sh DESCRIPTION | 46 | .Sh DESCRIPTION |
| 52 | The | 47 | The |
| 53 | .Fn atoi | 48 | .Fn atoi |
| 54 | function converts the initial portion of the string pointed to by | 49 | function converts the initial portion of the string pointed to by |
| 55 | .Em nptr | 50 | .Fa nptr |
| 56 | to | 51 | to |
| 57 | .Em integer | 52 | .Li integer |
| 58 | representation. | 53 | representation. |
| 59 | .Pp | 54 | .Pp |
| 60 | It is equivalent to: | 55 | It is equivalent to: |
| 61 | .Pp | ||
| 62 | .Bd -literal -offset indent | 56 | .Bd -literal -offset indent |
| 63 | (int)strtol(nptr, (char **)NULL, 10); | 57 | (int)strtol(nptr, (char **)NULL, 10); |
| 64 | .Ed | 58 | .Ed |
| @@ -67,9 +61,31 @@ It is equivalent to: | |||
| 67 | .Xr atol 3 , | 61 | .Xr atol 3 , |
| 68 | .Xr strtod 3 , | 62 | .Xr strtod 3 , |
| 69 | .Xr strtol 3 , | 63 | .Xr strtol 3 , |
| 64 | .Xr strtonum 3 , | ||
| 70 | .Xr strtoul 3 | 65 | .Xr strtoul 3 |
| 71 | .Sh STANDARDS | 66 | .Sh STANDARDS |
| 72 | The | 67 | The |
| 73 | .Fn atoi | 68 | .Fn atoi |
| 74 | function conforms to | 69 | function conforms to |
| 75 | .St -ansiC . | 70 | .St -ansiC . |
| 71 | .Sh HISTORY | ||
| 72 | An | ||
| 73 | .Fn atoi | ||
| 74 | function first appeared in | ||
| 75 | .At v1 . | ||
| 76 | .Sh CAVEATS | ||
| 77 | .Nm | ||
| 78 | does no overflow checking, handles unsigned numbers poorly, | ||
| 79 | and handles strings containing trailing extra characters | ||
| 80 | (like | ||
| 81 | .Dq "123abc" ) | ||
| 82 | poorly. | ||
| 83 | Careful use of | ||
| 84 | .Xr strtol 3 | ||
| 85 | and | ||
| 86 | .Xr strtoul 3 | ||
| 87 | can alleviate these problems, | ||
| 88 | but | ||
| 89 | .Xr strtonum 3 | ||
| 90 | can be used to convert numbers from strings much more safely | ||
| 91 | and easily. | ||
diff --git a/src/lib/libc/stdlib/atoi.c b/src/lib/libc/stdlib/atoi.c index df7845f90c..b0842678e2 100644 --- a/src/lib/libc/stdlib/atoi.c +++ b/src/lib/libc/stdlib/atoi.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: atoi.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */ | ||
| 1 | /* | 2 | /* |
| 2 | * Copyright (c) 1988 Regents of the University of California. | 3 | * Copyright (c) 1988 Regents of the University of California. |
| 3 | * All rights reserved. | 4 | * All rights reserved. |
| @@ -10,11 +11,7 @@ | |||
| 10 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the |
| 12 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. Neither the name of the University nor the names of its contributors |
| 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 | 15 | * may be used to endorse or promote products derived from this software |
| 19 | * without specific prior written permission. | 16 | * without specific prior written permission. |
| 20 | * | 17 | * |
| @@ -31,16 +28,10 @@ | |||
| 31 | * SUCH DAMAGE. | 28 | * SUCH DAMAGE. |
| 32 | */ | 29 | */ |
| 33 | 30 | ||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 35 | /*static char *sccsid = "from: @(#)atoi.c 5.7 (Berkeley) 2/23/91";*/ | ||
| 36 | static char *rcsid = "$Id: atoi.c,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $"; | ||
| 37 | #endif /* LIBC_SCCS and not lint */ | ||
| 38 | |||
| 39 | #include <stdlib.h> | 31 | #include <stdlib.h> |
| 40 | 32 | ||
| 41 | int | 33 | int |
| 42 | atoi(str) | 34 | atoi(const char *str) |
| 43 | const char *str; | ||
| 44 | { | 35 | { |
| 45 | return((int)strtol(str, (char **)NULL, 10)); | 36 | return((int)strtol(str, (char **)NULL, 10)); |
| 46 | } | 37 | } |
diff --git a/src/lib/libc/stdlib/atol.3 b/src/lib/libc/stdlib/atol.3 index 86e3d324a3..ae4cbc7c3d 100644 --- a/src/lib/libc/stdlib/atol.3 +++ b/src/lib/libc/stdlib/atol.3 | |||
| @@ -13,11 +13,7 @@ | |||
| 13 | .\" 2. Redistributions in binary form must reproduce the above copyright | 13 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 14 | .\" notice, this list of conditions and the following disclaimer in the | 14 | .\" notice, this list of conditions and the following disclaimer in the |
| 15 | .\" documentation and/or other materials provided with the distribution. | 15 | .\" documentation and/or other materials provided with the distribution. |
| 16 | .\" 3. All advertising materials mentioning features or use of this software | 16 | .\" 3. Neither the name of the University nor the names of its contributors |
| 17 | .\" must display the following acknowledgement: | ||
| 18 | .\" This product includes software developed by the University of | ||
| 19 | .\" California, Berkeley and its contributors. | ||
| 20 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 21 | .\" may be used to endorse or promote products derived from this software | 17 | .\" may be used to endorse or promote products derived from this software |
| 22 | .\" without specific prior written permission. | 18 | .\" without specific prior written permission. |
| 23 | .\" | 19 | .\" |
| @@ -33,10 +29,9 @@ | |||
| 33 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 29 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 34 | .\" SUCH DAMAGE. | 30 | .\" SUCH DAMAGE. |
| 35 | .\" | 31 | .\" |
| 36 | .\" from: @(#)atol.3 5.3 (Berkeley) 6/29/91 | 32 | .\" $OpenBSD: atol.3,v 1.8 2013/06/05 03:39:23 tedu Exp $ |
| 37 | .\" $Id: atol.3,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $ | ||
| 38 | .\" | 33 | .\" |
| 39 | .Dd June 29, 1991 | 34 | .Dd $Mdocdate: June 5 2013 $ |
| 40 | .Dt ATOL 3 | 35 | .Dt ATOL 3 |
| 41 | .Os | 36 | .Os |
| 42 | .Sh NAME | 37 | .Sh NAME |
| @@ -45,16 +40,16 @@ | |||
| 45 | .Tn ASCII | 40 | .Tn ASCII |
| 46 | string to long integer | 41 | string to long integer |
| 47 | .Sh SYNOPSIS | 42 | .Sh SYNOPSIS |
| 48 | .Fd #include <stdlib.h> | 43 | .In stdlib.h |
| 49 | .Ft long | 44 | .Ft long |
| 50 | .Fn atol "const char *nptr" | 45 | .Fn atol "const char *nptr" |
| 51 | .Sh DESCRIPTION | 46 | .Sh DESCRIPTION |
| 52 | The | 47 | The |
| 53 | .Fn atol | 48 | .Fn atol |
| 54 | function converts the initial portion of the string pointed to by | 49 | function converts the initial portion of the string pointed to by |
| 55 | .Ar nptr | 50 | .Fa nptr |
| 56 | to | 51 | to |
| 57 | .Em long integer | 52 | .Li long integer |
| 58 | representation. | 53 | representation. |
| 59 | .Pp | 54 | .Pp |
| 60 | It is equivalent to: | 55 | It is equivalent to: |
| @@ -64,12 +59,12 @@ strtol(nptr, (char **)NULL, 10); | |||
| 64 | .Sh SEE ALSO | 59 | .Sh SEE ALSO |
| 65 | .Xr atof 3 , | 60 | .Xr atof 3 , |
| 66 | .Xr atoi 3 , | 61 | .Xr atoi 3 , |
| 62 | .Xr atoll 3 , | ||
| 67 | .Xr strtod 3 , | 63 | .Xr strtod 3 , |
| 68 | .Xr strtol 3 , | 64 | .Xr strtol 3 , |
| 69 | .Xr strtoul 3 | 65 | .Xr strtoul 3 |
| 70 | .Sh STANDARDS | 66 | .Sh STANDARDS |
| 71 | The | 67 | The |
| 72 | .Fn atol | 68 | .Fn atol |
| 73 | function | 69 | function conforms to |
| 74 | conforms to | 70 | .St -ansiC-99 . |
| 75 | .St -ansiC . | ||
diff --git a/src/lib/libc/stdlib/atol.c b/src/lib/libc/stdlib/atol.c index 31ed06298b..1970804401 100644 --- a/src/lib/libc/stdlib/atol.c +++ b/src/lib/libc/stdlib/atol.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: atol.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */ | ||
| 1 | /* | 2 | /* |
| 2 | * Copyright (c) 1988 Regents of the University of California. | 3 | * Copyright (c) 1988 Regents of the University of California. |
| 3 | * All rights reserved. | 4 | * All rights reserved. |
| @@ -10,11 +11,7 @@ | |||
| 10 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the |
| 12 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. Neither the name of the University nor the names of its contributors |
| 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 | 15 | * may be used to endorse or promote products derived from this software |
| 19 | * without specific prior written permission. | 16 | * without specific prior written permission. |
| 20 | * | 17 | * |
| @@ -31,16 +28,10 @@ | |||
| 31 | * SUCH DAMAGE. | 28 | * SUCH DAMAGE. |
| 32 | */ | 29 | */ |
| 33 | 30 | ||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 35 | /*static char *sccsid = "from: @(#)atol.c 5.7 (Berkeley) 2/23/91";*/ | ||
| 36 | static char *rcsid = "$Id: atol.c,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $"; | ||
| 37 | #endif /* LIBC_SCCS and not lint */ | ||
| 38 | |||
| 39 | #include <stdlib.h> | 31 | #include <stdlib.h> |
| 40 | 32 | ||
| 41 | long | 33 | long |
| 42 | atol(str) | 34 | atol(const char *str) |
| 43 | const char *str; | ||
| 44 | { | 35 | { |
| 45 | return(strtol(str, (char **)NULL, 10)); | 36 | return(strtol(str, (char **)NULL, 10)); |
| 46 | } | 37 | } |
diff --git a/src/lib/libc/stdlib/free.3 b/src/lib/libc/stdlib/atoll.3 index 3d0131d7de..a9614ae7bb 100644 --- a/src/lib/libc/stdlib/free.3 +++ b/src/lib/libc/stdlib/atoll.3 | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | .\" Copyright (c) 1991 The Regents of the University of California. | 1 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. |
| 2 | .\" All rights reserved. | 2 | .\" All rights reserved. |
| 3 | .\" | 3 | .\" |
| 4 | .\" This code is derived from software contributed to Berkeley by | 4 | .\" This code is derived from software contributed to Berkeley by |
| @@ -13,11 +13,7 @@ | |||
| 13 | .\" 2. Redistributions in binary form must reproduce the above copyright | 13 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 14 | .\" notice, this list of conditions and the following disclaimer in the | 14 | .\" notice, this list of conditions and the following disclaimer in the |
| 15 | .\" documentation and/or other materials provided with the distribution. | 15 | .\" documentation and/or other materials provided with the distribution. |
| 16 | .\" 3. All advertising materials mentioning features or use of this software | 16 | .\" 3. Neither the name of the University nor the names of its contributors |
| 17 | .\" must display the following acknowledgement: | ||
| 18 | .\" This product includes software developed by the University of | ||
| 19 | .\" California, Berkeley and its contributors. | ||
| 20 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 21 | .\" may be used to endorse or promote products derived from this software | 17 | .\" may be used to endorse or promote products derived from this software |
| 22 | .\" without specific prior written permission. | 18 | .\" without specific prior written permission. |
| 23 | .\" | 19 | .\" |
| @@ -33,50 +29,42 @@ | |||
| 33 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 29 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 34 | .\" SUCH DAMAGE. | 30 | .\" SUCH DAMAGE. |
| 35 | .\" | 31 | .\" |
| 36 | .\" from: @(#)free.3 5.2 (Berkeley) 6/29/91 | 32 | .\" $OpenBSD: atoll.3,v 1.6 2013/06/05 03:39:23 tedu Exp $ |
| 37 | .\" $Id: free.3,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $ | ||
| 38 | .\" | 33 | .\" |
| 39 | .Dd June 29, 1991 | 34 | .Dd $Mdocdate: June 5 2013 $ |
| 40 | .Dt FREE 3 | 35 | .Dt ATOLL 3 |
| 41 | .Os | 36 | .Os |
| 42 | .Sh NAME | 37 | .Sh NAME |
| 43 | .Nm free | 38 | .Nm atoll |
| 44 | .Nd free up memory allocated with malloc, calloc or realloc | 39 | .Nd convert |
| 40 | .Tn ASCII | ||
| 41 | string to long long integer | ||
| 45 | .Sh SYNOPSIS | 42 | .Sh SYNOPSIS |
| 46 | .Fd #include <stdlib.h> | 43 | .In stdlib.h |
| 47 | .Ft void | 44 | .Ft long long |
| 48 | .Fn free "void *ptr" | 45 | .Fn atoll "const char *nptr" |
| 49 | .Sh DESCRIPTION | 46 | .Sh DESCRIPTION |
| 50 | The | 47 | The |
| 51 | .Fn free | 48 | .Fn atoll |
| 52 | function causes the space pointed to by | 49 | function converts the initial portion of the string pointed to by |
| 53 | .Fa ptr | 50 | .Fa nptr |
| 54 | to be deallocated, that is, made available | 51 | to |
| 55 | for further allocation. | 52 | .Li long long integer |
| 56 | If | 53 | representation. |
| 57 | .Fa ptr | 54 | .Pp |
| 58 | is a null pointer, no action occurs. | 55 | It is equivalent to: |
| 59 | Otherwise, if the argument does not match a pointer earlier | 56 | .Bd -literal -offset indent |
| 60 | returned by the | 57 | strtoll(nptr, (char **)NULL, 10); |
| 61 | .Xr calloc , | 58 | .Ed |
| 62 | .Xr malloc , | ||
| 63 | or | ||
| 64 | .Xr realloc | ||
| 65 | function, or if the space has been deallocated by a call to | ||
| 66 | .Fn free | ||
| 67 | or | ||
| 68 | .Xr realloc , | ||
| 69 | general havoc may occur. | ||
| 70 | .Sh RETURN VALUES | ||
| 71 | The | ||
| 72 | .Fn free | ||
| 73 | function returns no value. | ||
| 74 | .Sh SEE ALSO | 59 | .Sh SEE ALSO |
| 75 | .Xr calloc 3 , | 60 | .Xr atof 3 , |
| 76 | .Xr malloc 3 , | 61 | .Xr atoi 3 , |
| 77 | .Xr realloc 3 | 62 | .Xr atol 3 , |
| 63 | .Xr strtod 3 , | ||
| 64 | .Xr strtol 3 , | ||
| 65 | .Xr strtoul 3 | ||
| 78 | .Sh STANDARDS | 66 | .Sh STANDARDS |
| 79 | The | 67 | The |
| 80 | .Fn free | 68 | .Fn atoll |
| 81 | function conforms to | 69 | function conforms to |
| 82 | .St -ansiC . | 70 | .St -ansiC-99 . |
diff --git a/src/lib/libc/stdlib/putenv.c b/src/lib/libc/stdlib/atoll.c index 2194c2c608..a65e682cfb 100644 --- a/src/lib/libc/stdlib/putenv.c +++ b/src/lib/libc/stdlib/atoll.c | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | /*- | 1 | /* $OpenBSD: atoll.c,v 1.3 2005/08/08 08:05:36 espie Exp $ */ |
| 2 | * Copyright (c) 1988 The Regents of the University of California. | 2 | /* |
| 3 | * Copyright (c) 1988 Regents of the University of California. | ||
| 3 | * All rights reserved. | 4 | * All rights reserved. |
| 4 | * | 5 | * |
| 5 | * Redistribution and use in source and binary forms, with or without | 6 | * Redistribution and use in source and binary forms, with or without |
| @@ -10,11 +11,7 @@ | |||
| 10 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the |
| 12 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. Neither the name of the University nor the names of its contributors |
| 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 | 15 | * may be used to endorse or promote products derived from this software |
| 19 | * without specific prior written permission. | 16 | * without specific prior written permission. |
| 20 | * | 17 | * |
| @@ -31,29 +28,11 @@ | |||
| 31 | * SUCH DAMAGE. | 28 | * SUCH DAMAGE. |
| 32 | */ | 29 | */ |
| 33 | 30 | ||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 35 | /*static char *sccsid = "from: @(#)putenv.c 5.4 (Berkeley) 2/23/91";*/ | ||
| 36 | static char *rcsid = "$Id: putenv.c,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $"; | ||
| 37 | #endif /* LIBC_SCCS and not lint */ | ||
| 38 | |||
| 39 | #include <stdlib.h> | 31 | #include <stdlib.h> |
| 40 | #include <string.h> | ||
| 41 | 32 | ||
| 42 | int | 33 | long long |
| 43 | putenv(str) | 34 | atoll(str) |
| 44 | const char *str; | 35 | const char *str; |
| 45 | { | 36 | { |
| 46 | register char *p, *equal; | 37 | return(strtoll(str, (char **)NULL, 10)); |
| 47 | int rval; | ||
| 48 | |||
| 49 | if (!(p = strdup(str))) | ||
| 50 | return(1); | ||
| 51 | if (!(equal = strchr(p, '='))) { | ||
| 52 | (void)free(p); | ||
| 53 | return(1); | ||
| 54 | } | ||
| 55 | *equal = '\0'; | ||
| 56 | rval = setenv(p, equal + 1, 1); | ||
| 57 | (void)free(p); | ||
| 58 | return(rval); | ||
| 59 | } | 38 | } |
diff --git a/src/lib/libc/stdlib/bsearch.3 b/src/lib/libc/stdlib/bsearch.3 index 1622c96c6b..270086df36 100644 --- a/src/lib/libc/stdlib/bsearch.3 +++ b/src/lib/libc/stdlib/bsearch.3 | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. | 1 | .\" Copyright (c) 1990, 1991, 1993, 1994 |
| 2 | .\" All rights reserved. | 2 | .\" The Regents of the University of California. All rights reserved. |
| 3 | .\" | 3 | .\" |
| 4 | .\" This code is derived from software contributed to Berkeley by | 4 | .\" This code is derived from software contributed to Berkeley by |
| 5 | .\" the American National Standards Committee X3, on Information | 5 | .\" the American National Standards Committee X3, on Information |
| @@ -13,11 +13,7 @@ | |||
| 13 | .\" 2. Redistributions in binary form must reproduce the above copyright | 13 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 14 | .\" notice, this list of conditions and the following disclaimer in the | 14 | .\" notice, this list of conditions and the following disclaimer in the |
| 15 | .\" documentation and/or other materials provided with the distribution. | 15 | .\" documentation and/or other materials provided with the distribution. |
| 16 | .\" 3. All advertising materials mentioning features or use of this software | 16 | .\" 3. Neither the name of the University nor the names of its contributors |
| 17 | .\" must display the following acknowledgement: | ||
| 18 | .\" This product includes software developed by the University of | ||
| 19 | .\" California, Berkeley and its contributors. | ||
| 20 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 21 | .\" may be used to endorse or promote products derived from this software | 17 | .\" may be used to endorse or promote products derived from this software |
| 22 | .\" without specific prior written permission. | 18 | .\" without specific prior written permission. |
| 23 | .\" | 19 | .\" |
| @@ -33,30 +29,29 @@ | |||
| 33 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 29 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 34 | .\" SUCH DAMAGE. | 30 | .\" SUCH DAMAGE. |
| 35 | .\" | 31 | .\" |
| 36 | .\" from: @(#)bsearch.3 5.6 (Berkeley) 6/29/91 | 32 | .\" $OpenBSD: bsearch.3,v 1.9 2013/06/05 03:39:23 tedu Exp $ |
| 37 | .\" $Id: bsearch.3,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $ | ||
| 38 | .\" | 33 | .\" |
| 39 | .Dd June 29, 1991 | 34 | .Dd $Mdocdate: June 5 2013 $ |
| 40 | .Dt BSEARCH 3 | 35 | .Dt BSEARCH 3 |
| 41 | .Os | 36 | .Os |
| 42 | .Sh NAME | 37 | .Sh NAME |
| 43 | .Nm bsearch | 38 | .Nm bsearch |
| 44 | .Nd binary search of a sorted table | 39 | .Nd binary search of a sorted table |
| 45 | .Sh SYNOPSIS | 40 | .Sh SYNOPSIS |
| 46 | .Fd #include <stdlib.h> | 41 | .In stdlib.h |
| 47 | .Ft void * | 42 | .Ft void * |
| 48 | .Fn bsearch "const void *key" "const void *base" "size_t nmemb" "size_t size" "int (*compar) (const void *, const void *)" | 43 | .Fn bsearch "const void *key" "const void *base" "size_t nmemb" "size_t size" "int (*compar)(const void *, const void *)" |
| 49 | .Sh DESCRIPTION | 44 | .Sh DESCRIPTION |
| 50 | The | 45 | The |
| 51 | .Fn bsearch | 46 | .Fn bsearch |
| 52 | function searches an array of | 47 | function searches an array of |
| 53 | .Fa nmemb | 48 | .Fa nmemb |
| 54 | objects, the initial member of which is | 49 | objects, the initial member of which is |
| 55 | pointed to by | 50 | pointed to by |
| 56 | .Fa base , | 51 | .Fa base , |
| 57 | for a member that matches the object pointed to by | 52 | for a member that matches the object pointed to by |
| 58 | .Fa key . | 53 | .Fa key . |
| 59 | The size of each member of the array is specified by | 54 | The size of each member of the array is specified by |
| 60 | .Fa size . | 55 | .Fa size . |
| 61 | .Pp | 56 | .Pp |
| 62 | The contents of the array should be in ascending sorted order according | 57 | The contents of the array should be in ascending sorted order according |
| @@ -64,9 +59,7 @@ to the comparison function referenced by | |||
| 64 | .Fa compar . | 59 | .Fa compar . |
| 65 | The | 60 | The |
| 66 | .Fa compar | 61 | .Fa compar |
| 67 | routine | 62 | routine is expected to have two arguments which point to the |
| 68 | is expected to have two | ||
| 69 | two arguments which point to the | ||
| 70 | .Fa key | 63 | .Fa key |
| 71 | object and to an array member, in that order, and should return an integer | 64 | object and to an array member, in that order, and should return an integer |
| 72 | less than, equal to, or greater than zero if the | 65 | less than, equal to, or greater than zero if the |
| @@ -83,7 +76,7 @@ If two members compare as equal, which member is matched is unspecified. | |||
| 83 | .Xr db 3 , | 76 | .Xr db 3 , |
| 84 | .Xr lsearch 3 , | 77 | .Xr lsearch 3 , |
| 85 | .Xr qsort 3 , | 78 | .Xr qsort 3 , |
| 86 | .\" .Xr tsearch 3 | 79 | .Xr tsearch 3 |
| 87 | .Sh STANDARDS | 80 | .Sh STANDARDS |
| 88 | The | 81 | The |
| 89 | .Fn bsearch | 82 | .Fn bsearch |
diff --git a/src/lib/libc/stdlib/bsearch.c b/src/lib/libc/stdlib/bsearch.c index fac03f694f..b48747236e 100644 --- a/src/lib/libc/stdlib/bsearch.c +++ b/src/lib/libc/stdlib/bsearch.c | |||
| @@ -10,11 +10,7 @@ | |||
| 10 | * 2. Redistributions in binary form must reproduce the above copyright | 10 | * 2. Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in the | 11 | * notice, this list of conditions and the following disclaimer in the |
| 12 | * documentation and/or other materials provided with the distribution. | 12 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. All advertising materials mentioning features or use of this software | 13 | * 3. Neither the name of the University nor the names of its contributors |
| 14 | * must display the following acknowledgement: | ||
| 15 | * This product includes software developed by the University of | ||
| 16 | * California, Berkeley and its contributors. | ||
| 17 | * 4. Neither the name of the University nor the names of its contributors | ||
| 18 | * may be used to endorse or promote products derived from this software | 14 | * may be used to endorse or promote products derived from this software |
| 19 | * without specific prior written permission. | 15 | * without specific prior written permission. |
| 20 | * | 16 | * |
| @@ -31,11 +27,6 @@ | |||
| 31 | * SUCH DAMAGE. | 27 | * SUCH DAMAGE. |
| 32 | */ | 28 | */ |
| 33 | 29 | ||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 35 | /*static char *sccsid = "from: @(#)bsearch.c 5.4 (Berkeley) 2/23/91";*/ | ||
| 36 | static char *rcsid = "$Id: bsearch.c,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $"; | ||
| 37 | #endif /* LIBC_SCCS and not lint */ | ||
| 38 | |||
| 39 | #include <stdlib.h> | 30 | #include <stdlib.h> |
| 40 | 31 | ||
| 41 | /* | 32 | /* |
| @@ -46,7 +37,7 @@ static char *rcsid = "$Id: bsearch.c,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $ | |||
| 46 | * is odd, moving left simply involves halving lim: e.g., when lim | 37 | * is odd, moving left simply involves halving lim: e.g., when lim |
| 47 | * is 5 we look at item 2, so we change lim to 2 so that we will | 38 | * is 5 we look at item 2, so we change lim to 2 so that we will |
| 48 | * look at items 0 & 1. If lim is even, the same applies. If lim | 39 | * look at items 0 & 1. If lim is even, the same applies. If lim |
| 49 | * is odd, moving right again involes halving lim, this time moving | 40 | * is odd, moving right again involves halving lim, this time moving |
| 50 | * the base up one item past p: e.g., when lim is 5 we change base | 41 | * the base up one item past p: e.g., when lim is 5 we change base |
| 51 | * to item 3 and make lim 2 so that we will look at items 3 and 4. | 42 | * to item 3 and make lim 2 so that we will look at items 3 and 4. |
| 52 | * If lim is even, however, we have to shrink it by one before | 43 | * If lim is even, however, we have to shrink it by one before |
| @@ -55,16 +46,12 @@ static char *rcsid = "$Id: bsearch.c,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $ | |||
| 55 | * look at item 3. | 46 | * look at item 3. |
| 56 | */ | 47 | */ |
| 57 | void * | 48 | void * |
| 58 | bsearch(key, base0, nmemb, size, compar) | 49 | bsearch(const void *key, const void *base0, size_t nmemb, size_t size, |
| 59 | register const void *key; | 50 | int (*compar)(const void *, const void *)) |
| 60 | const void *base0; | ||
| 61 | size_t nmemb; | ||
| 62 | register size_t size; | ||
| 63 | register int (*compar) __P((const void *, const void *)); | ||
| 64 | { | 51 | { |
| 65 | register const char *base = base0; | 52 | const char *base = base0; |
| 66 | register int lim, cmp; | 53 | int lim, cmp; |
| 67 | register const void *p; | 54 | const void *p; |
| 68 | 55 | ||
| 69 | for (lim = nmemb; lim != 0; lim >>= 1) { | 56 | for (lim = nmemb; lim != 0; lim >>= 1) { |
| 70 | p = base + (lim >> 1) * size; | 57 | p = base + (lim >> 1) * size; |
diff --git a/src/lib/libc/stdlib/cfree.c b/src/lib/libc/stdlib/cfree.c new file mode 100644 index 0000000000..acf6d1c8ac --- /dev/null +++ b/src/lib/libc/stdlib/cfree.c | |||
| @@ -0,0 +1,39 @@ | |||
| 1 | /* $OpenBSD: cfree.c,v 1.6 2012/12/05 23:20:01 deraadt Exp $ */ | ||
| 2 | |||
| 3 | /* | ||
| 4 | * Copyright (c) 1996 SigmaSoft, Th. Lockert <tholo@sigmasoft.com> | ||
| 5 | * All rights reserved. | ||
| 6 | * | ||
| 7 | * Redistribution and use in source and binary forms, with or without | ||
| 8 | * modification, are permitted provided that the following conditions | ||
| 9 | * are met: | ||
| 10 | * 1. Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 13 | * notice, this list of conditions and the following disclaimer in the | ||
| 14 | * documentation and/or other materials provided with the distribution. | ||
| 15 | * | ||
| 16 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, | ||
| 17 | * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY | ||
| 18 | * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL | ||
| 19 | * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
| 20 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
| 21 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | ||
| 22 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||
| 23 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | ||
| 24 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | ||
| 25 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 26 | */ | ||
| 27 | |||
| 28 | #include <stdlib.h> | ||
| 29 | |||
| 30 | #ifdef __indr_reference | ||
| 31 | __indr_reference(free, cfree); | ||
| 32 | #else | ||
| 33 | |||
| 34 | void | ||
| 35 | cfree(void *p) | ||
| 36 | { | ||
| 37 | free(p); | ||
| 38 | } | ||
| 39 | #endif | ||
diff --git a/src/lib/libc/stdlib/div.3 b/src/lib/libc/stdlib/div.3 index a4730694a5..1a2a326269 100644 --- a/src/lib/libc/stdlib/div.3 +++ b/src/lib/libc/stdlib/div.3 | |||
| @@ -11,11 +11,7 @@ | |||
| 11 | .\" 2. Redistributions in binary form must reproduce the above copyright | 11 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 12 | .\" notice, this list of conditions and the following disclaimer in the | 12 | .\" notice, this list of conditions and the following disclaimer in the |
| 13 | .\" documentation and/or other materials provided with the distribution. | 13 | .\" documentation and/or other materials provided with the distribution. |
| 14 | .\" 3. All advertising materials mentioning features or use of this software | 14 | .\" 3. Neither the name of the University nor the names of its contributors |
| 15 | .\" must display the following acknowledgement: | ||
| 16 | .\" This product includes software developed by the University of | ||
| 17 | .\" California, Berkeley and its contributors. | ||
| 18 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 19 | .\" may be used to endorse or promote products derived from this software | 15 | .\" may be used to endorse or promote products derived from this software |
| 20 | .\" without specific prior written permission. | 16 | .\" without specific prior written permission. |
| 21 | .\" | 17 | .\" |
| @@ -31,40 +27,38 @@ | |||
| 31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 27 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 32 | .\" SUCH DAMAGE. | 28 | .\" SUCH DAMAGE. |
| 33 | .\" | 29 | .\" |
| 34 | .\" from: @(#)div.3 5.2 (Berkeley) 4/19/91 | 30 | .\" $OpenBSD: div.3,v 1.11 2013/06/05 03:39:23 tedu Exp $ |
| 35 | .\" $Id: div.3,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $ | ||
| 36 | .\" | 31 | .\" |
| 37 | .Dd April 19, 1991 | 32 | .Dd $Mdocdate: June 5 2013 $ |
| 38 | .Dt DIV 3 | 33 | .Dt DIV 3 |
| 39 | .Os | 34 | .Os |
| 40 | .Sh NAME | 35 | .Sh NAME |
| 41 | .Nm div | 36 | .Nm div |
| 42 | .Nd return quotient and remainder from division | 37 | .Nd return quotient and remainder from division |
| 43 | .Sh SYNOPSIS | 38 | .Sh SYNOPSIS |
| 44 | .Fd #include <stdlib.h> | 39 | .In stdlib.h |
| 45 | .Ft div_t | 40 | .Ft div_t |
| 46 | .Fn div "int num" "int denom" | 41 | .Fn div "int num" "int denom" |
| 47 | .Sh DESCRIPTION | 42 | .Sh DESCRIPTION |
| 48 | The | 43 | The |
| 49 | .Fn div | 44 | .Fn div |
| 50 | function | 45 | function computes the value |
| 51 | computes the value | 46 | .Fa num Ns / Ns Fa denom |
| 52 | .Fa num/denom | ||
| 53 | and returns the quotient and remainder in a structure named | 47 | and returns the quotient and remainder in a structure named |
| 54 | .Fa div_t | 48 | .Fa div_t |
| 55 | that contains two | 49 | that contains two |
| 56 | .Em int | 50 | .Li int |
| 57 | members named | 51 | members named |
| 58 | .Fa quot | 52 | .Fa quot |
| 59 | and | 53 | and |
| 60 | .Fa rem . | 54 | .Fa rem . |
| 61 | .Sh SEE ALSO | 55 | .Sh SEE ALSO |
| 56 | .Xr imaxdiv 3 , | ||
| 62 | .Xr ldiv 3 , | 57 | .Xr ldiv 3 , |
| 63 | .Xr qdiv 3 , | 58 | .Xr lldiv 3 , |
| 64 | .Xr math 3 | 59 | .Xr qdiv 3 |
| 65 | .Sh STANDARDS | 60 | .Sh STANDARDS |
| 66 | The | 61 | The |
| 67 | .Fn div | 62 | .Fn div |
| 68 | function | 63 | function conforms to |
| 69 | conforms to | ||
| 70 | .St -ansiC . | 64 | .St -ansiC . |
diff --git a/src/lib/libc/stdlib/div.c b/src/lib/libc/stdlib/div.c index 122ac0deec..f7ac2db4b0 100644 --- a/src/lib/libc/stdlib/div.c +++ b/src/lib/libc/stdlib/div.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: div.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */ | ||
| 1 | /* | 2 | /* |
| 2 | * Copyright (c) 1990 Regents of the University of California. | 3 | * Copyright (c) 1990 Regents of the University of California. |
| 3 | * All rights reserved. | 4 | * All rights reserved. |
| @@ -13,11 +14,7 @@ | |||
| 13 | * 2. Redistributions in binary form must reproduce the above copyright | 14 | * 2. Redistributions in binary form must reproduce the above copyright |
| 14 | * notice, this list of conditions and the following disclaimer in the | 15 | * notice, this list of conditions and the following disclaimer in the |
| 15 | * documentation and/or other materials provided with the distribution. | 16 | * documentation and/or other materials provided with the distribution. |
| 16 | * 3. All advertising materials mentioning features or use of this software | 17 | * 3. Neither the name of the University nor the names of its contributors |
| 17 | * must display the following acknowledgement: | ||
| 18 | * This product includes software developed by the University of | ||
| 19 | * California, Berkeley and its contributors. | ||
| 20 | * 4. Neither the name of the University nor the names of its contributors | ||
| 21 | * may be used to endorse or promote products derived from this software | 18 | * may be used to endorse or promote products derived from this software |
| 22 | * without specific prior written permission. | 19 | * without specific prior written permission. |
| 23 | * | 20 | * |
| @@ -34,16 +31,10 @@ | |||
| 34 | * SUCH DAMAGE. | 31 | * SUCH DAMAGE. |
| 35 | */ | 32 | */ |
| 36 | 33 | ||
| 37 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 38 | /*static char *sccsid = "from: @(#)div.c 5.2 (Berkeley) 4/16/91";*/ | ||
| 39 | static char *rcsid = "$Id: div.c,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $"; | ||
| 40 | #endif /* LIBC_SCCS and not lint */ | ||
| 41 | |||
| 42 | #include <stdlib.h> /* div_t */ | 34 | #include <stdlib.h> /* div_t */ |
| 43 | 35 | ||
| 44 | div_t | 36 | div_t |
| 45 | div(num, denom) | 37 | div(int num, int denom) |
| 46 | int num, denom; | ||
| 47 | { | 38 | { |
| 48 | div_t r; | 39 | div_t r; |
| 49 | 40 | ||
diff --git a/src/lib/libc/stdlib/drand48.c b/src/lib/libc/stdlib/drand48.c index ae1a8634dc..b6c046c831 100644 --- a/src/lib/libc/stdlib/drand48.c +++ b/src/lib/libc/stdlib/drand48.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: drand48.c,v 1.3 2005/08/08 08:05:36 espie Exp $ */ | ||
| 1 | /* | 2 | /* |
| 2 | * Copyright (c) 1993 Martin Birgmeier | 3 | * Copyright (c) 1993 Martin Birgmeier |
| 3 | * All rights reserved. | 4 | * All rights reserved. |
diff --git a/src/lib/libc/stdlib/ecvt.3 b/src/lib/libc/stdlib/ecvt.3 new file mode 100644 index 0000000000..d8a3489b1f --- /dev/null +++ b/src/lib/libc/stdlib/ecvt.3 | |||
| @@ -0,0 +1,168 @@ | |||
| 1 | .\" $OpenBSD: ecvt.3,v 1.11 2013/06/05 03:39:23 tedu Exp $ | ||
| 2 | .\" | ||
| 3 | .\" Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com> | ||
| 4 | .\" | ||
| 5 | .\" Permission to use, copy, modify, and distribute this software for any | ||
| 6 | .\" purpose with or without fee is hereby granted, provided that the above | ||
| 7 | .\" copyright notice and this permission notice appear in all copies. | ||
| 8 | .\" | ||
| 9 | .\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 10 | .\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 11 | .\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 12 | .\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 13 | .\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 14 | .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 15 | .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 16 | .\" | ||
| 17 | .\" Sponsored in part by the Defense Advanced Research Projects | ||
| 18 | .\" Agency (DARPA) and Air Force Research Laboratory, Air Force | ||
| 19 | .\" Materiel Command, USAF, under agreement number F39502-99-1-0512. | ||
| 20 | .\" | ||
| 21 | .Dd $Mdocdate: June 5 2013 $ | ||
| 22 | .Dt ECVT 3 | ||
| 23 | .Os | ||
| 24 | .Sh NAME | ||
| 25 | .Nm ecvt , | ||
| 26 | .Nm fcvt , | ||
| 27 | .Nm gcvt | ||
| 28 | .Nd convert double to | ||
| 29 | .Tn ASCII | ||
| 30 | string | ||
| 31 | .Sh SYNOPSIS | ||
| 32 | .In stdlib.h | ||
| 33 | .Ft char * | ||
| 34 | .Fn ecvt "double value" "int ndigit" "int *decpt" "int *sign" | ||
| 35 | .Ft char * | ||
| 36 | .Fn fcvt "double value" "int ndigit" "int *decpt" "int *sign" | ||
| 37 | .Ft char * | ||
| 38 | .Fn gcvt "double value" "int ndigit" "char *buf" | ||
| 39 | .Sh DESCRIPTION | ||
| 40 | .Bf -symbolic | ||
| 41 | These functions are provided for compatibility with legacy code. | ||
| 42 | New code should use the | ||
| 43 | .Xr snprintf 3 | ||
| 44 | function for improved safety and portability. | ||
| 45 | .Ef | ||
| 46 | .Pp | ||
| 47 | The | ||
| 48 | .Fn ecvt , | ||
| 49 | .Fn fcvt | ||
| 50 | and | ||
| 51 | .Fn gcvt | ||
| 52 | functions convert the double precision floating-point number | ||
| 53 | .Fa value | ||
| 54 | to a NUL-terminated | ||
| 55 | .Tn ASCII | ||
| 56 | string. | ||
| 57 | .Pp | ||
| 58 | The | ||
| 59 | .Fn ecvt | ||
| 60 | function converts | ||
| 61 | .Fa value | ||
| 62 | to a NUL-terminated string of exactly | ||
| 63 | .Fa ndigit | ||
| 64 | digits and returns a pointer to that string. | ||
| 65 | The result is padded with zeroes from left to right as needed. | ||
| 66 | There are no leading zeroes unless | ||
| 67 | .Fa value | ||
| 68 | itself is 0. | ||
| 69 | The least significant digit is rounded in an implementation-dependent manner. | ||
| 70 | The position of the decimal point relative to the beginning of the string | ||
| 71 | is stored in | ||
| 72 | .Fa decpt . | ||
| 73 | A negative value indicates that the decimal point is located | ||
| 74 | to the left of the returned digits (this occurs when there is no | ||
| 75 | whole number component to | ||
| 76 | .Fa value ) . | ||
| 77 | If | ||
| 78 | .Fa value | ||
| 79 | is zero, it is unspecified whether the integer pointed to by | ||
| 80 | .Fa decpt | ||
| 81 | will be 0 or 1. | ||
| 82 | The decimal point itself is not included in the returned string. | ||
| 83 | If the sign of the result is negative, the integer pointed to by | ||
| 84 | .Fa sign | ||
| 85 | is non-zero; otherwise, it is 0. | ||
| 86 | .Pp | ||
| 87 | If the converted value is out of range or is not representable, | ||
| 88 | the contents of the returned string are unspecified. | ||
| 89 | .Pp | ||
| 90 | The | ||
| 91 | .Fn fcvt | ||
| 92 | function is identical to | ||
| 93 | .Fn ecvt | ||
| 94 | with the exception that | ||
| 95 | .Fa ndigit | ||
| 96 | specifies the number of digits after the decimal point (zero-padded as | ||
| 97 | needed). | ||
| 98 | .Pp | ||
| 99 | The | ||
| 100 | .Fn gcvt | ||
| 101 | function converts | ||
| 102 | .Fa value | ||
| 103 | to a NUL-terminated string similar to the %g | ||
| 104 | .Xr printf 3 | ||
| 105 | format specifier and stores the result in | ||
| 106 | .Fa buf . | ||
| 107 | It produces | ||
| 108 | .Fa ndigit | ||
| 109 | significant digits similar to the %f | ||
| 110 | .Xr printf 3 | ||
| 111 | format specifier where possible. | ||
| 112 | If | ||
| 113 | .Fa ndigit | ||
| 114 | does allow sufficient precision, the result is stored in | ||
| 115 | exponential notation similar to the %e | ||
| 116 | .Xr printf 3 | ||
| 117 | format specifier. | ||
| 118 | If | ||
| 119 | .Fa value | ||
| 120 | is less than zero, | ||
| 121 | .Fa buf | ||
| 122 | will be prefixed with a minus sign. | ||
| 123 | A decimal point is included in the returned string if | ||
| 124 | .Fa value | ||
| 125 | is not a whole number. | ||
| 126 | Unlike the | ||
| 127 | .Fn ecvt | ||
| 128 | and | ||
| 129 | .Fn fcvt | ||
| 130 | functions, | ||
| 131 | .Fa buf | ||
| 132 | is not zero-padded. | ||
| 133 | .Sh RETURN VALUES | ||
| 134 | The | ||
| 135 | .Fn ecvt , | ||
| 136 | .Fn fcvt | ||
| 137 | and | ||
| 138 | .Fn gcvt | ||
| 139 | functions return a NUL-terminated string representation of | ||
| 140 | .Fa value . | ||
| 141 | .Sh SEE ALSO | ||
| 142 | .Xr printf 3 , | ||
| 143 | .Xr strtod 3 | ||
| 144 | .Sh STANDARDS | ||
| 145 | The | ||
| 146 | .Fn ecvt , | ||
| 147 | .Fn fcvt | ||
| 148 | and | ||
| 149 | .Fn gcvt | ||
| 150 | functions conform to | ||
| 151 | .St -p1003.1-2001 ; | ||
| 152 | as of | ||
| 153 | .St -p1003.1-2008 | ||
| 154 | they are no longer a part of the standard. | ||
| 155 | .Sh CAVEATS | ||
| 156 | The | ||
| 157 | .Fn ecvt | ||
| 158 | and | ||
| 159 | .Fn fcvt | ||
| 160 | functions return a pointer to internal storage space that will be | ||
| 161 | overwritten by subsequent calls to either function. | ||
| 162 | .Pp | ||
| 163 | The maximum possible precision of the return value is limited by the | ||
| 164 | precision of a double and may not be the same on all architectures. | ||
| 165 | .Pp | ||
| 166 | The | ||
| 167 | .Xr snprintf 3 | ||
| 168 | function is preferred over these functions for new code. | ||
diff --git a/src/lib/libc/stdlib/ecvt.c b/src/lib/libc/stdlib/ecvt.c new file mode 100644 index 0000000000..4562e309e8 --- /dev/null +++ b/src/lib/libc/stdlib/ecvt.c | |||
| @@ -0,0 +1,106 @@ | |||
| 1 | /* $OpenBSD: ecvt.c,v 1.8 2013/11/01 19:05:11 guenther Exp $ */ | ||
| 2 | |||
| 3 | /* | ||
| 4 | * Copyright (c) 2002, 2006 Todd C. Miller <Todd.Miller@courtesan.com> | ||
| 5 | * | ||
| 6 | * Permission to use, copy, modify, and distribute this software for any | ||
| 7 | * purpose with or without fee is hereby granted, provided that the above | ||
| 8 | * copyright notice and this permission notice appear in all copies. | ||
| 9 | * | ||
| 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 17 | * | ||
| 18 | * Sponsored in part by the Defense Advanced Research Projects | ||
| 19 | * Agency (DARPA) and Air Force Research Laboratory, Air Force | ||
| 20 | * Materiel Command, USAF, under agreement number F39502-99-1-0512. | ||
| 21 | */ | ||
| 22 | |||
| 23 | #include <stdio.h> | ||
| 24 | #include <stdlib.h> | ||
| 25 | #include <string.h> | ||
| 26 | #include "gdtoa.h" | ||
| 27 | |||
| 28 | static char *__cvt(double, int, int *, int *, int, int); | ||
| 29 | |||
| 30 | static char * | ||
| 31 | __cvt(double value, int ndigit, int *decpt, int *sign, int fmode, int pad) | ||
| 32 | { | ||
| 33 | static char *s; | ||
| 34 | char *p, *rve, c; | ||
| 35 | size_t siz; | ||
| 36 | |||
| 37 | if (ndigit == 0) { | ||
| 38 | *sign = value < 0.0; | ||
| 39 | *decpt = 0; | ||
| 40 | return (""); | ||
| 41 | } | ||
| 42 | |||
| 43 | if (s) { | ||
| 44 | free(s); | ||
| 45 | s = NULL; | ||
| 46 | } | ||
| 47 | |||
| 48 | if (ndigit < 0) | ||
| 49 | siz = -ndigit + 1; | ||
| 50 | else | ||
| 51 | siz = ndigit + 1; | ||
| 52 | |||
| 53 | |||
| 54 | /* __dtoa() doesn't allocate space for 0 so we do it by hand */ | ||
| 55 | if (value == 0.0) { | ||
| 56 | *decpt = 1 - fmode; /* 1 for 'e', 0 for 'f' */ | ||
| 57 | *sign = 0; | ||
| 58 | if ((rve = s = (char *)malloc(siz)) == NULL) | ||
| 59 | return(NULL); | ||
| 60 | *rve++ = '0'; | ||
| 61 | *rve = '\0'; | ||
| 62 | } else { | ||
| 63 | p = __dtoa(value, fmode + 2, ndigit, decpt, sign, &rve); | ||
| 64 | if (p == NULL) | ||
| 65 | return (NULL); | ||
| 66 | if (*decpt == 9999) { | ||
| 67 | /* Infinity or Nan, convert to inf or nan like printf */ | ||
| 68 | *decpt = 0; | ||
| 69 | c = *p; | ||
| 70 | __freedtoa(p); | ||
| 71 | return(c == 'I' ? "inf" : "nan"); | ||
| 72 | } | ||
| 73 | /* Make a local copy and adjust rve to be in terms of s */ | ||
| 74 | if (pad && fmode) | ||
| 75 | siz += *decpt; | ||
| 76 | if ((s = (char *)malloc(siz)) == NULL) { | ||
| 77 | __freedtoa(p); | ||
| 78 | return(NULL); | ||
| 79 | } | ||
| 80 | (void) strlcpy(s, p, siz); | ||
| 81 | rve = s + (rve - p); | ||
| 82 | __freedtoa(p); | ||
| 83 | } | ||
| 84 | |||
| 85 | /* Add trailing zeros */ | ||
| 86 | if (pad) { | ||
| 87 | siz -= rve - s; | ||
| 88 | while (--siz) | ||
| 89 | *rve++ = '0'; | ||
| 90 | *rve = '\0'; | ||
| 91 | } | ||
| 92 | |||
| 93 | return(s); | ||
| 94 | } | ||
| 95 | |||
| 96 | char * | ||
| 97 | ecvt(double value, int ndigit, int *decpt, int *sign) | ||
| 98 | { | ||
| 99 | return(__cvt(value, ndigit, decpt, sign, 0, 1)); | ||
| 100 | } | ||
| 101 | |||
| 102 | char * | ||
| 103 | fcvt(double value, int ndigit, int *decpt, int *sign) | ||
| 104 | { | ||
| 105 | return(__cvt(value, ndigit, decpt, sign, 1, 1)); | ||
| 106 | } | ||
diff --git a/src/lib/libc/stdlib/erand48.c b/src/lib/libc/stdlib/erand48.c index cc9fbf770c..2ffeaa6e71 100644 --- a/src/lib/libc/stdlib/erand48.c +++ b/src/lib/libc/stdlib/erand48.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: erand48.c,v 1.3 2005/08/08 08:05:36 espie Exp $ */ | ||
| 1 | /* | 2 | /* |
| 2 | * Copyright (c) 1993 Martin Birgmeier | 3 | * Copyright (c) 1993 Martin Birgmeier |
| 3 | * All rights reserved. | 4 | * All rights reserved. |
diff --git a/src/lib/libc/stdlib/exit.3 b/src/lib/libc/stdlib/exit.3 index adb81ffcb4..26922ca7b8 100644 --- a/src/lib/libc/stdlib/exit.3 +++ b/src/lib/libc/stdlib/exit.3 | |||
| @@ -13,11 +13,7 @@ | |||
| 13 | .\" 2. Redistributions in binary form must reproduce the above copyright | 13 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 14 | .\" notice, this list of conditions and the following disclaimer in the | 14 | .\" notice, this list of conditions and the following disclaimer in the |
| 15 | .\" documentation and/or other materials provided with the distribution. | 15 | .\" documentation and/or other materials provided with the distribution. |
| 16 | .\" 3. All advertising materials mentioning features or use of this software | 16 | .\" 3. Neither the name of the University nor the names of its contributors |
| 17 | .\" must display the following acknowledgement: | ||
| 18 | .\" This product includes software developed by the University of | ||
| 19 | .\" California, Berkeley and its contributors. | ||
| 20 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 21 | .\" may be used to endorse or promote products derived from this software | 17 | .\" may be used to endorse or promote products derived from this software |
| 22 | .\" without specific prior written permission. | 18 | .\" without specific prior written permission. |
| 23 | .\" | 19 | .\" |
| @@ -33,22 +29,22 @@ | |||
| 33 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 29 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 34 | .\" SUCH DAMAGE. | 30 | .\" SUCH DAMAGE. |
| 35 | .\" | 31 | .\" |
| 36 | .\" from: @(#)exit.3 6.6 (Berkeley) 6/29/91 | 32 | .\" $OpenBSD: exit.3,v 1.15 2013/07/17 05:42:11 schwarze Exp $ |
| 37 | .\" $Id: exit.3,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $ | ||
| 38 | .\" | 33 | .\" |
| 39 | .Dd June 29, 1991 | 34 | .Dd $Mdocdate: July 17 2013 $ |
| 40 | .Dt EXIT 3 | 35 | .Dt EXIT 3 |
| 41 | .Os | 36 | .Os |
| 42 | .Sh NAME | 37 | .Sh NAME |
| 43 | .Nm exit | 38 | .Nm exit |
| 44 | .Nd perform normal program termination | 39 | .Nd perform normal program termination |
| 45 | .Sh SYNOPSIS | 40 | .Sh SYNOPSIS |
| 46 | .Fd #include <stdlib.h> | 41 | .In stdlib.h |
| 47 | .Ft void | 42 | .Ft void |
| 48 | .Fn exit "int status" | 43 | .Fn exit "int status" |
| 49 | .Sh DESCRIPTION | 44 | .Sh DESCRIPTION |
| 50 | .Fn Exit | 45 | The |
| 51 | terminates a process. | 46 | .Fn exit |
| 47 | function terminates a process. | ||
| 52 | .Pp | 48 | .Pp |
| 53 | Before termination it performs the following functions in the | 49 | Before termination it performs the following functions in the |
| 54 | order listed: | 50 | order listed: |
| @@ -66,19 +62,41 @@ Unlink all files created with the | |||
| 66 | .Xr tmpfile 3 | 62 | .Xr tmpfile 3 |
| 67 | function. | 63 | function. |
| 68 | .El | 64 | .El |
| 65 | .Pp | ||
| 66 | Following this, | ||
| 67 | .Fn exit | ||
| 68 | calls | ||
| 69 | .Xr _exit 2 . | ||
| 70 | Note that typically | ||
| 71 | .Xr _exit 2 | ||
| 72 | only passes the lower 8 bits of | ||
| 73 | .Fa status | ||
| 74 | on to the parent, thus negative values have less meaning. | ||
| 69 | .Sh RETURN VALUES | 75 | .Sh RETURN VALUES |
| 70 | The | 76 | The |
| 71 | .Fn exit | 77 | .Fn exit |
| 72 | function | 78 | function never returns. |
| 73 | never returns. | ||
| 74 | .Sh SEE ALSO | 79 | .Sh SEE ALSO |
| 75 | .Xr _exit 2 , | 80 | .Xr _exit 2 , |
| 76 | .Xr atexit 3 , | 81 | .Xr atexit 3 , |
| 77 | .Xr intro 3 , | 82 | .Xr intro 3 , |
| 83 | .Xr sysexits 3 , | ||
| 78 | .Xr tmpfile 3 | 84 | .Xr tmpfile 3 |
| 79 | .Sh STANDARDS | 85 | .Sh STANDARDS |
| 80 | The | 86 | The |
| 81 | .Fn exit | 87 | .Fn exit |
| 82 | function | 88 | function conforms to |
| 83 | conforms to | 89 | .St -ansiC-99 . |
| 84 | .St -ansiC . | 90 | .Sh HISTORY |
| 91 | An | ||
| 92 | .Fn exit | ||
| 93 | function first appeared as a system call in | ||
| 94 | .At v1 . | ||
| 95 | It has accepted the | ||
| 96 | .Fa status | ||
| 97 | argument since | ||
| 98 | .At v2 . | ||
| 99 | In | ||
| 100 | .At v7 , | ||
| 101 | the bare system call was renamed to | ||
| 102 | .Xr _exit 2 . | ||
diff --git a/src/lib/libc/stdlib/exit.c b/src/lib/libc/stdlib/exit.c index b1412f42bb..83fe3d2de5 100644 --- a/src/lib/libc/stdlib/exit.c +++ b/src/lib/libc/stdlib/exit.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: exit.c,v 1.12 2007/09/03 14:40:16 millert Exp $ */ | ||
| 1 | /*- | 2 | /*- |
| 2 | * Copyright (c) 1990 The Regents of the University of California. | 3 | * Copyright (c) 1990 The Regents of the University of California. |
| 3 | * All rights reserved. | 4 | * All rights reserved. |
| @@ -10,11 +11,7 @@ | |||
| 10 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the |
| 12 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. Neither the name of the University nor the names of its contributors |
| 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 | 15 | * may be used to endorse or promote products derived from this software |
| 19 | * without specific prior written permission. | 16 | * without specific prior written permission. |
| 20 | * | 17 | * |
| @@ -31,31 +28,32 @@ | |||
| 31 | * SUCH DAMAGE. | 28 | * SUCH DAMAGE. |
| 32 | */ | 29 | */ |
| 33 | 30 | ||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | 31 | #include <sys/types.h> |
| 35 | /*static char *sccsid = "from: @(#)exit.c 5.4 (Berkeley) 2/23/91";*/ | 32 | #include <sys/mman.h> |
| 36 | static char *rcsid = "$Id: exit.c,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $"; | ||
| 37 | #endif /* LIBC_SCCS and not lint */ | ||
| 38 | |||
| 39 | #include <stdlib.h> | 33 | #include <stdlib.h> |
| 40 | #include <unistd.h> | 34 | #include <unistd.h> |
| 41 | #include "atexit.h" | 35 | #include "atexit.h" |
| 36 | #include "thread_private.h" | ||
| 42 | 37 | ||
| 43 | void (*__cleanup)(); | 38 | /* |
| 39 | * This variable is zero until a process has created a thread. | ||
| 40 | * It is used to avoid calling locking functions in libc when they | ||
| 41 | * are not required. By default, libc is intended to be(come) | ||
| 42 | * thread-safe, but without a (significant) penalty to non-threaded | ||
| 43 | * processes. | ||
| 44 | */ | ||
| 45 | int __isthreaded = 0; | ||
| 44 | 46 | ||
| 45 | /* | 47 | /* |
| 46 | * Exit, flushing stdio buffers if necessary. | 48 | * Exit, flushing stdio buffers if necessary. |
| 47 | */ | 49 | */ |
| 48 | void | 50 | void |
| 49 | exit(status) | 51 | exit(int status) |
| 50 | int status; | ||
| 51 | { | 52 | { |
| 52 | register struct atexit *p; | 53 | /* |
| 53 | register int n; | 54 | * Call functions registered by atexit() or _cxa_atexit() |
| 54 | 55 | * (including the stdio cleanup routine) and then _exit(). | |
| 55 | for (p = __atexit; p; p = p->next) | 56 | */ |
| 56 | for (n = p->ind; --n >= 0;) | 57 | __cxa_finalize(NULL); |
| 57 | (*p->fns[n])(); | ||
| 58 | if (__cleanup) | ||
| 59 | (*__cleanup)(); | ||
| 60 | _exit(status); | 58 | _exit(status); |
| 61 | } | 59 | } |
diff --git a/src/lib/libc/stdlib/gcvt.c b/src/lib/libc/stdlib/gcvt.c new file mode 100644 index 0000000000..f233332799 --- /dev/null +++ b/src/lib/libc/stdlib/gcvt.c | |||
| @@ -0,0 +1,123 @@ | |||
| 1 | /* $OpenBSD: gcvt.c,v 1.13 2013/11/01 19:05:11 guenther Exp $ */ | ||
| 2 | |||
| 3 | /* | ||
| 4 | * Copyright (c) 2002, 2003, 2006, 2010 | ||
| 5 | * Todd C. Miller <Todd.Miller@courtesan.com> | ||
| 6 | * | ||
| 7 | * Permission to use, copy, modify, and distribute this software for any | ||
| 8 | * purpose with or without fee is hereby granted, provided that the above | ||
| 9 | * copyright notice and this permission notice appear in all copies. | ||
| 10 | * | ||
| 11 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 12 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 13 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 14 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 15 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 16 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 17 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 18 | * | ||
| 19 | * Sponsored in part by the Defense Advanced Research Projects | ||
| 20 | * Agency (DARPA) and Air Force Research Laboratory, Air Force | ||
| 21 | * Materiel Command, USAF, under agreement number F39502-99-1-0512. | ||
| 22 | */ | ||
| 23 | |||
| 24 | #include <locale.h> | ||
| 25 | #include <stdio.h> | ||
| 26 | #include <stdlib.h> | ||
| 27 | #include <string.h> | ||
| 28 | #include "gdtoa.h" | ||
| 29 | |||
| 30 | #define DEFPREC 6 | ||
| 31 | |||
| 32 | char * | ||
| 33 | gcvt(double value, int ndigit, char *buf) | ||
| 34 | { | ||
| 35 | char *digits, *dst, *src; | ||
| 36 | int i, decpt, sign; | ||
| 37 | struct lconv *lconv; | ||
| 38 | |||
| 39 | lconv = localeconv(); | ||
| 40 | if (ndigit <= 0) { | ||
| 41 | /* Match printf(3) behavior. */ | ||
| 42 | ndigit = ndigit ? DEFPREC : 1; | ||
| 43 | } | ||
| 44 | |||
| 45 | digits = __dtoa(value, 2, ndigit, &decpt, &sign, NULL); | ||
| 46 | if (digits == NULL) | ||
| 47 | return (NULL); | ||
| 48 | if (decpt == 9999) { | ||
| 49 | /* | ||
| 50 | * Infinity or NaN, convert to inf or nan with sign. | ||
| 51 | * We can't infer buffer size based on ndigit. | ||
| 52 | * We have to assume it is at least 5 chars. | ||
| 53 | */ | ||
| 54 | snprintf(buf, 5, "%s%s", sign ? "-" : "", | ||
| 55 | *digits == 'I' ? "inf" : "nan"); | ||
| 56 | __freedtoa(digits); | ||
| 57 | return (buf); | ||
| 58 | } | ||
| 59 | |||
| 60 | dst = buf; | ||
| 61 | if (sign) | ||
| 62 | *dst++ = '-'; | ||
| 63 | |||
| 64 | /* Match printf(3) behavior for exponential vs. regular fomatting. */ | ||
| 65 | if (decpt <= -4 || decpt > ndigit) { | ||
| 66 | /* exponential format (e.g. 1.2345e+13) */ | ||
| 67 | if (--decpt < 0) { | ||
| 68 | sign = 1; | ||
| 69 | decpt = -decpt; | ||
| 70 | } else | ||
| 71 | sign = 0; | ||
| 72 | src = digits; | ||
| 73 | *dst++ = *src++; | ||
| 74 | if (*src != '\0') { | ||
| 75 | *dst++ = *lconv->decimal_point; | ||
| 76 | do { | ||
| 77 | *dst++ = *src++; | ||
| 78 | } while (*src != '\0'); | ||
| 79 | } | ||
| 80 | *dst++ = 'e'; | ||
| 81 | if (sign) | ||
| 82 | *dst++ = '-'; | ||
| 83 | else | ||
| 84 | *dst++ = '+'; | ||
| 85 | if (decpt < 10) { | ||
| 86 | *dst++ = '0'; | ||
| 87 | *dst++ = '0' + decpt; | ||
| 88 | *dst = '\0'; | ||
| 89 | } else { | ||
| 90 | /* XXX - optimize */ | ||
| 91 | for (sign = decpt, i = 0; (sign /= 10) != 0; i++) | ||
| 92 | continue; | ||
| 93 | dst[i + 1] = '\0'; | ||
| 94 | while (decpt != 0) { | ||
| 95 | dst[i--] = '0' + decpt % 10; | ||
| 96 | decpt /= 10; | ||
| 97 | } | ||
| 98 | } | ||
| 99 | } else { | ||
| 100 | /* standard format */ | ||
| 101 | for (i = 0, src = digits; i < decpt; i++) { | ||
| 102 | if (*src != '\0') | ||
| 103 | *dst++ = *src++; | ||
| 104 | else | ||
| 105 | *dst++ = '0'; | ||
| 106 | } | ||
| 107 | if (*src != '\0') { | ||
| 108 | if (src == digits) | ||
| 109 | *dst++ = '0'; /* zero before decimal point */ | ||
| 110 | *dst++ = *lconv->decimal_point; | ||
| 111 | while (decpt < 0) { | ||
| 112 | *dst++ = '0'; | ||
| 113 | decpt++; | ||
| 114 | } | ||
| 115 | for (i = decpt; digits[i] != '\0'; i++) { | ||
| 116 | *dst++ = digits[i]; | ||
| 117 | } | ||
| 118 | } | ||
| 119 | *dst = '\0'; | ||
| 120 | } | ||
| 121 | __freedtoa(digits); | ||
| 122 | return (buf); | ||
| 123 | } | ||
diff --git a/src/lib/libc/stdlib/getenv.3 b/src/lib/libc/stdlib/getenv.3 index 411eb35da4..5239d1b0d5 100644 --- a/src/lib/libc/stdlib/getenv.3 +++ b/src/lib/libc/stdlib/getenv.3 | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | .\" Copyright (c) 1988, 1991 The Regents of the University of California. | 1 | .\" Copyright (c) 1988, 1991, 1993 |
| 2 | .\" All rights reserved. | 2 | .\" The Regents of the University of California. All rights reserved. |
| 3 | .\" | 3 | .\" |
| 4 | .\" This code is derived from software contributed to Berkeley by | 4 | .\" This code is derived from software contributed to Berkeley by |
| 5 | .\" the American National Standards Committee X3, on Information | 5 | .\" the American National Standards Committee X3, on Information |
| @@ -13,11 +13,7 @@ | |||
| 13 | .\" 2. Redistributions in binary form must reproduce the above copyright | 13 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 14 | .\" notice, this list of conditions and the following disclaimer in the | 14 | .\" notice, this list of conditions and the following disclaimer in the |
| 15 | .\" documentation and/or other materials provided with the distribution. | 15 | .\" documentation and/or other materials provided with the distribution. |
| 16 | .\" 3. All advertising materials mentioning features or use of this software | 16 | .\" 3. Neither the name of the University nor the names of its contributors |
| 17 | .\" must display the following acknowledgement: | ||
| 18 | .\" This product includes software developed by the University of | ||
| 19 | .\" California, Berkeley and its contributors. | ||
| 20 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 21 | .\" may be used to endorse or promote products derived from this software | 17 | .\" may be used to endorse or promote products derived from this software |
| 22 | .\" without specific prior written permission. | 18 | .\" without specific prior written permission. |
| 23 | .\" | 19 | .\" |
| @@ -33,10 +29,9 @@ | |||
| 33 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 29 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 34 | .\" SUCH DAMAGE. | 30 | .\" SUCH DAMAGE. |
| 35 | .\" | 31 | .\" |
| 36 | .\" from: @(#)getenv.3 6.11 (Berkeley) 6/29/91 | 32 | .\" $OpenBSD: getenv.3,v 1.19 2013/06/05 03:39:23 tedu Exp $ |
| 37 | .\" $Id: getenv.3,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $ | ||
| 38 | .\" | 33 | .\" |
| 39 | .Dd June 29, 1991 | 34 | .Dd $Mdocdate: June 5 2013 $ |
| 40 | .Dt GETENV 3 | 35 | .Dt GETENV 3 |
| 41 | .Os | 36 | .Os |
| 42 | .Sh NAME | 37 | .Sh NAME |
| @@ -46,88 +41,103 @@ | |||
| 46 | .Nm unsetenv | 41 | .Nm unsetenv |
| 47 | .Nd environment variable functions | 42 | .Nd environment variable functions |
| 48 | .Sh SYNOPSIS | 43 | .Sh SYNOPSIS |
| 49 | .Fd #include <stdlib.h> | 44 | .In stdlib.h |
| 50 | .Ft char * | 45 | .Ft char * |
| 51 | .Fn getenv "const char *name" | 46 | .Fn getenv "const char *name" |
| 52 | .Ft int | 47 | .Ft int |
| 53 | .Fn setenv "const char *name" "const char *value" "int overwrite" | 48 | .Fn setenv "const char *name" "const char *value" "int overwrite" |
| 54 | .Ft int | 49 | .Ft int |
| 55 | .Fn putenv "const char *string" | 50 | .Fn putenv "char *string" |
| 56 | .Ft void | 51 | .Ft int |
| 57 | .Fn unsetenv "const char *name" | 52 | .Fn unsetenv "const char *name" |
| 58 | .Sh DESCRIPTION | 53 | .Sh DESCRIPTION |
| 59 | These functions set, unset and fetch environment variables from the | 54 | These functions set, unset, and fetch environment variables from the host |
| 60 | host | ||
| 61 | .Em environment list . | 55 | .Em environment list . |
| 62 | For compatibility with differing environment conventions, | ||
| 63 | the given arguments | ||
| 64 | .Ar name | ||
| 65 | and | ||
| 66 | .Ar value | ||
| 67 | may be appended and prepended, | ||
| 68 | respectively, | ||
| 69 | with an equal sign | ||
| 70 | .Dq Li \&= . | ||
| 71 | .Pp | 56 | .Pp |
| 72 | The | 57 | The |
| 73 | .Fn getenv | 58 | .Fn getenv |
| 74 | function obtains the current value of the environment variable, | 59 | function obtains the current value of the environment variable |
| 75 | .Ar name . | 60 | .Fa name . |
| 76 | If the variable | 61 | If the variable |
| 77 | .Ar name | 62 | .Fa name |
| 78 | is not in the current environment , | 63 | is not in the current environment, a null pointer is returned. |
| 79 | a null pointer is returned. | ||
| 80 | .Pp | 64 | .Pp |
| 81 | The | 65 | The |
| 82 | .Fn setenv | 66 | .Fn setenv |
| 83 | function inserts or resets the environment variable | 67 | function inserts or resets the environment variable |
| 84 | .Ar name | 68 | .Fa name |
| 85 | in the current environment list. | 69 | in the current environment list. |
| 86 | If the variable | 70 | If the variable |
| 87 | .Ar name | 71 | .Fa name |
| 88 | does not exist in the list, | 72 | does not exist in the list, it is inserted with the given |
| 89 | it is inserted with the given | 73 | .Fa value . |
| 90 | .Ar value. | ||
| 91 | If the variable does exist, the argument | 74 | If the variable does exist, the argument |
| 92 | .Ar overwrite | 75 | .Fa overwrite |
| 93 | is tested; if | 76 | is tested; if |
| 94 | .Ar overwrite is | 77 | .Fa overwrite |
| 95 | zero, the | 78 | is zero, the variable is not reset, otherwise it is reset to the given |
| 96 | variable is not reset, otherwise it is reset | 79 | .Fa value . |
| 97 | to the given | ||
| 98 | .Ar value . | ||
| 99 | .Pp | 80 | .Pp |
| 100 | The | 81 | The |
| 101 | .Fn putenv | 82 | .Fn putenv |
| 102 | function takes an argument of the form ``name=value'' and is | 83 | function takes an argument of the form |
| 103 | equivalent to: | 84 | .Ar name Ns = Ns Ar value . |
| 104 | .Bd -literal -offset indent | 85 | The memory pointed to by |
| 105 | setenv(name, value, 1); | 86 | .Ar string |
| 106 | .Ed | 87 | becomes part of the environment and must not be deallocated by the caller. |
| 88 | If the variable already exists, it will be overwritten. | ||
| 89 | A common source of bugs is to pass a | ||
| 90 | .Ar string | ||
| 91 | argument that is a locally scoped string buffer. | ||
| 92 | This will result in corruption of the environment after leaving | ||
| 93 | the scope in which the variable is defined. | ||
| 94 | For this reason, the | ||
| 95 | .Fn setenv | ||
| 96 | function is preferred over | ||
| 97 | .Fn putenv . | ||
| 107 | .Pp | 98 | .Pp |
| 108 | The | 99 | The |
| 109 | .Fn unsetenv | 100 | .Fn unsetenv |
| 110 | function | 101 | function deletes all instances of the variable name pointed to by |
| 111 | deletes all instances of the variable name pointed to by | ||
| 112 | .Fa name | 102 | .Fa name |
| 113 | from the list. | 103 | from the list. |
| 114 | .Sh RETURN VALUES | 104 | .Sh RETURN VALUES |
| 115 | The functions | 105 | These functions |
| 116 | .Fn setenv | ||
| 117 | and | ||
| 118 | .Fn putenv | ||
| 119 | return zero if successful; otherwise the global variable | 106 | return zero if successful; otherwise the global variable |
| 120 | .Va errno | 107 | .Va errno |
| 121 | is set to indicate the error and a | 108 | is set to indicate the error and \-1 is returned. |
| 122 | \-1 is returned. | 109 | .Pp |
| 110 | If | ||
| 111 | .Fn getenv | ||
| 112 | is successful, the string returned should be considered read-only. | ||
| 123 | .Sh ERRORS | 113 | .Sh ERRORS |
| 124 | .Bl -tag -width Er | 114 | .Bl -tag -width Er |
| 115 | .It Bq Er EINVAL | ||
| 116 | The | ||
| 117 | .Fn setenv | ||
| 118 | or | ||
| 119 | .Fn unsetenv | ||
| 120 | function was passed an empty | ||
| 121 | .Ar name | ||
| 122 | or a NULL pointer, or was passed a | ||
| 123 | .Ar name | ||
| 124 | containing an | ||
| 125 | .Sq = | ||
| 126 | character. | ||
| 127 | .Pp | ||
| 128 | The | ||
| 129 | .Fn putenv | ||
| 130 | function was passed a | ||
| 131 | .Ar string | ||
| 132 | that did not contain an | ||
| 133 | .Sq = | ||
| 134 | character. | ||
| 125 | .It Bq Er ENOMEM | 135 | .It Bq Er ENOMEM |
| 126 | The function | 136 | The |
| 127 | .Fn setenv | 137 | .Fn setenv |
| 128 | or | 138 | or |
| 129 | .Fn putenv | 139 | .Fn putenv |
| 130 | failed because they were unable to allocate memory for the environment. | 140 | function failed because it was unable to allocate memory for the environment. |
| 131 | .El | 141 | .El |
| 132 | .Sh SEE ALSO | 142 | .Sh SEE ALSO |
| 133 | .Xr csh 1 , | 143 | .Xr csh 1 , |
| @@ -139,13 +149,26 @@ The | |||
| 139 | .Fn getenv | 149 | .Fn getenv |
| 140 | function conforms to | 150 | function conforms to |
| 141 | .St -ansiC . | 151 | .St -ansiC . |
| 152 | The | ||
| 153 | .Fn putenv , | ||
| 154 | .Fn setenv , | ||
| 155 | and | ||
| 156 | .Fn unsetenv | ||
| 157 | functions conform to | ||
| 158 | .St -p1003.1-2008 . | ||
| 142 | .Sh HISTORY | 159 | .Sh HISTORY |
| 160 | The function | ||
| 161 | .Fn getenv | ||
| 162 | appeared in | ||
| 163 | .At v7 | ||
| 164 | and | ||
| 165 | .Bx 3 . | ||
| 143 | The functions | 166 | The functions |
| 144 | .Fn setenv | 167 | .Fn setenv |
| 145 | and | 168 | and |
| 146 | .Fn unsetenv | 169 | .Fn unsetenv |
| 147 | appeared in | 170 | appeared in |
| 148 | .At v7 . | 171 | .Bx 4.3 Tahoe . |
| 149 | The | 172 | The |
| 150 | .Fn putenv | 173 | .Fn putenv |
| 151 | function appeared in | 174 | function appeared in |
diff --git a/src/lib/libc/stdlib/getenv.c b/src/lib/libc/stdlib/getenv.c index 09d47f2149..fd8482e9e3 100644 --- a/src/lib/libc/stdlib/getenv.c +++ b/src/lib/libc/stdlib/getenv.c | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | /* $OpenBSD: getenv.c,v 1.10 2010/08/23 22:31:50 millert Exp $ */ | ||
| 1 | /* | 2 | /* |
| 2 | * Copyright (c) 1987 Regents of the University of California. | 3 | * Copyright (c) 1987, 1993 |
| 3 | * All rights reserved. | 4 | * The Regents of the University of California. All rights reserved. |
| 4 | * | 5 | * |
| 5 | * Redistribution and use in source and binary forms, with or without | 6 | * Redistribution and use in source and binary forms, with or without |
| 6 | * modification, are permitted provided that the following conditions | 7 | * modification, are permitted provided that the following conditions |
| @@ -10,11 +11,7 @@ | |||
| 10 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the |
| 12 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. Neither the name of the University nor the names of its contributors |
| 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 | 15 | * may be used to endorse or promote products derived from this software |
| 19 | * without specific prior written permission. | 16 | * without specific prior written permission. |
| 20 | * | 17 | * |
| @@ -31,52 +28,54 @@ | |||
| 31 | * SUCH DAMAGE. | 28 | * SUCH DAMAGE. |
| 32 | */ | 29 | */ |
| 33 | 30 | ||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 35 | /*static char *sccsid = "from: @(#)getenv.c 5.8 (Berkeley) 2/23/91";*/ | ||
| 36 | static char *rcsid = "$Id: getenv.c,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $"; | ||
| 37 | #endif /* LIBC_SCCS and not lint */ | ||
| 38 | |||
| 39 | #include <stdlib.h> | 31 | #include <stdlib.h> |
| 40 | #include <string.h> | 32 | #include <string.h> |
| 41 | 33 | ||
| 42 | /* | 34 | char *__findenv(const char *name, int len, int *offset); |
| 43 | * getenv -- | ||
| 44 | * Returns ptr to value associated with name, if any, else NULL. | ||
| 45 | */ | ||
| 46 | char * | ||
| 47 | getenv(name) | ||
| 48 | const char *name; | ||
| 49 | { | ||
| 50 | int offset; | ||
| 51 | char *__findenv(); | ||
| 52 | |||
| 53 | return(__findenv(name, &offset)); | ||
| 54 | } | ||
| 55 | 35 | ||
| 56 | /* | 36 | /* |
| 57 | * __findenv -- | 37 | * __findenv -- |
| 58 | * Returns pointer to value associated with name, if any, else NULL. | 38 | * Returns pointer to value associated with name, if any, else NULL. |
| 39 | * Starts searching within the environmental array at offset. | ||
| 59 | * Sets offset to be the offset of the name/value combination in the | 40 | * Sets offset to be the offset of the name/value combination in the |
| 60 | * environmental array, for use by setenv(3) and unsetenv(3). | 41 | * environmental array, for use by putenv(3), setenv(3) and unsetenv(3). |
| 61 | * Explicitly removes '=' in argument name. | 42 | * Explicitly removes '=' in argument name. |
| 62 | * | 43 | * |
| 63 | * This routine *should* be a static; don't use it. | 44 | * This routine *should* be a static; don't use it. |
| 64 | */ | 45 | */ |
| 65 | char * | 46 | char * |
| 66 | __findenv(name, offset) | 47 | __findenv(const char *name, int len, int *offset) |
| 67 | register char *name; | ||
| 68 | int *offset; | ||
| 69 | { | 48 | { |
| 70 | extern char **environ; | 49 | extern char **environ; |
| 71 | register int len; | 50 | int i; |
| 72 | register char **P, *C; | 51 | const char *np; |
| 52 | char **p, *cp; | ||
| 53 | |||
| 54 | if (name == NULL || environ == NULL) | ||
| 55 | return (NULL); | ||
| 56 | for (p = environ + *offset; (cp = *p) != NULL; ++p) { | ||
| 57 | for (np = name, i = len; i && *cp; i--) | ||
| 58 | if (*cp++ != *np++) | ||
| 59 | break; | ||
| 60 | if (i == 0 && *cp++ == '=') { | ||
| 61 | *offset = p - environ; | ||
| 62 | return (cp); | ||
| 63 | } | ||
| 64 | } | ||
| 65 | return (NULL); | ||
| 66 | } | ||
| 67 | |||
| 68 | /* | ||
| 69 | * getenv -- | ||
| 70 | * Returns ptr to value associated with name, if any, else NULL. | ||
| 71 | */ | ||
| 72 | char * | ||
| 73 | getenv(const char *name) | ||
| 74 | { | ||
| 75 | int offset = 0; | ||
| 76 | const char *np; | ||
| 73 | 77 | ||
| 74 | for (C = name, len = 0; *C && *C != '='; ++C, ++len); | 78 | for (np = name; *np && *np != '='; ++np) |
| 75 | for (P = environ; *P; ++P) | 79 | ; |
| 76 | if (!strncmp(*P, name, len)) | 80 | return (__findenv(name, (int)(np - name), &offset)); |
| 77 | if (*(C = *P + len) == '=') { | ||
| 78 | *offset = P - environ; | ||
| 79 | return(++C); | ||
| 80 | } | ||
| 81 | return(NULL); | ||
| 82 | } | 81 | } |
diff --git a/src/lib/libc/stdlib/getopt.3 b/src/lib/libc/stdlib/getopt.3 index f843881afd..6661e03841 100644 --- a/src/lib/libc/stdlib/getopt.3 +++ b/src/lib/libc/stdlib/getopt.3 | |||
| @@ -9,11 +9,7 @@ | |||
| 9 | .\" 2. Redistributions in binary form must reproduce the above copyright | 9 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 10 | .\" notice, this list of conditions and the following disclaimer in the | 10 | .\" notice, this list of conditions and the following disclaimer in the |
| 11 | .\" documentation and/or other materials provided with the distribution. | 11 | .\" documentation and/or other materials provided with the distribution. |
| 12 | .\" 3. All advertising materials mentioning features or use of this software | 12 | .\" 3. Neither the name of the University nor the names of its contributors |
| 13 | .\" must display the following acknowledgement: | ||
| 14 | .\" This product includes software developed by the University of | ||
| 15 | .\" California, Berkeley and its contributors. | ||
| 16 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 17 | .\" may be used to endorse or promote products derived from this software | 13 | .\" may be used to endorse or promote products derived from this software |
| 18 | .\" without specific prior written permission. | 14 | .\" without specific prior written permission. |
| 19 | .\" | 15 | .\" |
| @@ -29,20 +25,20 @@ | |||
| 29 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 25 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 30 | .\" SUCH DAMAGE. | 26 | .\" SUCH DAMAGE. |
| 31 | .\" | 27 | .\" |
| 32 | .\" @(#)getopt.3 8.4 (Berkeley) 4/19/94 | 28 | .\" $OpenBSD: getopt.3,v 1.44 2014/01/21 03:15:45 schwarze Exp $ |
| 33 | .\" | 29 | .\" |
| 34 | .Dd April 19, 1994 | 30 | .Dd $Mdocdate: January 21 2014 $ |
| 35 | .Dt GETOPT 3 | 31 | .Dt GETOPT 3 |
| 36 | .Os BSD 4.3 | 32 | .Os |
| 37 | .Sh NAME | 33 | .Sh NAME |
| 38 | .Nm getopt | 34 | .Nm getopt |
| 39 | .Nd get option character from command line argument list | 35 | .Nd get option character from command line argument list |
| 40 | .Sh SYNOPSIS | 36 | .Sh SYNOPSIS |
| 41 | .Fd #include <unistd.h> | 37 | .In unistd.h |
| 42 | .Vt extern char *optarg; | 38 | .Vt extern char *optarg; |
| 39 | .Vt extern int opterr; | ||
| 43 | .Vt extern int optind; | 40 | .Vt extern int optind; |
| 44 | .Vt extern int optopt; | 41 | .Vt extern int optopt; |
| 45 | .Vt extern int opterr; | ||
| 46 | .Vt extern int optreset; | 42 | .Vt extern int optreset; |
| 47 | .Ft int | 43 | .Ft int |
| 48 | .Fn getopt "int argc" "char * const *argv" "const char *optstring" | 44 | .Fn getopt "int argc" "char * const *argv" "const char *optstring" |
| @@ -61,20 +57,25 @@ if it has been specified in the string of accepted option characters, | |||
| 61 | .Pp | 57 | .Pp |
| 62 | The option string | 58 | The option string |
| 63 | .Fa optstring | 59 | .Fa optstring |
| 64 | may contain the following elements: individual characters, and | 60 | may contain the following elements: individual characters, |
| 65 | characters followed by a colon to indicate an option argument | 61 | characters followed by a colon, and characters followed by two colons. |
| 66 | is to follow. | 62 | A character followed by a single colon indicates that an argument |
| 63 | is to follow the option on the command line. | ||
| 64 | Two colons indicates that the argument is optional \- this is an | ||
| 65 | extension not covered by POSIX. | ||
| 67 | For example, an option string | 66 | For example, an option string |
| 68 | .Li "\&""x"" | 67 | .Qq x |
| 69 | recognizes an option | 68 | recognizes an option |
| 70 | .Dq Fl x , | 69 | .Fl x , |
| 71 | and an option string | 70 | and an option string |
| 72 | .Li "\&""x:"" | 71 | .Qq Li x: |
| 73 | recognizes an option and argument | 72 | recognizes an option and argument |
| 74 | .Dq Fl x Ar argument . | 73 | .Fl x Ar argument . |
| 75 | It does not matter to | 74 | It does not matter to |
| 76 | .Fn getopt | 75 | .Fn getopt |
| 77 | if a following argument has leading white space. | 76 | if a following argument has leading whitespace; except in the case where |
| 77 | the argument is optional, denoted with two colons, no leading whitespace | ||
| 78 | is permitted. | ||
| 78 | .Pp | 79 | .Pp |
| 79 | On return from | 80 | On return from |
| 80 | .Fn getopt , | 81 | .Fn getopt , |
| @@ -87,23 +88,23 @@ contains the index to the next | |||
| 87 | argument for a subsequent call | 88 | argument for a subsequent call |
| 88 | to | 89 | to |
| 89 | .Fn getopt . | 90 | .Fn getopt . |
| 90 | The variable | ||
| 91 | .Va optopt | ||
| 92 | saves the last | ||
| 93 | .Em known | ||
| 94 | option character returned by | ||
| 95 | .Fn getopt . | ||
| 96 | .Pp | 91 | .Pp |
| 97 | The variable | 92 | The variables |
| 98 | .Va opterr | 93 | .Va opterr |
| 99 | and | 94 | and |
| 100 | .Va optind | 95 | .Va optind |
| 101 | are both initialized to 1. | 96 | are both initialized to 1. |
| 102 | The | 97 | The |
| 103 | .Va optind | 98 | .Va optind |
| 104 | variable may be set to another value before a set of calls to | 99 | variable may be set to another value larger than 0 before a set of calls to |
| 105 | .Fn getopt | 100 | .Fn getopt |
| 106 | in order to skip over more or less argv entries. | 101 | in order to skip over more or less |
| 102 | .Fa argv | ||
| 103 | entries. | ||
| 104 | An | ||
| 105 | .Va optind | ||
| 106 | value of 0 is reserved for compatibility with GNU | ||
| 107 | .Fn getopt . | ||
| 107 | .Pp | 108 | .Pp |
| 108 | In order to use | 109 | In order to use |
| 109 | .Fn getopt | 110 | .Fn getopt |
| @@ -119,101 +120,154 @@ must be reinitialized. | |||
| 119 | .Pp | 120 | .Pp |
| 120 | The | 121 | The |
| 121 | .Fn getopt | 122 | .Fn getopt |
| 122 | function | 123 | function returns \-1 when the argument list is exhausted. |
| 123 | returns \-1 | ||
| 124 | when the argument list is exhausted, or a non-recognized | ||
| 125 | option is encountered. | ||
| 126 | The interpretation of options in the argument list may be cancelled | 124 | The interpretation of options in the argument list may be cancelled |
| 127 | by the option | 125 | by the option |
| 128 | .Ql -- | 126 | .Ql -- |
| 129 | (double dash) which causes | 127 | (double dash) which causes |
| 130 | .Fn getopt | 128 | .Fn getopt |
| 131 | to signal the end of argument processing and returns \-1. | 129 | to signal the end of argument processing and return \-1. |
| 132 | When all options have been processed (i.e., up to the first non-option | 130 | When all options have been processed (i.e., up to the first non-option |
| 133 | argument), | 131 | argument), |
| 134 | .Fn getopt | 132 | .Fn getopt |
| 135 | returns \-1. | 133 | returns \-1. |
| 136 | .Sh DIAGNOSTICS | 134 | .Sh RETURN VALUES |
| 137 | If the | 135 | The |
| 138 | .Fn getopt | 136 | .Fn getopt |
| 139 | function encounters a character not found in the string | 137 | function returns the next known option character in |
| 140 | .Va optarg | 138 | .Fa optstring . |
| 141 | or detects | ||
| 142 | a missing option argument it writes an error message and returns | ||
| 143 | .Ql ? | ||
| 144 | to the | ||
| 145 | .Em stderr . | ||
| 146 | Setting | ||
| 147 | .Va opterr | ||
| 148 | to a zero will disable these error messages. | ||
| 149 | If | 139 | If |
| 150 | .Va optstring | 140 | .Fn getopt |
| 151 | has a leading | 141 | encounters a character not found in |
| 152 | .Ql \&: | 142 | .Fa optstring |
| 153 | then a missing option argument causes a | 143 | or if it detects a missing option argument, |
| 154 | .Ql \&: | 144 | it returns |
| 155 | to be returned in addition to suppressing any error messages. | 145 | .Sq \&? |
| 156 | .Pp | 146 | (question mark). |
| 157 | Option arguments are allowed to begin with | 147 | If |
| 158 | .Dq Li \- ; | 148 | .Fa optstring |
| 159 | this is reasonable but | 149 | has a leading |
| 160 | reduces the amount of error checking possible. | 150 | .Sq \&: |
| 161 | .Sh EXTENSIONS | 151 | then a missing option argument causes |
| 152 | .Sq \&: | ||
| 153 | to be returned instead of | ||
| 154 | .Sq \&? . | ||
| 155 | In either case, the variable | ||
| 156 | .Va optopt | ||
| 157 | is set to the character that caused the error. | ||
| 162 | The | 158 | The |
| 163 | .Va optreset | ||
| 164 | variable was added to make it possible to call the | ||
| 165 | .Fn getopt | 159 | .Fn getopt |
| 166 | function multiple times. | 160 | function returns \-1 when the argument list is exhausted. |
| 167 | This is an extension to the | 161 | .Sh EXAMPLES |
| 168 | .St -p1003.2 | 162 | The following code accepts the options |
| 169 | specification. | 163 | .Fl b |
| 170 | .Sh EXAMPLE | 164 | and |
| 171 | .Bd -literal -compact | 165 | .Fl f Ar argument |
| 172 | extern char *optarg; | 166 | and adjusts |
| 173 | extern int optind; | 167 | .Va argc |
| 168 | and | ||
| 169 | .Va argv | ||
| 170 | after option argument processing has completed. | ||
| 171 | .Bd -literal -offset indent | ||
| 174 | int bflag, ch, fd; | 172 | int bflag, ch, fd; |
| 175 | 173 | ||
| 176 | bflag = 0; | 174 | bflag = 0; |
| 177 | while ((ch = getopt(argc, argv, "bf:")) != -1) | 175 | while ((ch = getopt(argc, argv, "bf:")) != -1) { |
| 178 | switch(ch) { | 176 | switch (ch) { |
| 179 | case 'b': | 177 | case 'b': |
| 180 | bflag = 1; | 178 | bflag = 1; |
| 181 | break; | 179 | break; |
| 182 | case 'f': | 180 | case 'f': |
| 183 | if ((fd = open(optarg, O_RDONLY, 0)) < 0) { | 181 | if ((fd = open(optarg, O_RDONLY, 0)) == -1) |
| 184 | (void)fprintf(stderr, | 182 | err(1, "%s", optarg); |
| 185 | "myname: %s: %s\en", optarg, strerror(errno)); | ||
| 186 | exit(1); | ||
| 187 | } | ||
| 188 | break; | 183 | break; |
| 189 | case '?': | ||
| 190 | default: | 184 | default: |
| 191 | usage(); | 185 | usage(); |
| 186 | /* NOTREACHED */ | ||
| 187 | } | ||
| 192 | } | 188 | } |
| 193 | argc -= optind; | 189 | argc -= optind; |
| 194 | argv += optind; | 190 | argv += optind; |
| 195 | .Ed | 191 | .Ed |
| 196 | .Sh HISTORY | 192 | .Sh DIAGNOSTICS |
| 193 | If the | ||
| 194 | .Fn getopt | ||
| 195 | function encounters a character not found in the string | ||
| 196 | .Fa optstring | ||
| 197 | or detects | ||
| 198 | a missing option argument, it writes an error message to | ||
| 199 | .Em stderr | ||
| 200 | and returns | ||
| 201 | .Ql \&? . | ||
| 202 | Setting | ||
| 203 | .Va opterr | ||
| 204 | to a zero will disable these error messages. | ||
| 205 | If | ||
| 206 | .Fa optstring | ||
| 207 | has a leading | ||
| 208 | .Ql \&: | ||
| 209 | then a missing option argument causes a | ||
| 210 | .Ql \&: | ||
| 211 | to be returned in addition to suppressing any error messages. | ||
| 212 | .Pp | ||
| 213 | Option arguments are allowed to begin with | ||
| 214 | .Ql - ; | ||
| 215 | this is reasonable but reduces the amount of error checking possible. | ||
| 216 | .Sh SEE ALSO | ||
| 217 | .Xr getopt 1 , | ||
| 218 | .Xr getopt_long 3 , | ||
| 219 | .Xr getsubopt 3 | ||
| 220 | .Sh STANDARDS | ||
| 197 | The | 221 | The |
| 198 | .Fn getopt | 222 | .Fn getopt |
| 199 | function appeared | 223 | function implements a superset of the functionality specified by |
| 200 | .Bx 4.3 . | 224 | .St -p1003.1 . |
| 201 | .Sh BUGS | 225 | .Pp |
| 226 | The following extensions are supported: | ||
| 227 | .Bl -tag -width "xxx" | ||
| 228 | .It Li o | ||
| 202 | The | 229 | The |
| 230 | .Va optreset | ||
| 231 | variable was added to make it possible to call the | ||
| 203 | .Fn getopt | 232 | .Fn getopt |
| 204 | function was once specified to return | 233 | function multiple times. |
| 205 | .Dv EOF | 234 | .It Li o |
| 206 | instead of \-1. | 235 | If the |
| 207 | This was changed by | 236 | .Va optind |
| 208 | .St -p1003.2-92 | 237 | variable is set to 0, |
| 209 | to decouple | ||
| 210 | .Fn getopt | 238 | .Fn getopt |
| 211 | from | 239 | will behave as if the |
| 212 | .Pa <stdio.h> . | 240 | .Va optreset |
| 213 | .Pp | 241 | variable has been set. |
| 242 | This is for compatibility with | ||
| 243 | .Tn GNU | ||
| 244 | .Fn getopt . | ||
| 245 | New code should use | ||
| 246 | .Va optreset | ||
| 247 | instead. | ||
| 248 | .It Li o | ||
| 249 | If the first character of | ||
| 250 | .Fa optstring | ||
| 251 | is a plus sign | ||
| 252 | .Pq Ql + , | ||
| 253 | it will be ignored. | ||
| 254 | This is for compatibility with | ||
| 255 | .Tn GNU | ||
| 256 | .Fn getopt . | ||
| 257 | .It Li o | ||
| 258 | If the first character of | ||
| 259 | .Fa optstring | ||
| 260 | is a dash | ||
| 261 | .Pq Ql - , | ||
| 262 | non-options will be returned as arguments to the option character | ||
| 263 | .Ql \e1 . | ||
| 264 | This is for compatibility with | ||
| 265 | .Tn GNU | ||
| 266 | .Fn getopt . | ||
| 267 | .It Li o | ||
| 214 | A single dash | 268 | A single dash |
| 215 | .Dq Li - | 269 | .Pq Ql - |
| 216 | may be specified as an character in | 270 | may be specified as a character in |
| 217 | .Fa optstring , | 271 | .Fa optstring , |
| 218 | however it should | 272 | however it should |
| 219 | .Em never | 273 | .Em never |
| @@ -221,40 +275,90 @@ have an argument associated with it. | |||
| 221 | This allows | 275 | This allows |
| 222 | .Fn getopt | 276 | .Fn getopt |
| 223 | to be used with programs that expect | 277 | to be used with programs that expect |
| 224 | .Dq Li - | 278 | .Ql - |
| 225 | as an option flag. | 279 | as an option flag. |
| 226 | This practice is wrong, and should not be used in any current development. | 280 | This practice is wrong, and should not be used in any current development. |
| 227 | It is provided for backward compatibility | 281 | It is provided for backward compatibility |
| 228 | .Em only . | 282 | .Em only . |
| 283 | Care should be taken not to use | ||
| 284 | .Ql - | ||
| 285 | as the first character in | ||
| 286 | .Fa optstring | ||
| 287 | to avoid a semantic conflict with | ||
| 288 | .Tn GNU | ||
| 289 | .Fn getopt | ||
| 290 | semantics (see above). | ||
| 229 | By default, a single dash causes | 291 | By default, a single dash causes |
| 230 | .Fn getopt | 292 | .Fn getopt |
| 231 | to return \-1. | 293 | to return \-1. |
| 232 | This is, we believe, compatible with System V. | 294 | .El |
| 295 | .Pp | ||
| 296 | Historic | ||
| 297 | .Bx | ||
| 298 | versions of | ||
| 299 | .Fn getopt | ||
| 300 | set | ||
| 301 | .Fa optopt | ||
| 302 | to the last option character processed. | ||
| 303 | However, this conflicts with | ||
| 304 | .St -p1003.1 | ||
| 305 | which stipulates that | ||
| 306 | .Fa optopt | ||
| 307 | be set to the last character that caused an error. | ||
| 308 | .Sh HISTORY | ||
| 309 | The | ||
| 310 | .Fn getopt | ||
| 311 | function appeared in | ||
| 312 | .Bx 4.3 . | ||
| 313 | .Sh BUGS | ||
| 314 | The | ||
| 315 | .Fn getopt | ||
| 316 | function was once specified to return | ||
| 317 | .Dv EOF | ||
| 318 | instead of \-1. | ||
| 319 | This was changed by | ||
| 320 | .St -p1003.2-92 | ||
| 321 | to decouple | ||
| 322 | .Fn getopt | ||
| 323 | from | ||
| 324 | .In stdio.h . | ||
| 233 | .Pp | 325 | .Pp |
| 234 | It is also possible to handle digits as option letters. | 326 | It is possible to handle digits as option letters. |
| 235 | This allows | 327 | This allows |
| 236 | .Fn getopt | 328 | .Fn getopt |
| 237 | to be used with programs that expect a number | 329 | to be used with programs that expect a number |
| 238 | .Pq Dq Li \&-\&3 | 330 | .Pq Dq Li \-3 |
| 239 | as an option. | 331 | as an option. |
| 240 | This practice is wrong, and should not be used in any current development. | 332 | This practice is wrong, and should not be used in any current development. |
| 241 | It is provided for backward compatibility | 333 | It is provided for backward compatibility |
| 242 | .Em only . | 334 | .Em only . |
| 243 | The following code fragment works in most cases. | 335 | The following code fragment works in most cases and can handle mixed |
| 336 | number and letter arguments. | ||
| 244 | .Bd -literal -offset indent | 337 | .Bd -literal -offset indent |
| 245 | int length; | 338 | int aflag = 0, bflag = 0, ch, lastch = '\e0'; |
| 246 | char *p; | 339 | int length = -1, newarg = 1, prevoptind = 1; |
| 247 | 340 | ||
| 248 | while ((c = getopt(argc, argv, "0123456789")) != -1) | 341 | while ((ch = getopt(argc, argv, "0123456789ab")) != -1) { |
| 249 | switch (c) { | 342 | switch (ch) { |
| 250 | case '0': case '1': case '2': case '3': case '4': | 343 | case '0': case '1': case '2': case '3': case '4': |
| 251 | case '5': case '6': case '7': case '8': case '9': | 344 | case '5': case '6': case '7': case '8': case '9': |
| 252 | p = argv[optind - 1]; | 345 | if (newarg || !isdigit(lastch)) |
| 253 | if (p[0] == '-' && p[1] == ch && !p[2]) | 346 | length = 0; |
| 254 | length = atoi(++p); | 347 | else if (length > INT_MAX / 10) |
| 255 | else | 348 | usage(); |
| 256 | length = atoi(argv[optind] + 1); | 349 | length = (length * 10) + (ch - '0'); |
| 257 | break; | 350 | break; |
| 351 | case 'a': | ||
| 352 | aflag = 1; | ||
| 353 | break; | ||
| 354 | case 'b': | ||
| 355 | bflag = 1; | ||
| 356 | break; | ||
| 357 | default: | ||
| 358 | usage(); | ||
| 258 | } | 359 | } |
| 360 | lastch = ch; | ||
| 361 | newarg = optind != prevoptind; | ||
| 362 | prevoptind = optind; | ||
| 259 | } | 363 | } |
| 260 | .Ed | 364 | .Ed |
diff --git a/src/lib/libc/stdlib/getopt.c b/src/lib/libc/stdlib/getopt.c deleted file mode 100644 index 63c5e6a479..0000000000 --- a/src/lib/libc/stdlib/getopt.c +++ /dev/null | |||
| @@ -1,118 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1987, 1993, 1994 | ||
| 3 | * The Regents of the University of California. All rights reserved. | ||
| 4 | * | ||
| 5 | * Redistribution and use in source and binary forms, with or without | ||
| 6 | * modification, are permitted provided that the following conditions | ||
| 7 | * are met: | ||
| 8 | * 1. Redistributions of source code must retain the above copyright | ||
| 9 | * notice, this list of conditions and the following disclaimer. | ||
| 10 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer in the | ||
| 12 | * documentation and/or other materials provided with the distribution. | ||
| 13 | * 3. All advertising materials mentioning features or use of this software | ||
| 14 | * must display the following acknowledgement: | ||
| 15 | * This product includes software developed by the University of | ||
| 16 | * California, Berkeley and its contributors. | ||
| 17 | * 4. Neither the name of the University nor the names of its contributors | ||
| 18 | * may be used to endorse or promote products derived from this software | ||
| 19 | * without specific prior written permission. | ||
| 20 | * | ||
| 21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
| 22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
| 25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 31 | * SUCH DAMAGE. | ||
| 32 | */ | ||
| 33 | |||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 35 | /* static char sccsid[] = "from: @(#)getopt.c 8.2 (Berkeley) 4/2/94"; */ | ||
| 36 | static char *rcsid = "$Id: getopt.c,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $"; | ||
| 37 | #endif /* LIBC_SCCS and not lint */ | ||
| 38 | |||
| 39 | #include <stdio.h> | ||
| 40 | #include <stdlib.h> | ||
| 41 | #include <string.h> | ||
| 42 | |||
| 43 | int opterr = 1, /* if error message should be printed */ | ||
| 44 | optind = 1, /* index into parent argv vector */ | ||
| 45 | optopt, /* character checked for validity */ | ||
| 46 | optreset; /* reset getopt */ | ||
| 47 | char *optarg; /* argument associated with option */ | ||
| 48 | |||
| 49 | #define BADCH (int)'?' | ||
| 50 | #define BADARG (int)':' | ||
| 51 | #define EMSG "" | ||
| 52 | |||
| 53 | /* | ||
| 54 | * getopt -- | ||
| 55 | * Parse argc/argv argument vector. | ||
| 56 | */ | ||
| 57 | int | ||
| 58 | getopt(nargc, nargv, ostr) | ||
| 59 | int nargc; | ||
| 60 | char * const *nargv; | ||
| 61 | const char *ostr; | ||
| 62 | { | ||
| 63 | extern char *__progname; | ||
| 64 | static char *place = EMSG; /* option letter processing */ | ||
| 65 | char *oli; /* option letter list index */ | ||
| 66 | |||
| 67 | if (optreset || !*place) { /* update scanning pointer */ | ||
| 68 | optreset = 0; | ||
| 69 | if (optind >= nargc || *(place = nargv[optind]) != '-') { | ||
| 70 | place = EMSG; | ||
| 71 | return (-1); | ||
| 72 | } | ||
| 73 | if (place[1] && *++place == '-') { /* found "--" */ | ||
| 74 | ++optind; | ||
| 75 | place = EMSG; | ||
| 76 | return (-1); | ||
| 77 | } | ||
| 78 | } /* option letter okay? */ | ||
| 79 | if ((optopt = (int)*place++) == (int)':' || | ||
| 80 | !(oli = strchr(ostr, optopt))) { | ||
| 81 | /* | ||
| 82 | * if the user didn't specify '-' as an option, | ||
| 83 | * assume it means -1. | ||
| 84 | */ | ||
| 85 | if (optopt == (int)'-') | ||
| 86 | return (-1); | ||
| 87 | if (!*place) | ||
| 88 | ++optind; | ||
| 89 | if (opterr && *ostr != ':') | ||
| 90 | (void)fprintf(stderr, | ||
| 91 | "%s: illegal option -- %c\n", __progname, optopt); | ||
| 92 | return (BADCH); | ||
| 93 | } | ||
| 94 | if (*++oli != ':') { /* don't need argument */ | ||
| 95 | optarg = NULL; | ||
| 96 | if (!*place) | ||
| 97 | ++optind; | ||
| 98 | } | ||
| 99 | else { /* need an argument */ | ||
| 100 | if (*place) /* no white space */ | ||
| 101 | optarg = place; | ||
| 102 | else if (nargc <= ++optind) { /* no arg */ | ||
| 103 | place = EMSG; | ||
| 104 | if (*ostr == ':') | ||
| 105 | return (BADARG); | ||
| 106 | if (opterr) | ||
| 107 | (void)fprintf(stderr, | ||
| 108 | "%s: option requires an argument -- %c\n", | ||
| 109 | __progname, optopt); | ||
| 110 | return (BADCH); | ||
| 111 | } | ||
| 112 | else /* white space */ | ||
| 113 | optarg = nargv[optind]; | ||
| 114 | place = EMSG; | ||
| 115 | ++optind; | ||
| 116 | } | ||
| 117 | return (optopt); /* dump back option letter */ | ||
| 118 | } | ||
diff --git a/src/lib/libc/stdlib/getopt_long.3 b/src/lib/libc/stdlib/getopt_long.3 new file mode 100644 index 0000000000..a5973d6c99 --- /dev/null +++ b/src/lib/libc/stdlib/getopt_long.3 | |||
| @@ -0,0 +1,445 @@ | |||
| 1 | .\" $OpenBSD: getopt_long.3,v 1.20 2013/06/05 03:39:23 tedu Exp $ | ||
| 2 | .\" $NetBSD: getopt_long.3,v 1.11 2002/10/02 10:54:19 wiz Exp $ | ||
| 3 | .\" | ||
| 4 | .\" Copyright (c) 1988, 1991, 1993 | ||
| 5 | .\" The Regents of the University of California. All rights reserved. | ||
| 6 | .\" | ||
| 7 | .\" Redistribution and use in source and binary forms, with or without | ||
| 8 | .\" modification, are permitted provided that the following conditions | ||
| 9 | .\" are met: | ||
| 10 | .\" 1. Redistributions of source code must retain the above copyright | ||
| 11 | .\" notice, this list of conditions and the following disclaimer. | ||
| 12 | .\" 2. Redistributions in binary form must reproduce the above copyright | ||
| 13 | .\" notice, this list of conditions and the following disclaimer in the | ||
| 14 | .\" documentation and/or other materials provided with the distribution. | ||
| 15 | .\" 3. Neither the name of the University nor the names of its contributors | ||
| 16 | .\" may be used to endorse or promote products derived from this software | ||
| 17 | .\" without specific prior written permission. | ||
| 18 | .\" | ||
| 19 | .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
| 20 | .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 21 | .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 22 | .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
| 23 | .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 24 | .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 25 | .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 26 | .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 28 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 29 | .\" SUCH DAMAGE. | ||
| 30 | .\" | ||
| 31 | .\" @(#)getopt.3 8.5 (Berkeley) 4/27/95 | ||
| 32 | .\" | ||
| 33 | .Dd $Mdocdate: June 5 2013 $ | ||
| 34 | .Dt GETOPT_LONG 3 | ||
| 35 | .Os | ||
| 36 | .Sh NAME | ||
| 37 | .Nm getopt_long , | ||
| 38 | .Nm getopt_long_only | ||
| 39 | .Nd get long options from command line argument list | ||
| 40 | .Sh SYNOPSIS | ||
| 41 | .In getopt.h | ||
| 42 | .Vt extern char *optarg; | ||
| 43 | .Vt extern int optind; | ||
| 44 | .Vt extern int optopt; | ||
| 45 | .Vt extern int opterr; | ||
| 46 | .Vt extern int optreset; | ||
| 47 | .Ft int | ||
| 48 | .Fn getopt_long "int argc" "char * const *argv" "const char *optstring" "const struct option *longopts" "int *longindex" | ||
| 49 | .Ft int | ||
| 50 | .Fn getopt_long_only "int argc" "char * const *argv" "const char *optstring" "const struct option *longopts" "int *longindex" | ||
| 51 | .Sh DESCRIPTION | ||
| 52 | The | ||
| 53 | .Fn getopt_long | ||
| 54 | function is similar to | ||
| 55 | .Xr getopt 3 | ||
| 56 | but it accepts options in two forms: words and characters. | ||
| 57 | The | ||
| 58 | .Fn getopt_long | ||
| 59 | function provides a superset of the functionality of | ||
| 60 | .Xr getopt 3 . | ||
| 61 | .Fn getopt_long | ||
| 62 | can be used in two ways. | ||
| 63 | In the first way, every long option understood by the program has a | ||
| 64 | corresponding short option, and the option structure is only used to | ||
| 65 | translate from long options to short options. | ||
| 66 | When used in this fashion, | ||
| 67 | .Fn getopt_long | ||
| 68 | behaves identically to | ||
| 69 | .Xr getopt 3 . | ||
| 70 | This is a good way to add long option processing to an existing program | ||
| 71 | with the minimum of rewriting. | ||
| 72 | .Pp | ||
| 73 | In the second mechanism, a long option sets a flag in the | ||
| 74 | .Fa option | ||
| 75 | structure passed, or will store a pointer to the command line argument | ||
| 76 | in the | ||
| 77 | .Fa option | ||
| 78 | structure passed to it for options that take arguments. | ||
| 79 | Additionally, the long option's argument may be specified as a single | ||
| 80 | argument with an equal sign, e.g. | ||
| 81 | .Bd -literal -offset indent | ||
| 82 | $ myprogram --myoption=somevalue | ||
| 83 | .Ed | ||
| 84 | .Pp | ||
| 85 | When a long option is processed, the call to | ||
| 86 | .Fn getopt_long | ||
| 87 | will return 0. | ||
| 88 | For this reason, long option processing without | ||
| 89 | shortcuts is not backwards compatible with | ||
| 90 | .Xr getopt 3 . | ||
| 91 | .Pp | ||
| 92 | It is possible to combine these methods, providing for long options | ||
| 93 | processing with short option equivalents for some options. | ||
| 94 | Less frequently used options would be processed as long options only. | ||
| 95 | .Pp | ||
| 96 | Abbreviated long option names are accepted when | ||
| 97 | .Fn getopt_long | ||
| 98 | processes long options if the abbreviation is unique. | ||
| 99 | An exact match is always preferred for a defined long option. | ||
| 100 | .Pp | ||
| 101 | The | ||
| 102 | .Fn getopt_long | ||
| 103 | call requires an array to be initialized describing the long | ||
| 104 | options. | ||
| 105 | Each element of the array is a structure: | ||
| 106 | .Bd -literal -offset indent | ||
| 107 | struct option { | ||
| 108 | char *name; | ||
| 109 | int has_arg; | ||
| 110 | int *flag; | ||
| 111 | int val; | ||
| 112 | }; | ||
| 113 | .Ed | ||
| 114 | .Pp | ||
| 115 | The | ||
| 116 | .Fa name | ||
| 117 | field should contain the option name without the leading double dash. | ||
| 118 | .Pp | ||
| 119 | The | ||
| 120 | .Fa has_arg | ||
| 121 | field should be one of: | ||
| 122 | .Pp | ||
| 123 | .Bl -tag -width "optional_argument" -compact -offset indent | ||
| 124 | .It Dv no_argument | ||
| 125 | no argument to the option is expected. | ||
| 126 | .It Dv required_argument | ||
| 127 | an argument to the option is required. | ||
| 128 | .It Dv optional_argument | ||
| 129 | an argument to the option may be presented. | ||
| 130 | .El | ||
| 131 | .Pp | ||
| 132 | If | ||
| 133 | .Fa flag | ||
| 134 | is not | ||
| 135 | .Dv NULL , | ||
| 136 | then the integer pointed to by it will be set to the value in the | ||
| 137 | .Fa val | ||
| 138 | field. | ||
| 139 | If the | ||
| 140 | .Fa flag | ||
| 141 | field is | ||
| 142 | .Dv NULL , | ||
| 143 | then the | ||
| 144 | .Fa val | ||
| 145 | field will be returned. | ||
| 146 | Setting | ||
| 147 | .Fa flag | ||
| 148 | to | ||
| 149 | .Dv NULL | ||
| 150 | and setting | ||
| 151 | .Fa val | ||
| 152 | to the corresponding short option will make this function act just | ||
| 153 | like | ||
| 154 | .Xr getopt 3 . | ||
| 155 | .Pp | ||
| 156 | If the | ||
| 157 | .Fa longindex | ||
| 158 | field is not | ||
| 159 | .Dv NULL , | ||
| 160 | then the integer pointed to by it will be set to the index of the long | ||
| 161 | option relative to | ||
| 162 | .Fa longopts . | ||
| 163 | .Pp | ||
| 164 | The last element of the | ||
| 165 | .Fa longopts | ||
| 166 | array has to be filled with zeroes. | ||
| 167 | .Pp | ||
| 168 | The | ||
| 169 | .Fn getopt_long_only | ||
| 170 | function behaves identically to | ||
| 171 | .Fn getopt_long | ||
| 172 | with the exception that long options may start with | ||
| 173 | .Sq - | ||
| 174 | in addition to | ||
| 175 | .Sq -- . | ||
| 176 | If an option starting with | ||
| 177 | .Sq - | ||
| 178 | does not match a long option but does match a single-character option, | ||
| 179 | the single-character option is returned. | ||
| 180 | .Sh RETURN VALUES | ||
| 181 | If the | ||
| 182 | .Fa flag | ||
| 183 | field in | ||
| 184 | .Li struct option | ||
| 185 | is | ||
| 186 | .Dv NULL , | ||
| 187 | .Fn getopt_long | ||
| 188 | and | ||
| 189 | .Fn getopt_long_only | ||
| 190 | return the value specified in the | ||
| 191 | .Fa val | ||
| 192 | field, which is usually just the corresponding short option. | ||
| 193 | If | ||
| 194 | .Fa flag | ||
| 195 | is not | ||
| 196 | .Dv NULL , | ||
| 197 | these functions return 0 and store | ||
| 198 | .Fa val | ||
| 199 | in the location pointed to by | ||
| 200 | .Fa flag . | ||
| 201 | These functions return | ||
| 202 | .Sq \&: | ||
| 203 | if there was a missing option argument, | ||
| 204 | .Sq \&? | ||
| 205 | if the user specified an unknown or ambiguous option, and | ||
| 206 | \-1 when the argument list has been exhausted. | ||
| 207 | .Sh IMPLEMENTATION DIFFERENCES | ||
| 208 | This section describes differences to the GNU implementation | ||
| 209 | found in glibc-2.1.3: | ||
| 210 | .Bl -bullet | ||
| 211 | .It | ||
| 212 | handling of | ||
| 213 | .Ql - | ||
| 214 | within the option string (not the first character): | ||
| 215 | .Bl -tag -width "OpenBSD" | ||
| 216 | .It GNU | ||
| 217 | treats a | ||
| 218 | .Ql - | ||
| 219 | on the command line as a non-argument. | ||
| 220 | .It OpenBSD | ||
| 221 | a | ||
| 222 | .Ql - | ||
| 223 | within the option string matches a | ||
| 224 | .Ql - | ||
| 225 | (single dash) on the command line. | ||
| 226 | This functionality is provided for backward compatibility with | ||
| 227 | programs, such as | ||
| 228 | .Xr su 1 , | ||
| 229 | that use | ||
| 230 | .Ql - | ||
| 231 | as an option flag. | ||
| 232 | This practice is wrong, and should not be used in any current development. | ||
| 233 | .El | ||
| 234 | .It | ||
| 235 | handling of | ||
| 236 | .Ql :: | ||
| 237 | in the option string in the presence of | ||
| 238 | .Ev POSIXLY_CORRECT : | ||
| 239 | .Bl -tag -width "OpenBSD" | ||
| 240 | .It Both | ||
| 241 | GNU and | ||
| 242 | .Ox | ||
| 243 | ignore | ||
| 244 | .Ev POSIXLY_CORRECT | ||
| 245 | here and take | ||
| 246 | .Ql :: | ||
| 247 | to mean the preceding option takes an optional argument. | ||
| 248 | .El | ||
| 249 | .It | ||
| 250 | return value in case of missing argument if first character | ||
| 251 | (after | ||
| 252 | .Ql + | ||
| 253 | or | ||
| 254 | .Ql - ) | ||
| 255 | in the option string is not | ||
| 256 | .Ql \&: : | ||
| 257 | .Bl -tag -width "OpenBSD" | ||
| 258 | .It GNU | ||
| 259 | returns | ||
| 260 | .Ql \&? | ||
| 261 | .It OpenBSD | ||
| 262 | returns | ||
| 263 | .Ql \&: | ||
| 264 | (since | ||
| 265 | .Ox Ns 's | ||
| 266 | .Xr getopt 3 | ||
| 267 | does). | ||
| 268 | .El | ||
| 269 | .It | ||
| 270 | handling of | ||
| 271 | .Ql --a | ||
| 272 | in | ||
| 273 | .Xr getopt 3 : | ||
| 274 | .Bl -tag -width "OpenBSD" | ||
| 275 | .It GNU | ||
| 276 | parses this as option | ||
| 277 | .Ql - , | ||
| 278 | option | ||
| 279 | .Ql a . | ||
| 280 | .It OpenBSD | ||
| 281 | parses this as | ||
| 282 | .Ql -- , | ||
| 283 | and returns \-1 (ignoring the | ||
| 284 | .Ql a ) | ||
| 285 | (because the original | ||
| 286 | .Fn getopt | ||
| 287 | did.) | ||
| 288 | .El | ||
| 289 | .It | ||
| 290 | setting of | ||
| 291 | .Va optopt | ||
| 292 | for long options with | ||
| 293 | .Va flag | ||
| 294 | .No non- Ns Dv NULL : | ||
| 295 | .Bl -tag -width "OpenBSD" | ||
| 296 | .It GNU | ||
| 297 | sets | ||
| 298 | .Va optopt | ||
| 299 | to | ||
| 300 | .Va val . | ||
| 301 | .It OpenBSD | ||
| 302 | sets | ||
| 303 | .Va optopt | ||
| 304 | to 0 (since | ||
| 305 | .Va val | ||
| 306 | would never be returned). | ||
| 307 | .El | ||
| 308 | .It | ||
| 309 | handling of | ||
| 310 | .Ql -W | ||
| 311 | with | ||
| 312 | .Ql W; | ||
| 313 | in the option string in | ||
| 314 | .Xr getopt 3 | ||
| 315 | (not | ||
| 316 | .Fn getopt_long ) : | ||
| 317 | .Bl -tag -width "OpenBSD" | ||
| 318 | .It GNU | ||
| 319 | causes a segmentation fault. | ||
| 320 | .It OpenBSD | ||
| 321 | no special handling is done; | ||
| 322 | .Ql W; | ||
| 323 | is interpreted as two separate options, neither of which take an argument. | ||
| 324 | .El | ||
| 325 | .It | ||
| 326 | setting of | ||
| 327 | .Va optarg | ||
| 328 | for long options without an argument that are invoked via | ||
| 329 | .Ql -W | ||
| 330 | (with | ||
| 331 | .Ql W; | ||
| 332 | in the option string): | ||
| 333 | .Bl -tag -width "OpenBSD" | ||
| 334 | .It GNU | ||
| 335 | sets | ||
| 336 | .Va optarg | ||
| 337 | to the option name (the argument of | ||
| 338 | .Ql -W ) . | ||
| 339 | .It OpenBSD | ||
| 340 | sets | ||
| 341 | .Va optarg | ||
| 342 | to | ||
| 343 | .Dv NULL | ||
| 344 | (the argument of the long option). | ||
| 345 | .El | ||
| 346 | .It | ||
| 347 | handling of | ||
| 348 | .Ql -W | ||
| 349 | with an argument that is not (a prefix to) a known long option | ||
| 350 | (with | ||
| 351 | .Ql W; | ||
| 352 | in the option string): | ||
| 353 | .Bl -tag -width "OpenBSD" | ||
| 354 | .It GNU | ||
| 355 | returns | ||
| 356 | .Ql -W | ||
| 357 | with | ||
| 358 | .Va optarg | ||
| 359 | set to the unknown option. | ||
| 360 | .It OpenBSD | ||
| 361 | treats this as an error (unknown option) and returns | ||
| 362 | .Ql \&? | ||
| 363 | with | ||
| 364 | .Va optopt | ||
| 365 | set to 0 and | ||
| 366 | .Va optarg | ||
| 367 | set to | ||
| 368 | .Dv NULL | ||
| 369 | (as GNU's man page documents). | ||
| 370 | .El | ||
| 371 | .It | ||
| 372 | The error messages are different. | ||
| 373 | .It | ||
| 374 | .Ox | ||
| 375 | does not permute the argument vector at the same points in | ||
| 376 | the calling sequence as GNU does. | ||
| 377 | The aspects normally used by the caller | ||
| 378 | (ordering after \-1 is returned, value of | ||
| 379 | .Va optind | ||
| 380 | relative to current positions) are the same, though. | ||
| 381 | (We do fewer variable swaps.) | ||
| 382 | .El | ||
| 383 | .Sh ENVIRONMENT | ||
| 384 | .Bl -tag -width Ev | ||
| 385 | .It Ev POSIXLY_CORRECT | ||
| 386 | If set, option processing stops when the first non-option is found and | ||
| 387 | a leading | ||
| 388 | .Sq + | ||
| 389 | in the | ||
| 390 | .Ar optstring | ||
| 391 | is ignored. | ||
| 392 | .El | ||
| 393 | .Sh EXAMPLES | ||
| 394 | .Bd -literal | ||
| 395 | int bflag, ch, fd; | ||
| 396 | int daggerset; | ||
| 397 | |||
| 398 | /* options descriptor */ | ||
| 399 | static struct option longopts[] = { | ||
| 400 | { "buffy", no_argument, NULL, 'b' }, | ||
| 401 | { "fluoride", required_argument, NULL, 'f' }, | ||
| 402 | { "daggerset", no_argument, &daggerset, 1 }, | ||
| 403 | { NULL, 0, NULL, 0 } | ||
| 404 | }; | ||
| 405 | |||
| 406 | bflag = 0; | ||
| 407 | while ((ch = getopt_long(argc, argv, "bf:", longopts, NULL)) != -1) | ||
| 408 | switch (ch) { | ||
| 409 | case 'b': | ||
| 410 | bflag = 1; | ||
| 411 | break; | ||
| 412 | case 'f': | ||
| 413 | if ((fd = open(optarg, O_RDONLY, 0)) == -1) | ||
| 414 | err(1, "unable to open %s", optarg); | ||
| 415 | break; | ||
| 416 | case 0: | ||
| 417 | if (daggerset) | ||
| 418 | fprintf(stderr, "Buffy will use her dagger to " | ||
| 419 | "apply fluoride to dracula's teeth\en"); | ||
| 420 | break; | ||
| 421 | default: | ||
| 422 | usage(); | ||
| 423 | /* NOTREACHED */ | ||
| 424 | } | ||
| 425 | argc -= optind; | ||
| 426 | argv += optind; | ||
| 427 | .Ed | ||
| 428 | .Sh SEE ALSO | ||
| 429 | .Xr getopt 3 | ||
| 430 | .Sh HISTORY | ||
| 431 | The | ||
| 432 | .Fn getopt_long | ||
| 433 | and | ||
| 434 | .Fn getopt_long_only | ||
| 435 | functions first appeared in GNU libiberty. | ||
| 436 | This implementation first appeared in | ||
| 437 | .Ox 3.3 . | ||
| 438 | .Sh BUGS | ||
| 439 | The | ||
| 440 | .Ar argv | ||
| 441 | argument is not really | ||
| 442 | .Dv const | ||
| 443 | as its elements may be permuted (unless | ||
| 444 | .Ev POSIXLY_CORRECT | ||
| 445 | is set). | ||
diff --git a/src/lib/libc/stdlib/getopt_long.c b/src/lib/libc/stdlib/getopt_long.c new file mode 100644 index 0000000000..f46cd8bf4e --- /dev/null +++ b/src/lib/libc/stdlib/getopt_long.c | |||
| @@ -0,0 +1,518 @@ | |||
| 1 | /* $OpenBSD: getopt_long.c,v 1.26 2013/06/08 22:47:56 millert Exp $ */ | ||
| 2 | /* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */ | ||
| 3 | |||
| 4 | /* | ||
| 5 | * Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com> | ||
| 6 | * | ||
| 7 | * Permission to use, copy, modify, and distribute this software for any | ||
| 8 | * purpose with or without fee is hereby granted, provided that the above | ||
| 9 | * copyright notice and this permission notice appear in all copies. | ||
| 10 | * | ||
| 11 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 12 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 13 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 14 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 15 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 16 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 17 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 18 | * | ||
| 19 | * Sponsored in part by the Defense Advanced Research Projects | ||
| 20 | * Agency (DARPA) and Air Force Research Laboratory, Air Force | ||
| 21 | * Materiel Command, USAF, under agreement number F39502-99-1-0512. | ||
| 22 | */ | ||
| 23 | /*- | ||
| 24 | * Copyright (c) 2000 The NetBSD Foundation, Inc. | ||
| 25 | * All rights reserved. | ||
| 26 | * | ||
| 27 | * This code is derived from software contributed to The NetBSD Foundation | ||
| 28 | * by Dieter Baron and Thomas Klausner. | ||
| 29 | * | ||
| 30 | * Redistribution and use in source and binary forms, with or without | ||
| 31 | * modification, are permitted provided that the following conditions | ||
| 32 | * are met: | ||
| 33 | * 1. Redistributions of source code must retain the above copyright | ||
| 34 | * notice, this list of conditions and the following disclaimer. | ||
| 35 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 36 | * notice, this list of conditions and the following disclaimer in the | ||
| 37 | * documentation and/or other materials provided with the distribution. | ||
| 38 | * | ||
| 39 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | ||
| 40 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | ||
| 41 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
| 42 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | ||
| 43 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
| 44 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
| 45 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
| 46 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
| 47 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
| 48 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 49 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 50 | */ | ||
| 51 | |||
| 52 | #include <err.h> | ||
| 53 | #include <errno.h> | ||
| 54 | #include <getopt.h> | ||
| 55 | #include <stdlib.h> | ||
| 56 | #include <string.h> | ||
| 57 | |||
| 58 | int opterr = 1; /* if error message should be printed */ | ||
| 59 | int optind = 1; /* index into parent argv vector */ | ||
| 60 | int optopt = '?'; /* character checked for validity */ | ||
| 61 | int optreset; /* reset getopt */ | ||
| 62 | char *optarg; /* argument associated with option */ | ||
| 63 | |||
| 64 | #define PRINT_ERROR ((opterr) && (*options != ':')) | ||
| 65 | |||
| 66 | #define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */ | ||
| 67 | #define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */ | ||
| 68 | #define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */ | ||
| 69 | |||
| 70 | /* return values */ | ||
| 71 | #define BADCH (int)'?' | ||
| 72 | #define BADARG ((*options == ':') ? (int)':' : (int)'?') | ||
| 73 | #define INORDER (int)1 | ||
| 74 | |||
| 75 | #define EMSG "" | ||
| 76 | |||
| 77 | static int getopt_internal(int, char * const *, const char *, | ||
| 78 | const struct option *, int *, int); | ||
| 79 | static int parse_long_options(char * const *, const char *, | ||
| 80 | const struct option *, int *, int, int); | ||
| 81 | static int gcd(int, int); | ||
| 82 | static void permute_args(int, int, int, char * const *); | ||
| 83 | |||
| 84 | static char *place = EMSG; /* option letter processing */ | ||
| 85 | |||
| 86 | /* XXX: set optreset to 1 rather than these two */ | ||
| 87 | static int nonopt_start = -1; /* first non option argument (for permute) */ | ||
| 88 | static int nonopt_end = -1; /* first option after non options (for permute) */ | ||
| 89 | |||
| 90 | /* Error messages */ | ||
| 91 | static const char recargchar[] = "option requires an argument -- %c"; | ||
| 92 | static const char recargstring[] = "option requires an argument -- %s"; | ||
| 93 | static const char ambig[] = "ambiguous option -- %.*s"; | ||
| 94 | static const char noarg[] = "option doesn't take an argument -- %.*s"; | ||
| 95 | static const char illoptchar[] = "unknown option -- %c"; | ||
| 96 | static const char illoptstring[] = "unknown option -- %s"; | ||
| 97 | |||
| 98 | /* | ||
| 99 | * Compute the greatest common divisor of a and b. | ||
| 100 | */ | ||
| 101 | static int | ||
| 102 | gcd(int a, int b) | ||
| 103 | { | ||
| 104 | int c; | ||
| 105 | |||
| 106 | c = a % b; | ||
| 107 | while (c != 0) { | ||
| 108 | a = b; | ||
| 109 | b = c; | ||
| 110 | c = a % b; | ||
| 111 | } | ||
| 112 | |||
| 113 | return (b); | ||
| 114 | } | ||
| 115 | |||
| 116 | /* | ||
| 117 | * Exchange the block from nonopt_start to nonopt_end with the block | ||
| 118 | * from nonopt_end to opt_end (keeping the same order of arguments | ||
| 119 | * in each block). | ||
| 120 | */ | ||
| 121 | static void | ||
| 122 | permute_args(int panonopt_start, int panonopt_end, int opt_end, | ||
| 123 | char * const *nargv) | ||
| 124 | { | ||
| 125 | int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos; | ||
| 126 | char *swap; | ||
| 127 | |||
| 128 | /* | ||
| 129 | * compute lengths of blocks and number and size of cycles | ||
| 130 | */ | ||
| 131 | nnonopts = panonopt_end - panonopt_start; | ||
| 132 | nopts = opt_end - panonopt_end; | ||
| 133 | ncycle = gcd(nnonopts, nopts); | ||
| 134 | cyclelen = (opt_end - panonopt_start) / ncycle; | ||
| 135 | |||
| 136 | for (i = 0; i < ncycle; i++) { | ||
| 137 | cstart = panonopt_end+i; | ||
| 138 | pos = cstart; | ||
| 139 | for (j = 0; j < cyclelen; j++) { | ||
| 140 | if (pos >= panonopt_end) | ||
| 141 | pos -= nnonopts; | ||
| 142 | else | ||
| 143 | pos += nopts; | ||
| 144 | swap = nargv[pos]; | ||
| 145 | /* LINTED const cast */ | ||
| 146 | ((char **) nargv)[pos] = nargv[cstart]; | ||
| 147 | /* LINTED const cast */ | ||
| 148 | ((char **)nargv)[cstart] = swap; | ||
| 149 | } | ||
| 150 | } | ||
| 151 | } | ||
| 152 | |||
| 153 | /* | ||
| 154 | * parse_long_options -- | ||
| 155 | * Parse long options in argc/argv argument vector. | ||
| 156 | * Returns -1 if short_too is set and the option does not match long_options. | ||
| 157 | */ | ||
| 158 | static int | ||
| 159 | parse_long_options(char * const *nargv, const char *options, | ||
| 160 | const struct option *long_options, int *idx, int short_too, int flags) | ||
| 161 | { | ||
| 162 | char *current_argv, *has_equal; | ||
| 163 | size_t current_argv_len; | ||
| 164 | int i, match, exact_match, second_partial_match; | ||
| 165 | |||
| 166 | current_argv = place; | ||
| 167 | match = -1; | ||
| 168 | exact_match = 0; | ||
| 169 | second_partial_match = 0; | ||
| 170 | |||
| 171 | optind++; | ||
| 172 | |||
| 173 | if ((has_equal = strchr(current_argv, '=')) != NULL) { | ||
| 174 | /* argument found (--option=arg) */ | ||
| 175 | current_argv_len = has_equal - current_argv; | ||
| 176 | has_equal++; | ||
| 177 | } else | ||
| 178 | current_argv_len = strlen(current_argv); | ||
| 179 | |||
| 180 | for (i = 0; long_options[i].name; i++) { | ||
| 181 | /* find matching long option */ | ||
| 182 | if (strncmp(current_argv, long_options[i].name, | ||
| 183 | current_argv_len)) | ||
| 184 | continue; | ||
| 185 | |||
| 186 | if (strlen(long_options[i].name) == current_argv_len) { | ||
| 187 | /* exact match */ | ||
| 188 | match = i; | ||
| 189 | exact_match = 1; | ||
| 190 | break; | ||
| 191 | } | ||
| 192 | /* | ||
| 193 | * If this is a known short option, don't allow | ||
| 194 | * a partial match of a single character. | ||
| 195 | */ | ||
| 196 | if (short_too && current_argv_len == 1) | ||
| 197 | continue; | ||
| 198 | |||
| 199 | if (match == -1) /* first partial match */ | ||
| 200 | match = i; | ||
| 201 | else if ((flags & FLAG_LONGONLY) || | ||
| 202 | long_options[i].has_arg != long_options[match].has_arg || | ||
| 203 | long_options[i].flag != long_options[match].flag || | ||
| 204 | long_options[i].val != long_options[match].val) | ||
| 205 | second_partial_match = 1; | ||
| 206 | } | ||
| 207 | if (!exact_match && second_partial_match) { | ||
| 208 | /* ambiguous abbreviation */ | ||
| 209 | if (PRINT_ERROR) | ||
| 210 | warnx(ambig, (int)current_argv_len, current_argv); | ||
| 211 | optopt = 0; | ||
| 212 | return (BADCH); | ||
| 213 | } | ||
| 214 | if (match != -1) { /* option found */ | ||
| 215 | if (long_options[match].has_arg == no_argument | ||
| 216 | && has_equal) { | ||
| 217 | if (PRINT_ERROR) | ||
| 218 | warnx(noarg, (int)current_argv_len, | ||
| 219 | current_argv); | ||
| 220 | /* | ||
| 221 | * XXX: GNU sets optopt to val regardless of flag | ||
| 222 | */ | ||
| 223 | if (long_options[match].flag == NULL) | ||
| 224 | optopt = long_options[match].val; | ||
| 225 | else | ||
| 226 | optopt = 0; | ||
| 227 | return (BADARG); | ||
| 228 | } | ||
| 229 | if (long_options[match].has_arg == required_argument || | ||
| 230 | long_options[match].has_arg == optional_argument) { | ||
| 231 | if (has_equal) | ||
| 232 | optarg = has_equal; | ||
| 233 | else if (long_options[match].has_arg == | ||
| 234 | required_argument) { | ||
| 235 | /* | ||
| 236 | * optional argument doesn't use next nargv | ||
| 237 | */ | ||
| 238 | optarg = nargv[optind++]; | ||
| 239 | } | ||
| 240 | } | ||
| 241 | if ((long_options[match].has_arg == required_argument) | ||
| 242 | && (optarg == NULL)) { | ||
| 243 | /* | ||
| 244 | * Missing argument; leading ':' indicates no error | ||
| 245 | * should be generated. | ||
| 246 | */ | ||
| 247 | if (PRINT_ERROR) | ||
| 248 | warnx(recargstring, | ||
| 249 | current_argv); | ||
| 250 | /* | ||
| 251 | * XXX: GNU sets optopt to val regardless of flag | ||
| 252 | */ | ||
| 253 | if (long_options[match].flag == NULL) | ||
| 254 | optopt = long_options[match].val; | ||
| 255 | else | ||
| 256 | optopt = 0; | ||
| 257 | --optind; | ||
| 258 | return (BADARG); | ||
| 259 | } | ||
| 260 | } else { /* unknown option */ | ||
| 261 | if (short_too) { | ||
| 262 | --optind; | ||
| 263 | return (-1); | ||
| 264 | } | ||
| 265 | if (PRINT_ERROR) | ||
| 266 | warnx(illoptstring, current_argv); | ||
| 267 | optopt = 0; | ||
| 268 | return (BADCH); | ||
| 269 | } | ||
| 270 | if (idx) | ||
| 271 | *idx = match; | ||
| 272 | if (long_options[match].flag) { | ||
| 273 | *long_options[match].flag = long_options[match].val; | ||
| 274 | return (0); | ||
| 275 | } else | ||
| 276 | return (long_options[match].val); | ||
| 277 | } | ||
| 278 | |||
| 279 | /* | ||
| 280 | * getopt_internal -- | ||
| 281 | * Parse argc/argv argument vector. Called by user level routines. | ||
| 282 | */ | ||
| 283 | static int | ||
| 284 | getopt_internal(int nargc, char * const *nargv, const char *options, | ||
| 285 | const struct option *long_options, int *idx, int flags) | ||
| 286 | { | ||
| 287 | char *oli; /* option letter list index */ | ||
| 288 | int optchar, short_too; | ||
| 289 | static int posixly_correct = -1; | ||
| 290 | |||
| 291 | if (options == NULL) | ||
| 292 | return (-1); | ||
| 293 | |||
| 294 | /* | ||
| 295 | * XXX Some GNU programs (like cvs) set optind to 0 instead of | ||
| 296 | * XXX using optreset. Work around this braindamage. | ||
| 297 | */ | ||
| 298 | if (optind == 0) | ||
| 299 | optind = optreset = 1; | ||
| 300 | |||
| 301 | /* | ||
| 302 | * Disable GNU extensions if POSIXLY_CORRECT is set or options | ||
| 303 | * string begins with a '+'. | ||
| 304 | */ | ||
| 305 | if (posixly_correct == -1 || optreset) | ||
| 306 | posixly_correct = (getenv("POSIXLY_CORRECT") != NULL); | ||
| 307 | if (*options == '-') | ||
| 308 | flags |= FLAG_ALLARGS; | ||
| 309 | else if (posixly_correct || *options == '+') | ||
| 310 | flags &= ~FLAG_PERMUTE; | ||
| 311 | if (*options == '+' || *options == '-') | ||
| 312 | options++; | ||
| 313 | |||
| 314 | optarg = NULL; | ||
| 315 | if (optreset) | ||
| 316 | nonopt_start = nonopt_end = -1; | ||
| 317 | start: | ||
| 318 | if (optreset || !*place) { /* update scanning pointer */ | ||
| 319 | optreset = 0; | ||
| 320 | if (optind >= nargc) { /* end of argument vector */ | ||
| 321 | place = EMSG; | ||
| 322 | if (nonopt_end != -1) { | ||
| 323 | /* do permutation, if we have to */ | ||
| 324 | permute_args(nonopt_start, nonopt_end, | ||
| 325 | optind, nargv); | ||
| 326 | optind -= nonopt_end - nonopt_start; | ||
| 327 | } | ||
| 328 | else if (nonopt_start != -1) { | ||
| 329 | /* | ||
| 330 | * If we skipped non-options, set optind | ||
| 331 | * to the first of them. | ||
| 332 | */ | ||
| 333 | optind = nonopt_start; | ||
| 334 | } | ||
| 335 | nonopt_start = nonopt_end = -1; | ||
| 336 | return (-1); | ||
| 337 | } | ||
| 338 | if (*(place = nargv[optind]) != '-' || | ||
| 339 | (place[1] == '\0' && strchr(options, '-') == NULL)) { | ||
| 340 | place = EMSG; /* found non-option */ | ||
| 341 | if (flags & FLAG_ALLARGS) { | ||
| 342 | /* | ||
| 343 | * GNU extension: | ||
| 344 | * return non-option as argument to option 1 | ||
| 345 | */ | ||
| 346 | optarg = nargv[optind++]; | ||
| 347 | return (INORDER); | ||
| 348 | } | ||
| 349 | if (!(flags & FLAG_PERMUTE)) { | ||
| 350 | /* | ||
| 351 | * If no permutation wanted, stop parsing | ||
| 352 | * at first non-option. | ||
| 353 | */ | ||
| 354 | return (-1); | ||
| 355 | } | ||
| 356 | /* do permutation */ | ||
| 357 | if (nonopt_start == -1) | ||
| 358 | nonopt_start = optind; | ||
| 359 | else if (nonopt_end != -1) { | ||
| 360 | permute_args(nonopt_start, nonopt_end, | ||
| 361 | optind, nargv); | ||
| 362 | nonopt_start = optind - | ||
| 363 | (nonopt_end - nonopt_start); | ||
| 364 | nonopt_end = -1; | ||
| 365 | } | ||
| 366 | optind++; | ||
| 367 | /* process next argument */ | ||
| 368 | goto start; | ||
| 369 | } | ||
| 370 | if (nonopt_start != -1 && nonopt_end == -1) | ||
| 371 | nonopt_end = optind; | ||
| 372 | |||
| 373 | /* | ||
| 374 | * If we have "-" do nothing, if "--" we are done. | ||
| 375 | */ | ||
| 376 | if (place[1] != '\0' && *++place == '-' && place[1] == '\0') { | ||
| 377 | optind++; | ||
| 378 | place = EMSG; | ||
| 379 | /* | ||
| 380 | * We found an option (--), so if we skipped | ||
| 381 | * non-options, we have to permute. | ||
| 382 | */ | ||
| 383 | if (nonopt_end != -1) { | ||
| 384 | permute_args(nonopt_start, nonopt_end, | ||
| 385 | optind, nargv); | ||
| 386 | optind -= nonopt_end - nonopt_start; | ||
| 387 | } | ||
| 388 | nonopt_start = nonopt_end = -1; | ||
| 389 | return (-1); | ||
| 390 | } | ||
| 391 | } | ||
| 392 | |||
| 393 | /* | ||
| 394 | * Check long options if: | ||
| 395 | * 1) we were passed some | ||
| 396 | * 2) the arg is not just "-" | ||
| 397 | * 3) either the arg starts with -- we are getopt_long_only() | ||
| 398 | */ | ||
| 399 | if (long_options != NULL && place != nargv[optind] && | ||
| 400 | (*place == '-' || (flags & FLAG_LONGONLY))) { | ||
| 401 | short_too = 0; | ||
| 402 | if (*place == '-') | ||
| 403 | place++; /* --foo long option */ | ||
| 404 | else if (*place != ':' && strchr(options, *place) != NULL) | ||
| 405 | short_too = 1; /* could be short option too */ | ||
| 406 | |||
| 407 | optchar = parse_long_options(nargv, options, long_options, | ||
| 408 | idx, short_too, flags); | ||
| 409 | if (optchar != -1) { | ||
| 410 | place = EMSG; | ||
| 411 | return (optchar); | ||
| 412 | } | ||
| 413 | } | ||
| 414 | |||
| 415 | if ((optchar = (int)*place++) == (int)':' || | ||
| 416 | (optchar == (int)'-' && *place != '\0') || | ||
| 417 | (oli = strchr(options, optchar)) == NULL) { | ||
| 418 | /* | ||
| 419 | * If the user specified "-" and '-' isn't listed in | ||
| 420 | * options, return -1 (non-option) as per POSIX. | ||
| 421 | * Otherwise, it is an unknown option character (or ':'). | ||
| 422 | */ | ||
| 423 | if (optchar == (int)'-' && *place == '\0') | ||
| 424 | return (-1); | ||
| 425 | if (!*place) | ||
| 426 | ++optind; | ||
| 427 | if (PRINT_ERROR) | ||
| 428 | warnx(illoptchar, optchar); | ||
| 429 | optopt = optchar; | ||
| 430 | return (BADCH); | ||
| 431 | } | ||
| 432 | if (long_options != NULL && optchar == 'W' && oli[1] == ';') { | ||
| 433 | /* -W long-option */ | ||
| 434 | if (*place) /* no space */ | ||
| 435 | /* NOTHING */; | ||
| 436 | else if (++optind >= nargc) { /* no arg */ | ||
| 437 | place = EMSG; | ||
| 438 | if (PRINT_ERROR) | ||
| 439 | warnx(recargchar, optchar); | ||
| 440 | optopt = optchar; | ||
| 441 | return (BADARG); | ||
| 442 | } else /* white space */ | ||
| 443 | place = nargv[optind]; | ||
| 444 | optchar = parse_long_options(nargv, options, long_options, | ||
| 445 | idx, 0, flags); | ||
| 446 | place = EMSG; | ||
| 447 | return (optchar); | ||
| 448 | } | ||
| 449 | if (*++oli != ':') { /* doesn't take argument */ | ||
| 450 | if (!*place) | ||
| 451 | ++optind; | ||
| 452 | } else { /* takes (optional) argument */ | ||
| 453 | optarg = NULL; | ||
| 454 | if (*place) /* no white space */ | ||
| 455 | optarg = place; | ||
| 456 | else if (oli[1] != ':') { /* arg not optional */ | ||
| 457 | if (++optind >= nargc) { /* no arg */ | ||
| 458 | place = EMSG; | ||
| 459 | if (PRINT_ERROR) | ||
| 460 | warnx(recargchar, optchar); | ||
| 461 | optopt = optchar; | ||
| 462 | return (BADARG); | ||
| 463 | } else | ||
| 464 | optarg = nargv[optind]; | ||
| 465 | } | ||
| 466 | place = EMSG; | ||
| 467 | ++optind; | ||
| 468 | } | ||
| 469 | /* dump back option letter */ | ||
| 470 | return (optchar); | ||
| 471 | } | ||
| 472 | |||
| 473 | /* | ||
| 474 | * getopt -- | ||
| 475 | * Parse argc/argv argument vector. | ||
| 476 | * | ||
| 477 | * [eventually this will replace the BSD getopt] | ||
| 478 | */ | ||
| 479 | int | ||
| 480 | getopt(int nargc, char * const *nargv, const char *options) | ||
| 481 | { | ||
| 482 | |||
| 483 | /* | ||
| 484 | * We don't pass FLAG_PERMUTE to getopt_internal() since | ||
| 485 | * the BSD getopt(3) (unlike GNU) has never done this. | ||
| 486 | * | ||
| 487 | * Furthermore, since many privileged programs call getopt() | ||
| 488 | * before dropping privileges it makes sense to keep things | ||
| 489 | * as simple (and bug-free) as possible. | ||
| 490 | */ | ||
| 491 | return (getopt_internal(nargc, nargv, options, NULL, NULL, 0)); | ||
| 492 | } | ||
| 493 | |||
| 494 | /* | ||
| 495 | * getopt_long -- | ||
| 496 | * Parse argc/argv argument vector. | ||
| 497 | */ | ||
| 498 | int | ||
| 499 | getopt_long(int nargc, char * const *nargv, const char *options, | ||
| 500 | const struct option *long_options, int *idx) | ||
| 501 | { | ||
| 502 | |||
| 503 | return (getopt_internal(nargc, nargv, options, long_options, idx, | ||
| 504 | FLAG_PERMUTE)); | ||
| 505 | } | ||
| 506 | |||
| 507 | /* | ||
| 508 | * getopt_long_only -- | ||
| 509 | * Parse argc/argv argument vector. | ||
| 510 | */ | ||
| 511 | int | ||
| 512 | getopt_long_only(int nargc, char * const *nargv, const char *options, | ||
| 513 | const struct option *long_options, int *idx) | ||
| 514 | { | ||
| 515 | |||
| 516 | return (getopt_internal(nargc, nargv, options, long_options, idx, | ||
| 517 | FLAG_PERMUTE|FLAG_LONGONLY)); | ||
| 518 | } | ||
diff --git a/src/lib/libc/stdlib/getsubopt.3 b/src/lib/libc/stdlib/getsubopt.3 new file mode 100644 index 0000000000..ef813430de --- /dev/null +++ b/src/lib/libc/stdlib/getsubopt.3 | |||
| @@ -0,0 +1,145 @@ | |||
| 1 | .\" $OpenBSD: getsubopt.3,v 1.13 2013/06/05 03:39:23 tedu Exp $ | ||
| 2 | .\" | ||
| 3 | .\" Copyright (c) 1990, 1991, 1993 | ||
| 4 | .\" The Regents of the University of California. All rights reserved. | ||
| 5 | .\" | ||
| 6 | .\" Redistribution and use in source and binary forms, with or without | ||
| 7 | .\" modification, are permitted provided that the following conditions | ||
| 8 | .\" are met: | ||
| 9 | .\" 1. Redistributions of source code must retain the above copyright | ||
| 10 | .\" notice, this list of conditions and the following disclaimer. | ||
| 11 | .\" 2. Redistributions in binary form must reproduce the above copyright | ||
| 12 | .\" notice, this list of conditions and the following disclaimer in the | ||
| 13 | .\" documentation and/or other materials provided with the distribution. | ||
| 14 | .\" 3. Neither the name of the University nor the names of its contributors | ||
| 15 | .\" may be used to endorse or promote products derived from this software | ||
| 16 | .\" without specific prior written permission. | ||
| 17 | .\" | ||
| 18 | .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
| 19 | .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 20 | .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 21 | .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
| 22 | .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 23 | .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 24 | .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 25 | .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 26 | .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 27 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 28 | .\" SUCH DAMAGE. | ||
| 29 | .\" | ||
| 30 | .\" @(#)getsubopt.3 8.1 (Berkeley) 6/9/93 | ||
| 31 | .\" | ||
| 32 | .Dd $Mdocdate: June 5 2013 $ | ||
| 33 | .Dt GETSUBOPT 3 | ||
| 34 | .Os | ||
| 35 | .Sh NAME | ||
| 36 | .Nm getsubopt | ||
| 37 | .Nd get sub options from an argument | ||
| 38 | .Sh SYNOPSIS | ||
| 39 | .In stdlib.h | ||
| 40 | .Vt extern char *suboptarg; | ||
| 41 | .Ft int | ||
| 42 | .Fn getsubopt "char **optionp" "char * const *tokens" "char **valuep" | ||
| 43 | .Sh DESCRIPTION | ||
| 44 | The | ||
| 45 | .Fn getsubopt | ||
| 46 | function parses a string containing tokens delimited by one or more | ||
| 47 | tab, space, or comma | ||
| 48 | .Pq Ql \&, | ||
| 49 | characters. | ||
| 50 | It is intended for use in parsing groups of option arguments provided | ||
| 51 | as part of a utility command line. | ||
| 52 | .Pp | ||
| 53 | The argument | ||
| 54 | .Fa optionp | ||
| 55 | is a pointer to a pointer to the string. | ||
| 56 | The argument | ||
| 57 | .Fa tokens | ||
| 58 | is a pointer to a null-terminated array of pointers to strings. | ||
| 59 | .Pp | ||
| 60 | The | ||
| 61 | .Fn getsubopt | ||
| 62 | function returns the zero-based offset of the pointer in the | ||
| 63 | .Fa tokens | ||
| 64 | array referencing a string which matches the first token | ||
| 65 | in the string, or \-1 if the string contains no tokens or | ||
| 66 | .Fa tokens | ||
| 67 | does not contain a matching string. | ||
| 68 | .Pp | ||
| 69 | If the token is of the form | ||
| 70 | .Ar name Ns = Ns Ar value , | ||
| 71 | the location referenced by | ||
| 72 | .Fa valuep | ||
| 73 | will be set to point to the start of the | ||
| 74 | .Dq value | ||
| 75 | portion of the token. | ||
| 76 | .Pp | ||
| 77 | On return from | ||
| 78 | .Fn getsubopt , | ||
| 79 | .Fa optionp | ||
| 80 | will be set to point to the start of the next token in the string, | ||
| 81 | or the NUL at the end of the string if no more tokens are present. | ||
| 82 | The external variable | ||
| 83 | .Fa suboptarg | ||
| 84 | will be set to point to the start of the current token, or | ||
| 85 | .Dv NULL | ||
| 86 | if no tokens were present. | ||
| 87 | The argument | ||
| 88 | .Fa valuep | ||
| 89 | will be set to point to the value portion of the token, or | ||
| 90 | .Dv NULL | ||
| 91 | if no value portion was present. | ||
| 92 | .Sh EXAMPLES | ||
| 93 | .Bd -literal | ||
| 94 | char *tokens[] = { | ||
| 95 | #define ONE 0 | ||
| 96 | "one", | ||
| 97 | #define TWO 1 | ||
| 98 | "two", | ||
| 99 | NULL | ||
| 100 | }; | ||
| 101 | |||
| 102 | \&... | ||
| 103 | |||
| 104 | extern char *optarg, *suboptarg; | ||
| 105 | char *options, *value; | ||
| 106 | |||
| 107 | while ((ch = getopt(argc, argv, "ab:")) != -1) { | ||
| 108 | switch (ch) { | ||
| 109 | case 'a': | ||
| 110 | /* process ``a'' option */ | ||
| 111 | break; | ||
| 112 | case 'b': | ||
| 113 | options = optarg; | ||
| 114 | while (*options) { | ||
| 115 | switch (getsubopt(&options, tokens, &value)) { | ||
| 116 | case ONE: | ||
| 117 | /* process ``one'' sub option */ | ||
| 118 | break; | ||
| 119 | case TWO: | ||
| 120 | /* process ``two'' sub option */ | ||
| 121 | if (!value) | ||
| 122 | error("no value for two"); | ||
| 123 | i = atoi(value); | ||
| 124 | break; | ||
| 125 | case -1: | ||
| 126 | if (suboptarg) | ||
| 127 | error("illegal sub option %s", | ||
| 128 | suboptarg); | ||
| 129 | else | ||
| 130 | error("missing sub option"); | ||
| 131 | break; | ||
| 132 | } | ||
| 133 | } | ||
| 134 | break; | ||
| 135 | } | ||
| 136 | } | ||
| 137 | .Ed | ||
| 138 | .Sh SEE ALSO | ||
| 139 | .Xr getopt 3 , | ||
| 140 | .Xr strsep 3 | ||
| 141 | .Sh HISTORY | ||
| 142 | The | ||
| 143 | .Fn getsubopt | ||
| 144 | function first appeared in | ||
| 145 | .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..735c85ba8a --- /dev/null +++ b/src/lib/libc/stdlib/getsubopt.c | |||
| @@ -0,0 +1,92 @@ | |||
| 1 | /* $OpenBSD: getsubopt.c,v 1.4 2005/08/08 08:05:36 espie Exp $ */ | ||
| 2 | |||
| 3 | /*- | ||
| 4 | * Copyright (c) 1990, 1993 | ||
| 5 | * The Regents of the University of California. All rights reserved. | ||
| 6 | * | ||
| 7 | * Redistribution and use in source and binary forms, with or without | ||
| 8 | * modification, are permitted provided that the following conditions | ||
| 9 | * are met: | ||
| 10 | * 1. Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 13 | * notice, this list of conditions and the following disclaimer in the | ||
| 14 | * documentation and/or other materials provided with the distribution. | ||
| 15 | * 3. Neither the name of the University nor the names of its contributors | ||
| 16 | * may be used to endorse or promote products derived from this software | ||
| 17 | * without specific prior written permission. | ||
| 18 | * | ||
| 19 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
| 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
| 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 29 | * SUCH DAMAGE. | ||
| 30 | */ | ||
| 31 | |||
| 32 | #include <unistd.h> | ||
| 33 | #include <stdlib.h> | ||
| 34 | #include <string.h> | ||
| 35 | |||
| 36 | /* | ||
| 37 | * The SVID interface to getsubopt provides no way of figuring out which | ||
| 38 | * part of the suboptions list wasn't matched. This makes error messages | ||
| 39 | * tricky... The extern variable suboptarg is a pointer to the token | ||
| 40 | * which didn't match. | ||
| 41 | */ | ||
| 42 | char *suboptarg; | ||
| 43 | |||
| 44 | int | ||
| 45 | getsubopt(char **optionp, char * const *tokens, char **valuep) | ||
| 46 | { | ||
| 47 | int cnt; | ||
| 48 | char *p; | ||
| 49 | |||
| 50 | suboptarg = *valuep = NULL; | ||
| 51 | |||
| 52 | if (!optionp || !*optionp) | ||
| 53 | return(-1); | ||
| 54 | |||
| 55 | /* skip leading white-space, commas */ | ||
| 56 | for (p = *optionp; *p && (*p == ',' || *p == ' ' || *p == '\t'); ++p); | ||
| 57 | |||
| 58 | if (!*p) { | ||
| 59 | *optionp = p; | ||
| 60 | return(-1); | ||
| 61 | } | ||
| 62 | |||
| 63 | /* save the start of the token, and skip the rest of the token. */ | ||
| 64 | for (suboptarg = p; | ||
| 65 | *++p && *p != ',' && *p != '=' && *p != ' ' && *p != '\t';); | ||
| 66 | |||
| 67 | if (*p) { | ||
| 68 | /* | ||
| 69 | * If there's an equals sign, set the value pointer, and | ||
| 70 | * skip over the value part of the token. Terminate the | ||
| 71 | * token. | ||
| 72 | */ | ||
| 73 | if (*p == '=') { | ||
| 74 | *p = '\0'; | ||
| 75 | for (*valuep = ++p; | ||
| 76 | *p && *p != ',' && *p != ' ' && *p != '\t'; ++p); | ||
| 77 | if (*p) | ||
| 78 | *p++ = '\0'; | ||
| 79 | } else | ||
| 80 | *p++ = '\0'; | ||
| 81 | /* Skip any whitespace or commas after this token. */ | ||
| 82 | for (; *p && (*p == ',' || *p == ' ' || *p == '\t'); ++p); | ||
| 83 | } | ||
| 84 | |||
| 85 | /* set optionp for next round. */ | ||
| 86 | *optionp = p; | ||
| 87 | |||
| 88 | for (cnt = 0; *tokens; ++tokens, ++cnt) | ||
| 89 | if (!strcmp(suboptarg, *tokens)) | ||
| 90 | return(cnt); | ||
| 91 | return(-1); | ||
| 92 | } | ||
diff --git a/src/lib/libc/stdlib/hcreate.3 b/src/lib/libc/stdlib/hcreate.3 new file mode 100644 index 0000000000..ea264b57c8 --- /dev/null +++ b/src/lib/libc/stdlib/hcreate.3 | |||
| @@ -0,0 +1,239 @@ | |||
| 1 | .\" $OpenBSD: hcreate.3,v 1.6 2010/07/28 09:00:20 ray Exp $ | ||
| 2 | .\" $NetBSD: hcreate.3,v 1.8 2010/05/01 06:18:03 jruoho Exp $ | ||
| 3 | .\" | ||
| 4 | .\" Copyright (c) 1999 The NetBSD Foundation, Inc. | ||
| 5 | .\" All rights reserved. | ||
| 6 | .\" | ||
| 7 | .\" This code is derived from software contributed to The NetBSD Foundation | ||
| 8 | .\" by Klaus Klein. | ||
| 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 | .\" | ||
| 19 | .\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | ||
| 20 | .\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | ||
| 21 | .\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
| 22 | .\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | ||
| 23 | .\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
| 24 | .\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
| 25 | .\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
| 26 | .\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
| 27 | .\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
| 28 | .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 29 | .\" POSSIBILITY OF SUCH DAMAGE. | ||
| 30 | .\" | ||
| 31 | .Dd $Mdocdate: July 28 2010 $ | ||
| 32 | .Dt HCREATE 3 | ||
| 33 | .Os | ||
| 34 | .Sh NAME | ||
| 35 | .Nm hcreate , | ||
| 36 | .Nm hdestroy , | ||
| 37 | .Nm hsearch | ||
| 38 | .Nd manage hash search table | ||
| 39 | .Sh SYNOPSIS | ||
| 40 | .In search.h | ||
| 41 | .Ft int | ||
| 42 | .Fn hcreate "size_t nel" | ||
| 43 | .Ft void | ||
| 44 | .Fn hdestroy "void" | ||
| 45 | .Ft ENTRY * | ||
| 46 | .Fn hsearch "ENTRY item" "ACTION action" | ||
| 47 | .Sh DESCRIPTION | ||
| 48 | The | ||
| 49 | .Fn hcreate , | ||
| 50 | .Fn hdestroy , | ||
| 51 | and | ||
| 52 | .Fn hsearch | ||
| 53 | functions manage hash search tables. | ||
| 54 | .Pp | ||
| 55 | The | ||
| 56 | .Fn hcreate | ||
| 57 | function allocates and initializes the table. | ||
| 58 | The | ||
| 59 | .Fa nel | ||
| 60 | argument specifies an estimate of the maximum number of entries to be held | ||
| 61 | by the table. | ||
| 62 | Unless further memory allocation fails, supplying an insufficient | ||
| 63 | .Fa nel | ||
| 64 | value will not result in functional harm, although a performance degradation | ||
| 65 | may occur. | ||
| 66 | Initialization using the | ||
| 67 | .Fn hcreate | ||
| 68 | function is mandatory prior to any access operations using | ||
| 69 | .Fn hsearch . | ||
| 70 | .Pp | ||
| 71 | The | ||
| 72 | .Fn hdestroy | ||
| 73 | function destroys a table previously created using | ||
| 74 | .Fn hcreate . | ||
| 75 | After a call to | ||
| 76 | .Fn hdestroy , | ||
| 77 | the data can no longer be accessed. | ||
| 78 | .Pp | ||
| 79 | The | ||
| 80 | .Fn hsearch | ||
| 81 | function is used to search to the hash table. | ||
| 82 | It returns a pointer into the | ||
| 83 | hash table indicating the address of an item. | ||
| 84 | The | ||
| 85 | .Fa item | ||
| 86 | argument is of type | ||
| 87 | .Vt ENTRY , | ||
| 88 | defined in the | ||
| 89 | .In search.h | ||
| 90 | header. | ||
| 91 | This is a structure type that contains two pointers: | ||
| 92 | .Pp | ||
| 93 | .Bl -tag -compact -offset indent -width "void *data " | ||
| 94 | .It Fa char *key | ||
| 95 | comparison key | ||
| 96 | .It Fa void *data | ||
| 97 | pointer to data associated with | ||
| 98 | .Fa key | ||
| 99 | .El | ||
| 100 | .Pp | ||
| 101 | The key comparison function used by | ||
| 102 | .Fn hsearch | ||
| 103 | is | ||
| 104 | .Xr strcmp 3 . | ||
| 105 | .Pp | ||
| 106 | The | ||
| 107 | .Fa action | ||
| 108 | argument is of type | ||
| 109 | .Vt ACTION , | ||
| 110 | an enumeration type which defines the following values: | ||
| 111 | .Bl -tag -offset indent -width ENTERXX | ||
| 112 | .It Dv ENTER | ||
| 113 | Insert | ||
| 114 | .Fa item | ||
| 115 | into the hash table. | ||
| 116 | If an existing item with the same key is found, it is not replaced. | ||
| 117 | Note that the | ||
| 118 | .Fa key | ||
| 119 | and | ||
| 120 | .Fa data | ||
| 121 | elements of | ||
| 122 | .Fa item | ||
| 123 | are used directly by the new table entry. | ||
| 124 | The storage for the | ||
| 125 | key must not be modified during the lifetime of the hash table. | ||
| 126 | .It Dv FIND | ||
| 127 | Search the hash table without inserting | ||
| 128 | .Fa item . | ||
| 129 | .El | ||
| 130 | .Pp | ||
| 131 | Note that the comparison | ||
| 132 | .Fa key | ||
| 133 | must be allocated using | ||
| 134 | .Xr malloc 3 | ||
| 135 | or | ||
| 136 | .Xr calloc 3 | ||
| 137 | if action is | ||
| 138 | .Dv ENTER | ||
| 139 | and | ||
| 140 | .Fn hdestroy | ||
| 141 | will be called. | ||
| 142 | This is because | ||
| 143 | .Fn hdestroy | ||
| 144 | will call | ||
| 145 | .Xr free 3 | ||
| 146 | for each comparison | ||
| 147 | .Fa key | ||
| 148 | (but not | ||
| 149 | .Fa data ) . | ||
| 150 | Typically the comparison | ||
| 151 | .Fa key | ||
| 152 | is allocated by using | ||
| 153 | .Xr strdup 3 . | ||
| 154 | .Sh RETURN VALUES | ||
| 155 | If successful, the | ||
| 156 | .Fn hcreate | ||
| 157 | function returns a non-zero value. | ||
| 158 | Otherwise, a value of 0 is returned and | ||
| 159 | .Va errno | ||
| 160 | is set to indicate the error. | ||
| 161 | .Pp | ||
| 162 | The | ||
| 163 | .Fn hdestroy | ||
| 164 | functions | ||
| 165 | returns no value. | ||
| 166 | .Pp | ||
| 167 | If successful, the | ||
| 168 | .Fn hsearch | ||
| 169 | function returns a pointer to a hash table entry matching | ||
| 170 | the provided key. | ||
| 171 | If the action is | ||
| 172 | .Dv FIND | ||
| 173 | and the item was not found, or if the action is | ||
| 174 | .Dv ENTER | ||
| 175 | and the insertion failed, | ||
| 176 | .Dv NULL | ||
| 177 | is returned and | ||
| 178 | .Va errno | ||
| 179 | is set to indicate the error. | ||
| 180 | If the action is | ||
| 181 | .Dv ENTER | ||
| 182 | and an entry already existed in the table matching the given | ||
| 183 | key, the existing entry is returned and is not replaced. | ||
| 184 | .Sh ERRORS | ||
| 185 | The | ||
| 186 | .Fn hcreate | ||
| 187 | and | ||
| 188 | .Fn hsearch | ||
| 189 | functions will fail if: | ||
| 190 | .Bl -tag -width Er | ||
| 191 | .It Bq Er ENOMEM | ||
| 192 | Insufficient memory is available. | ||
| 193 | .El | ||
| 194 | .Sh SEE ALSO | ||
| 195 | .Xr bsearch 3 , | ||
| 196 | .Xr lsearch 3 , | ||
| 197 | .Xr malloc 3 , | ||
| 198 | .Xr strcmp 3 | ||
| 199 | .Sh STANDARDS | ||
| 200 | The | ||
| 201 | .Fn hcreate , | ||
| 202 | .Fn hdestroy | ||
| 203 | and | ||
| 204 | .Fn hsearch | ||
| 205 | functions conform to | ||
| 206 | .St -xpg4.2 . | ||
| 207 | .Sh HISTORY | ||
| 208 | The | ||
| 209 | .Fn hcreate , | ||
| 210 | .Fn hdestroy | ||
| 211 | and | ||
| 212 | .Fn hsearch | ||
| 213 | functions first appeared in | ||
| 214 | .At V . | ||
| 215 | .Sh CAVEATS | ||
| 216 | At least the following limitations can be mentioned: | ||
| 217 | .Bl -bullet | ||
| 218 | .It | ||
| 219 | The interface permits the use of only one hash table at a time. | ||
| 220 | .It | ||
| 221 | Individual hash table entries can be added, but not deleted. | ||
| 222 | .It | ||
| 223 | The standard is indecipherable about the | ||
| 224 | internal memory usage of the functions, | ||
| 225 | mentioning only that | ||
| 226 | .Do | ||
| 227 | .Fn hcreate | ||
| 228 | and | ||
| 229 | .Fn hsearch | ||
| 230 | functions may use | ||
| 231 | .Fn malloc | ||
| 232 | to allocate space | ||
| 233 | .Dc . | ||
| 234 | This limits the portability of the functions, | ||
| 235 | given that other implementations may not | ||
| 236 | .Xr free 3 | ||
| 237 | the buffer pointed by | ||
| 238 | .Fa key . | ||
| 239 | .El | ||
diff --git a/src/lib/libc/stdlib/hcreate.c b/src/lib/libc/stdlib/hcreate.c new file mode 100644 index 0000000000..094f32c173 --- /dev/null +++ b/src/lib/libc/stdlib/hcreate.c | |||
| @@ -0,0 +1,191 @@ | |||
| 1 | /* $OpenBSD: hcreate.c,v 1.4 2007/09/02 15:19:17 deraadt Exp $ */ | ||
| 2 | /* $NetBSD: hcreate.c,v 1.5 2004/04/23 02:48:12 simonb Exp $ */ | ||
| 3 | |||
| 4 | /* | ||
| 5 | * Copyright (c) 2001 Christopher G. Demetriou | ||
| 6 | * All rights reserved. | ||
| 7 | * | ||
| 8 | * Redistribution and use in source and binary forms, with or without | ||
| 9 | * modification, are permitted provided that the following conditions | ||
| 10 | * are met: | ||
| 11 | * 1. Redistributions of source code must retain the above copyright | ||
| 12 | * notice, this list of conditions and the following disclaimer. | ||
| 13 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in the | ||
| 15 | * documentation and/or other materials provided with the distribution. | ||
| 16 | * 3. All advertising materials mentioning features or use of this software | ||
| 17 | * must display the following acknowledgement: | ||
| 18 | * This product includes software developed for the | ||
| 19 | * NetBSD Project. See http://www.NetBSD.org/ for | ||
| 20 | * information about NetBSD. | ||
| 21 | * 4. The name of the author may not be used to endorse or promote products | ||
| 22 | * derived from this software without specific prior written permission. | ||
| 23 | * | ||
| 24 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | ||
| 25 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
| 26 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
| 27 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 28 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
| 29 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
| 30 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
| 31 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| 32 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
| 33 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 34 | * | ||
| 35 | * <<Id: LICENSE,v 1.2 2000/06/14 15:57:33 cgd Exp>> | ||
| 36 | */ | ||
| 37 | |||
| 38 | /* | ||
| 39 | * hcreate() / hsearch() / hdestroy() | ||
| 40 | * | ||
| 41 | * SysV/XPG4 hash table functions. | ||
| 42 | * | ||
| 43 | * Implementation done based on NetBSD manual page and Solaris manual page, | ||
| 44 | * plus my own personal experience about how they're supposed to work. | ||
| 45 | * | ||
| 46 | * I tried to look at Knuth (as cited by the Solaris manual page), but | ||
| 47 | * nobody had a copy in the office, so... | ||
| 48 | */ | ||
| 49 | |||
| 50 | #include "namespace.h" | ||
| 51 | #include <assert.h> | ||
| 52 | #include <errno.h> | ||
| 53 | #include <inttypes.h> | ||
| 54 | #include <search.h> | ||
| 55 | #include <stdlib.h> | ||
| 56 | #include <string.h> | ||
| 57 | #include <sys/queue.h> | ||
| 58 | |||
| 59 | #ifndef _DIAGASSERT | ||
| 60 | #define _DIAGASSERT(x) | ||
| 61 | #endif | ||
| 62 | |||
| 63 | /* | ||
| 64 | * DO NOT MAKE THIS STRUCTURE LARGER THAN 32 BYTES (4 ptrs on 64-bit | ||
| 65 | * ptr machine) without adjusting MAX_BUCKETS_LG2 below. | ||
| 66 | */ | ||
| 67 | struct internal_entry { | ||
| 68 | SLIST_ENTRY(internal_entry) link; | ||
| 69 | ENTRY ent; | ||
| 70 | }; | ||
| 71 | SLIST_HEAD(internal_head, internal_entry); | ||
| 72 | |||
| 73 | #define MIN_BUCKETS_LG2 4 | ||
| 74 | #define MIN_BUCKETS (1 << MIN_BUCKETS_LG2) | ||
| 75 | |||
| 76 | /* | ||
| 77 | * max * sizeof internal_entry must fit into size_t. | ||
| 78 | * assumes internal_entry is <= 32 (2^5) bytes. | ||
| 79 | */ | ||
| 80 | #define MAX_BUCKETS_LG2 (sizeof (size_t) * 8 - 1 - 5) | ||
| 81 | #define MAX_BUCKETS ((size_t)1 << MAX_BUCKETS_LG2) | ||
| 82 | |||
| 83 | /* Default hash function, from db/hash/hash_func.c */ | ||
| 84 | extern u_int32_t (*__default_hash)(const void *, size_t); | ||
| 85 | |||
| 86 | static struct internal_head *htable; | ||
| 87 | static size_t htablesize; | ||
| 88 | |||
| 89 | int | ||
| 90 | hcreate(size_t nel) | ||
| 91 | { | ||
| 92 | size_t idx; | ||
| 93 | unsigned int p2; | ||
| 94 | |||
| 95 | /* Make sure this isn't called when a table already exists. */ | ||
| 96 | _DIAGASSERT(htable == NULL); | ||
| 97 | if (htable != NULL) { | ||
| 98 | errno = EINVAL; | ||
| 99 | return 0; | ||
| 100 | } | ||
| 101 | |||
| 102 | /* If nel is too small, make it min sized. */ | ||
| 103 | if (nel < MIN_BUCKETS) | ||
| 104 | nel = MIN_BUCKETS; | ||
| 105 | |||
| 106 | /* If it's too large, cap it. */ | ||
| 107 | if (nel > MAX_BUCKETS) | ||
| 108 | nel = MAX_BUCKETS; | ||
| 109 | |||
| 110 | /* If it's is not a power of two in size, round up. */ | ||
| 111 | if ((nel & (nel - 1)) != 0) { | ||
| 112 | for (p2 = 0; nel != 0; p2++) | ||
| 113 | nel >>= 1; | ||
| 114 | _DIAGASSERT(p2 <= MAX_BUCKETS_LG2); | ||
| 115 | nel = 1 << p2; | ||
| 116 | } | ||
| 117 | |||
| 118 | /* Allocate the table. */ | ||
| 119 | htablesize = nel; | ||
| 120 | htable = calloc(htablesize, sizeof htable[0]); | ||
| 121 | if (htable == NULL) { | ||
| 122 | errno = ENOMEM; | ||
| 123 | return 0; | ||
| 124 | } | ||
| 125 | |||
| 126 | /* Initialize it. */ | ||
| 127 | for (idx = 0; idx < htablesize; idx++) | ||
| 128 | SLIST_INIT(&htable[idx]); | ||
| 129 | |||
| 130 | return 1; | ||
| 131 | } | ||
| 132 | |||
| 133 | void | ||
| 134 | hdestroy(void) | ||
| 135 | { | ||
| 136 | struct internal_entry *ie; | ||
| 137 | size_t idx; | ||
| 138 | |||
| 139 | _DIAGASSERT(htable != NULL); | ||
| 140 | if (htable == NULL) | ||
| 141 | return; | ||
| 142 | |||
| 143 | for (idx = 0; idx < htablesize; idx++) { | ||
| 144 | while (!SLIST_EMPTY(&htable[idx])) { | ||
| 145 | ie = SLIST_FIRST(&htable[idx]); | ||
| 146 | SLIST_REMOVE_HEAD(&htable[idx], link); | ||
| 147 | free(ie->ent.key); | ||
| 148 | free(ie); | ||
| 149 | } | ||
| 150 | } | ||
| 151 | free(htable); | ||
| 152 | htable = NULL; | ||
| 153 | } | ||
| 154 | |||
| 155 | ENTRY * | ||
| 156 | hsearch(ENTRY item, ACTION action) | ||
| 157 | { | ||
| 158 | struct internal_head *head; | ||
| 159 | struct internal_entry *ie; | ||
| 160 | uint32_t hashval; | ||
| 161 | size_t len; | ||
| 162 | |||
| 163 | _DIAGASSERT(htable != NULL); | ||
| 164 | _DIAGASSERT(item.key != NULL); | ||
| 165 | _DIAGASSERT(action == ENTER || action == FIND); | ||
| 166 | |||
| 167 | len = strlen(item.key); | ||
| 168 | hashval = (*__default_hash)(item.key, len); | ||
| 169 | |||
| 170 | head = &htable[hashval & (htablesize - 1)]; | ||
| 171 | ie = SLIST_FIRST(head); | ||
| 172 | while (ie != NULL) { | ||
| 173 | if (strcmp(ie->ent.key, item.key) == 0) | ||
| 174 | break; | ||
| 175 | ie = SLIST_NEXT(ie, link); | ||
| 176 | } | ||
| 177 | |||
| 178 | if (ie != NULL) | ||
| 179 | return &ie->ent; | ||
| 180 | else if (action == FIND) | ||
| 181 | return NULL; | ||
| 182 | |||
| 183 | ie = malloc(sizeof *ie); | ||
| 184 | if (ie == NULL) | ||
| 185 | return NULL; | ||
| 186 | ie->ent.key = item.key; | ||
| 187 | ie->ent.data = item.data; | ||
| 188 | |||
| 189 | SLIST_INSERT_HEAD(head, ie, link); | ||
| 190 | return &ie->ent; | ||
| 191 | } | ||
diff --git a/src/lib/libc/stdlib/heapsort.c b/src/lib/libc/stdlib/heapsort.c index bd998fa357..ad3fffbcd9 100644 --- a/src/lib/libc/stdlib/heapsort.c +++ b/src/lib/libc/stdlib/heapsort.c | |||
| @@ -13,11 +13,7 @@ | |||
| 13 | * 2. Redistributions in binary form must reproduce the above copyright | 13 | * 2. Redistributions in binary form must reproduce the above copyright |
| 14 | * notice, this list of conditions and the following disclaimer in the | 14 | * notice, this list of conditions and the following disclaimer in the |
| 15 | * documentation and/or other materials provided with the distribution. | 15 | * documentation and/or other materials provided with the distribution. |
| 16 | * 3. All advertising materials mentioning features or use of this software | 16 | * 3. Neither the name of the University nor the names of its contributors |
| 17 | * must display the following acknowledgement: | ||
| 18 | * This product includes software developed by the University of | ||
| 19 | * California, Berkeley and its contributors. | ||
| 20 | * 4. Neither the name of the University nor the names of its contributors | ||
| 21 | * may be used to endorse or promote products derived from this software | 17 | * may be used to endorse or promote products derived from this software |
| 22 | * without specific prior written permission. | 18 | * without specific prior written permission. |
| 23 | * | 19 | * |
| @@ -34,11 +30,6 @@ | |||
| 34 | * SUCH DAMAGE. | 30 | * SUCH DAMAGE. |
| 35 | */ | 31 | */ |
| 36 | 32 | ||
| 37 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 38 | /*static char sccsid[] = "from: @(#)heapsort.c 8.1 (Berkeley) 6/4/93";*/ | ||
| 39 | static char *rcsid = "$Id: heapsort.c,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $"; | ||
| 40 | #endif /* LIBC_SCCS and not lint */ | ||
| 41 | |||
| 42 | #include <sys/types.h> | 33 | #include <sys/types.h> |
| 43 | #include <errno.h> | 34 | #include <errno.h> |
| 44 | #include <stdlib.h> | 35 | #include <stdlib.h> |
| @@ -73,7 +64,7 @@ static char *rcsid = "$Id: heapsort.c,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp | |||
| 73 | * Build the list into a heap, where a heap is defined such that for | 64 | * Build the list into a heap, where a heap is defined such that for |
| 74 | * the records K1 ... KN, Kj/2 >= Kj for 1 <= j/2 <= j <= N. | 65 | * the records K1 ... KN, Kj/2 >= Kj for 1 <= j/2 <= j <= N. |
| 75 | * | 66 | * |
| 76 | * There two cases. If j == nmemb, select largest of Ki and Kj. If | 67 | * There are two cases. If j == nmemb, select largest of Ki and Kj. If |
| 77 | * j < nmemb, select largest of Ki, Kj and Kj+1. | 68 | * j < nmemb, select largest of Ki, Kj and Kj+1. |
| 78 | */ | 69 | */ |
| 79 | #define CREATE(initval, nmemb, par_i, child_i, par, child, size, count, tmp) { \ | 70 | #define CREATE(initval, nmemb, par_i, child_i, par, child, size, count, tmp) { \ |
| @@ -95,12 +86,12 @@ static char *rcsid = "$Id: heapsort.c,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp | |||
| 95 | * Select the top of the heap and 'heapify'. Since by far the most expensive | 86 | * Select the top of the heap and 'heapify'. Since by far the most expensive |
| 96 | * action is the call to the compar function, a considerable optimization | 87 | * action is the call to the compar function, a considerable optimization |
| 97 | * in the average case can be achieved due to the fact that k, the displaced | 88 | * in the average case can be achieved due to the fact that k, the displaced |
| 98 | * elememt, is ususally quite small, so it would be preferable to first | 89 | * element, is usually quite small, so it would be preferable to first |
| 99 | * heapify, always maintaining the invariant that the larger child is copied | 90 | * heapify, always maintaining the invariant that the larger child is copied |
| 100 | * over its parent's record. | 91 | * over its parent's record. |
| 101 | * | 92 | * |
| 102 | * Then, starting from the *bottom* of the heap, finding k's correct place, | 93 | * Then, starting from the *bottom* of the heap, finding k's correct place, |
| 103 | * again maintianing the invariant. As a result of the invariant no element | 94 | * again maintaining the invariant. As a result of the invariant no element |
| 104 | * is 'lost' when k is assigned its correct place in the heap. | 95 | * is 'lost' when k is assigned its correct place in the heap. |
| 105 | * | 96 | * |
| 106 | * The time savings from this optimization are on the order of 15-20% for the | 97 | * The time savings from this optimization are on the order of 15-20% for the |
| @@ -139,13 +130,11 @@ static char *rcsid = "$Id: heapsort.c,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp | |||
| 139 | * only advantage over quicksort is that it requires little additional memory. | 130 | * only advantage over quicksort is that it requires little additional memory. |
| 140 | */ | 131 | */ |
| 141 | int | 132 | int |
| 142 | heapsort(vbase, nmemb, size, compar) | 133 | heapsort(void *vbase, size_t nmemb, size_t size, |
| 143 | void *vbase; | 134 | int (*compar)(const void *, const void *)) |
| 144 | size_t nmemb, size; | ||
| 145 | int (*compar) __P((const void *, const void *)); | ||
| 146 | { | 135 | { |
| 147 | register int cnt, i, j, l; | 136 | size_t cnt, i, j, l; |
| 148 | register char tmp, *tmp1, *tmp2; | 137 | char tmp, *tmp1, *tmp2; |
| 149 | char *base, *k, *p, *t; | 138 | char *base, *k, *p, *t; |
| 150 | 139 | ||
| 151 | if (nmemb <= 1) | 140 | if (nmemb <= 1) |
diff --git a/src/lib/libc/stdlib/calloc.3 b/src/lib/libc/stdlib/imaxabs.3 index d0754b46a0..6c4793477e 100644 --- a/src/lib/libc/stdlib/calloc.3 +++ b/src/lib/libc/stdlib/imaxabs.3 | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | .\" Copyright (c) 1991 The Regents of the University of California. | 1 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. |
| 2 | .\" All rights reserved. | 2 | .\" All rights reserved. |
| 3 | .\" | 3 | .\" |
| 4 | .\" This code is derived from software contributed to Berkeley by | 4 | .\" This code is derived from software contributed to Berkeley by |
| @@ -13,11 +13,7 @@ | |||
| 13 | .\" 2. Redistributions in binary form must reproduce the above copyright | 13 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 14 | .\" notice, this list of conditions and the following disclaimer in the | 14 | .\" notice, this list of conditions and the following disclaimer in the |
| 15 | .\" documentation and/or other materials provided with the distribution. | 15 | .\" documentation and/or other materials provided with the distribution. |
| 16 | .\" 3. All advertising materials mentioning features or use of this software | 16 | .\" 3. Neither the name of the University nor the names of its contributors |
| 17 | .\" must display the following acknowledgement: | ||
| 18 | .\" This product includes software developed by the University of | ||
| 19 | .\" California, Berkeley and its contributors. | ||
| 20 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 21 | .\" may be used to endorse or promote products derived from this software | 17 | .\" may be used to endorse or promote products derived from this software |
| 22 | .\" without specific prior written permission. | 18 | .\" without specific prior written permission. |
| 23 | .\" | 19 | .\" |
| @@ -33,39 +29,37 @@ | |||
| 33 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 29 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 34 | .\" SUCH DAMAGE. | 30 | .\" SUCH DAMAGE. |
| 35 | .\" | 31 | .\" |
| 36 | .\" from: @(#)calloc.3 5.2 (Berkeley) 6/29/91 | 32 | .\" $OpenBSD: imaxabs.3,v 1.6 2013/06/05 03:39:23 tedu Exp $ |
| 37 | .\" $Id: calloc.3,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $ | ||
| 38 | .\" | 33 | .\" |
| 39 | .Dd June 29, 1991 | 34 | .Dd $Mdocdate: June 5 2013 $ |
| 40 | .Dt CALLOC 3 | 35 | .Dt IMAXABS 3 |
| 41 | .Os | 36 | .Os |
| 42 | .Sh NAME | 37 | .Sh NAME |
| 43 | .Nm calloc | 38 | .Nm imaxabs |
| 44 | .Nd allocate clean memory (zero initialized space) | 39 | .Nd integer absolute value function |
| 45 | .Sh SYNOPSIS | 40 | .Sh SYNOPSIS |
| 46 | .Fd #include <stdlib.h> | 41 | .In inttypes.h |
| 47 | .Ft void * | 42 | .Ft intmax_t |
| 48 | .Fn calloc "size_t nmemb" "size_t size" | 43 | .Fn imaxabs "intmax_t j" |
| 49 | .Sh DESCRIPTION | 44 | .Sh DESCRIPTION |
| 50 | The | 45 | The |
| 51 | .Fn calloc | 46 | .Fn imaxabs |
| 52 | function allocates space for an array of | 47 | function computes the absolute value of the intmax_t variable |
| 53 | .Fa nmemb | 48 | .Fa j . |
| 54 | objects, each of whose size is | ||
| 55 | .Fa size . | ||
| 56 | The space is initialized to all bits zero. | ||
| 57 | .Sh RETURN VALUES | 49 | .Sh RETURN VALUES |
| 58 | The | 50 | The |
| 59 | .Fn calloc | 51 | .Fn imaxabs |
| 60 | function returns | 52 | function returns the absolute value. |
| 61 | a pointer to the | ||
| 62 | the allocated space if successful; otherwise a null pointer is returned. | ||
| 63 | .Sh SEE ALSO | 53 | .Sh SEE ALSO |
| 64 | .Xr malloc 3 , | 54 | .Xr abs 3 , |
| 65 | .Xr realloc 3 , | 55 | .Xr cabs 3 , |
| 66 | .Xr free 3 | 56 | .Xr floor 3 , |
| 57 | .Xr hypot 3 , | ||
| 58 | .Xr labs 3 | ||
| 67 | .Sh STANDARDS | 59 | .Sh STANDARDS |
| 68 | The | 60 | The |
| 69 | .Fn calloc | 61 | .Fn imaxabs |
| 70 | function conforms to | 62 | function conforms to |
| 71 | .St -ansiC . | 63 | .St -ansiC-99 . |
| 64 | .Sh BUGS | ||
| 65 | The absolute value of the most negative integer remains negative. | ||
diff --git a/src/lib/libc/stdlib/imaxabs.c b/src/lib/libc/stdlib/imaxabs.c new file mode 100644 index 0000000000..b7e910eefd --- /dev/null +++ b/src/lib/libc/stdlib/imaxabs.c | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | /* $OpenBSD: imaxabs.c,v 1.1 2006/01/13 17:58:09 millert Exp $ */ | ||
| 2 | |||
| 3 | /*- | ||
| 4 | * Copyright (c) 1990 The Regents of the University of California. | ||
| 5 | * All rights reserved. | ||
| 6 | * | ||
| 7 | * Redistribution and use in source and binary forms, with or without | ||
| 8 | * modification, are permitted provided that the following conditions | ||
| 9 | * are met: | ||
| 10 | * 1. Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 13 | * notice, this list of conditions and the following disclaimer in the | ||
| 14 | * documentation and/or other materials provided with the distribution. | ||
| 15 | * 3. Neither the name of the University nor the names of its contributors | ||
| 16 | * may be used to endorse or promote products derived from this software | ||
| 17 | * without specific prior written permission. | ||
| 18 | * | ||
| 19 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
| 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
| 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 29 | * SUCH DAMAGE. | ||
| 30 | */ | ||
| 31 | |||
| 32 | #include <inttypes.h> | ||
| 33 | |||
| 34 | intmax_t | ||
| 35 | imaxabs(intmax_t j) | ||
| 36 | { | ||
| 37 | return (j < 0 ? -j : j); | ||
| 38 | } | ||
diff --git a/src/lib/libc/stdlib/memory.3 b/src/lib/libc/stdlib/imaxdiv.3 index 735252c837..40ac0bc236 100644 --- a/src/lib/libc/stdlib/memory.3 +++ b/src/lib/libc/stdlib/imaxdiv.3 | |||
| @@ -1,6 +1,10 @@ | |||
| 1 | .\" Copyright (c) 1991 Regents of the University of California. | 1 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. |
| 2 | .\" All rights reserved. | 2 | .\" All rights reserved. |
| 3 | .\" | 3 | .\" |
| 4 | .\" This code is derived from software contributed to Berkeley by | ||
| 5 | .\" Chris Torek and the American National Standards Committee X3, | ||
| 6 | .\" on Information Processing Systems. | ||
| 7 | .\" | ||
| 4 | .\" Redistribution and use in source and binary forms, with or without | 8 | .\" Redistribution and use in source and binary forms, with or without |
| 5 | .\" modification, are permitted provided that the following conditions | 9 | .\" modification, are permitted provided that the following conditions |
| 6 | .\" are met: | 10 | .\" are met: |
| @@ -9,11 +13,7 @@ | |||
| 9 | .\" 2. Redistributions in binary form must reproduce the above copyright | 13 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 10 | .\" notice, this list of conditions and the following disclaimer in the | 14 | .\" notice, this list of conditions and the following disclaimer in the |
| 11 | .\" documentation and/or other materials provided with the distribution. | 15 | .\" documentation and/or other materials provided with the distribution. |
| 12 | .\" 3. All advertising materials mentioning features or use of this software | 16 | .\" 3. Neither the name of the University nor the names of its contributors |
| 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 | 17 | .\" may be used to endorse or promote products derived from this software |
| 18 | .\" without specific prior written permission. | 18 | .\" without specific prior written permission. |
| 19 | .\" | 19 | .\" |
| @@ -29,43 +29,38 @@ | |||
| 29 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 29 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 30 | .\" SUCH DAMAGE. | 30 | .\" SUCH DAMAGE. |
| 31 | .\" | 31 | .\" |
| 32 | .\" from: @(#)memory.3 5.1 (Berkeley) 5/2/91 | 32 | .\" $OpenBSD: imaxdiv.3,v 1.5 2013/06/05 03:39:23 tedu Exp $ |
| 33 | .\" $Id: memory.3,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $ | ||
| 34 | .\" | 33 | .\" |
| 35 | .Dd May 2, 1991 | 34 | .Dd $Mdocdate: June 5 2013 $ |
| 36 | .Dt MEMORY 3 | 35 | .Dt IMAXDIV 3 |
| 37 | .Os BSD 4 | 36 | .Os |
| 38 | .Sh NAME | 37 | .Sh NAME |
| 39 | .Nm malloc , | 38 | .Nm imaxdiv |
| 40 | .Nm free , | 39 | .Nd return quotient and remainder from division |
| 41 | .Nm realloc , | ||
| 42 | .Nm calloc , | ||
| 43 | .Nm alloca | ||
| 44 | .Nd general memory allocation operations | ||
| 45 | .Sh SYNOPSIS | 40 | .Sh SYNOPSIS |
| 46 | .Fd #include <stdlib.h> | 41 | .In inttypes.h |
| 47 | .Ft void * | 42 | .Ft imaxdiv_t |
| 48 | .Fn malloc "size_t size" | 43 | .Fn imaxdiv "intmax_t num" "intmax_t denom" |
| 49 | .Ft void | ||
| 50 | .Fn free "void *ptr" | ||
| 51 | .Ft void * | ||
| 52 | .Fn realloc "void *ptr" "size_t size" | ||
| 53 | .Ft void * | ||
| 54 | .Fn calloc "size_t nelem" "size_t elsize" | ||
| 55 | .Ft void * | ||
| 56 | .Fn alloca "size_t size" | ||
| 57 | .Sh DESCRIPTION | 44 | .Sh DESCRIPTION |
| 58 | These functions allocate and free memory for the calling process. | 45 | The |
| 59 | They are described in the | 46 | .Fn imaxdiv |
| 60 | individual manual pages. | 47 | function computes the value |
| 48 | .Fa num Ns / Ns Fa denom | ||
| 49 | and returns the quotient and remainder in a structure named | ||
| 50 | .Li imaxdiv_t | ||
| 51 | that contains two | ||
| 52 | .Li intmax_t | ||
| 53 | members named | ||
| 54 | .Fa quot | ||
| 55 | and | ||
| 56 | .Fa rem . | ||
| 61 | .Sh SEE ALSO | 57 | .Sh SEE ALSO |
| 62 | .Xr calloc 3 , | 58 | .Xr div 3 , |
| 63 | .Xr free 3 , | 59 | .Xr ldiv 3 , |
| 64 | .Xr malloc 3 , | 60 | .Xr lldiv 3 , |
| 65 | .Xr realloc 3 , | 61 | .Xr qdiv 3 |
| 66 | .Xr alloca 3 , | ||
| 67 | .Sh STANDARDS | 62 | .Sh STANDARDS |
| 68 | These functions, with the exception of | 63 | The |
| 69 | .Fn alloca | 64 | .Fn imaxdiv |
| 70 | conform to | 65 | function conforms to |
| 71 | .St -ansiC . | 66 | .St -ansiC-99 . |
diff --git a/src/lib/libc/stdlib/imaxdiv.c b/src/lib/libc/stdlib/imaxdiv.c new file mode 100644 index 0000000000..0515a94b96 --- /dev/null +++ b/src/lib/libc/stdlib/imaxdiv.c | |||
| @@ -0,0 +1,50 @@ | |||
| 1 | /* $OpenBSD: imaxdiv.c,v 1.1 2006/01/13 17:58:09 millert Exp $ */ | ||
| 2 | /* | ||
| 3 | * Copyright (c) 1990 Regents of the University of California. | ||
| 4 | * 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. 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 | #include <inttypes.h> /* imaxdiv_t */ | ||
| 35 | |||
| 36 | imaxdiv_t | ||
| 37 | imaxdiv(intmax_t num, intmax_t denom) | ||
| 38 | { | ||
| 39 | imaxdiv_t r; | ||
| 40 | |||
| 41 | /* see div.c for comments */ | ||
| 42 | |||
| 43 | r.quot = num / denom; | ||
| 44 | r.rem = num % denom; | ||
| 45 | if (num >= 0 && r.rem < 0) { | ||
| 46 | r.quot++; | ||
| 47 | r.rem -= denom; | ||
| 48 | } | ||
| 49 | return (r); | ||
| 50 | } | ||
diff --git a/src/lib/libc/stdlib/insque.3 b/src/lib/libc/stdlib/insque.3 new file mode 100644 index 0000000000..64da36a898 --- /dev/null +++ b/src/lib/libc/stdlib/insque.3 | |||
| @@ -0,0 +1,106 @@ | |||
| 1 | .\" $OpenBSD: insque.3,v 1.9 2013/06/05 03:39:23 tedu Exp $ | ||
| 2 | .\" Copyright (c) 1993 John Brezak | ||
| 3 | .\" All rights reserved. | ||
| 4 | .\" | ||
| 5 | .\" Redistribution and use in source and binary forms, with or without | ||
| 6 | .\" modification, are permitted provided that the following conditions | ||
| 7 | .\" are met: | ||
| 8 | .\" 1. Redistributions of source code must retain the above copyright | ||
| 9 | .\" notice, this list of conditions and the following disclaimer. | ||
| 10 | .\" 2. Redistributions in binary form must reproduce the above copyright | ||
| 11 | .\" notice, this list of conditions and the following disclaimer in the | ||
| 12 | .\" documentation and/or other materials provided with the distribution. | ||
| 13 | .\" 3. The name of the author may be used to endorse or promote products | ||
| 14 | .\" derived from this software without specific prior written permission. | ||
| 15 | .\" | ||
| 16 | .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND | ||
| 17 | .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 18 | .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 19 | .\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE | ||
| 20 | .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 21 | .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 22 | .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 23 | .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 24 | .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 25 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 26 | .\" SUCH DAMAGE. | ||
| 27 | .\" | ||
| 28 | .\" | ||
| 29 | .Dd $Mdocdate: June 5 2013 $ | ||
| 30 | .Dt INSQUE 3 | ||
| 31 | .Os | ||
| 32 | .Sh NAME | ||
| 33 | .Nm insque , | ||
| 34 | .Nm remque | ||
| 35 | .Nd insert/remove element from a queue | ||
| 36 | .Sh SYNOPSIS | ||
| 37 | .In search.h | ||
| 38 | .Ft void | ||
| 39 | .Fn insque "void *elem" "void *pred" | ||
| 40 | .Ft void | ||
| 41 | .Fn remque "void *elem" | ||
| 42 | .Sh DESCRIPTION | ||
| 43 | .Bf -symbolic | ||
| 44 | These interfaces have been superseded by the | ||
| 45 | .Xr queue 3 | ||
| 46 | macros and are provided for compatibility with legacy code. | ||
| 47 | .Ef | ||
| 48 | .Pp | ||
| 49 | .Fn insque | ||
| 50 | and | ||
| 51 | .Fn remque | ||
| 52 | manipulate queues built from doubly linked lists. | ||
| 53 | The queue can be either circular or linear. | ||
| 54 | Each element in the queue must be of the following form: | ||
| 55 | .Bd -literal -offset indent | ||
| 56 | struct qelem { | ||
| 57 | struct qelem *q_forw; | ||
| 58 | struct qelem *q_back; | ||
| 59 | char q_data[]; | ||
| 60 | }; | ||
| 61 | .Ed | ||
| 62 | .Pp | ||
| 63 | The first two elements in the struct must be pointers of the | ||
| 64 | same type that point to the previous and next elements in | ||
| 65 | the queue respectively. | ||
| 66 | Any subsequent data in the struct is application-dependent. | ||
| 67 | .Pp | ||
| 68 | The | ||
| 69 | .Fn insque | ||
| 70 | function inserts | ||
| 71 | .Fa elem | ||
| 72 | into a queue immediately after | ||
| 73 | .Fa pred . | ||
| 74 | .Pp | ||
| 75 | The | ||
| 76 | .Fn remque | ||
| 77 | function removes | ||
| 78 | .Fa elem | ||
| 79 | from the queue. | ||
| 80 | .Pp | ||
| 81 | These functions are not atomic unless that machine architecture allows it. | ||
| 82 | .Sh SEE ALSO | ||
| 83 | .Xr queue 3 | ||
| 84 | .Sh STANDARDS | ||
| 85 | The | ||
| 86 | .Fn insque | ||
| 87 | and | ||
| 88 | .Fn remque | ||
| 89 | functions conform to the | ||
| 90 | .St -p1003.1-2001 | ||
| 91 | and | ||
| 92 | .St -xpg4.3 | ||
| 93 | specifications. | ||
| 94 | .Sh HISTORY | ||
| 95 | The | ||
| 96 | .Fn insque | ||
| 97 | and | ||
| 98 | .Fn remque | ||
| 99 | functions are derived from the | ||
| 100 | .Li insque | ||
| 101 | and | ||
| 102 | .Li remque | ||
| 103 | instructions on the | ||
| 104 | .Tn VAX . | ||
| 105 | They first appeared in | ||
| 106 | .Bx 4.2 . | ||
diff --git a/src/lib/libc/stdlib/insque.c b/src/lib/libc/stdlib/insque.c new file mode 100644 index 0000000000..8724efec74 --- /dev/null +++ b/src/lib/libc/stdlib/insque.c | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | /* $OpenBSD: insque.c,v 1.2 2005/08/08 08:05:36 espie Exp $ */ | ||
| 2 | |||
| 3 | /* | ||
| 4 | * Copyright (c) 1993 John Brezak | ||
| 5 | * All rights reserved. | ||
| 6 | * | ||
| 7 | * Redistribution and use in source and binary forms, with or without | ||
| 8 | * modification, are permitted provided that the following conditions | ||
| 9 | * are met: | ||
| 10 | * 1. Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 13 | * notice, this list of conditions and the following disclaimer in the | ||
| 14 | * documentation and/or other materials provided with the distribution. | ||
| 15 | * 3. The name of the author may be used to endorse or promote products | ||
| 16 | * derived from this software without specific prior written permission. | ||
| 17 | * | ||
| 18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR | ||
| 19 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
| 20 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
| 21 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, | ||
| 22 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
| 23 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||
| 24 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| 26 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 27 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 28 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 29 | */ | ||
| 30 | |||
| 31 | #include <search.h> | ||
| 32 | |||
| 33 | struct qelem { | ||
| 34 | struct qelem *q_forw; | ||
| 35 | struct qelem *q_back; | ||
| 36 | }; | ||
| 37 | |||
| 38 | void | ||
| 39 | insque(void *entry, void *pred) | ||
| 40 | { | ||
| 41 | struct qelem *e = (struct qelem *) entry; | ||
| 42 | struct qelem *p = (struct qelem *) pred; | ||
| 43 | |||
| 44 | e->q_forw = p->q_forw; | ||
| 45 | e->q_back = p; | ||
| 46 | p->q_forw->q_back = e; | ||
| 47 | p->q_forw = e; | ||
| 48 | } | ||
diff --git a/src/lib/libc/stdlib/jrand48.c b/src/lib/libc/stdlib/jrand48.c index 205781e0ee..cb8c592750 100644 --- a/src/lib/libc/stdlib/jrand48.c +++ b/src/lib/libc/stdlib/jrand48.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: jrand48.c,v 1.3 2005/08/08 08:05:36 espie Exp $ */ | ||
| 1 | /* | 2 | /* |
| 2 | * Copyright (c) 1993 Martin Birgmeier | 3 | * Copyright (c) 1993 Martin Birgmeier |
| 3 | * All rights reserved. | 4 | * All rights reserved. |
diff --git a/src/lib/libc/stdlib/l64a.c b/src/lib/libc/stdlib/l64a.c index 3069b31bf6..4f33df37b2 100644 --- a/src/lib/libc/stdlib/l64a.c +++ b/src/lib/libc/stdlib/l64a.c | |||
| @@ -1,25 +1,24 @@ | |||
| 1 | /* $OpenBSD: l64a.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */ | ||
| 1 | /* | 2 | /* |
| 2 | * Written by J.T. Conklin <jtc@netbsd.org>. | 3 | * Written by J.T. Conklin <jtc@netbsd.org>. |
| 3 | * Public domain. | 4 | * Public domain. |
| 4 | */ | 5 | */ |
| 5 | 6 | ||
| 6 | #if defined(LIBC_SCCS) && !defined(lint) | 7 | #include <errno.h> |
| 7 | static char *rcsid = "$NetBSD: l64a.c,v 1.4 1995/05/11 23:04:52 jtc Exp $"; | ||
| 8 | #endif | ||
| 9 | |||
| 10 | #include <stdlib.h> | 8 | #include <stdlib.h> |
| 11 | 9 | ||
| 12 | char * | 10 | char * |
| 13 | l64a (value) | 11 | l64a(long value) |
| 14 | long value; | ||
| 15 | { | 12 | { |
| 16 | static char buf[8]; | 13 | static char buf[8]; |
| 17 | char *s = buf; | 14 | char *s = buf; |
| 18 | int digit; | 15 | int digit; |
| 19 | int i; | 16 | int i; |
| 20 | 17 | ||
| 21 | if (!value) | 18 | if (value < 0) { |
| 22 | return NULL; | 19 | errno = EINVAL; |
| 20 | return(NULL); | ||
| 21 | } | ||
| 23 | 22 | ||
| 24 | for (i = 0; value != 0 && i < 6; i++) { | 23 | for (i = 0; value != 0 && i < 6; i++) { |
| 25 | digit = value & 0x3f; | 24 | digit = value & 0x3f; |
| @@ -39,5 +38,5 @@ l64a (value) | |||
| 39 | 38 | ||
| 40 | *s = '\0'; | 39 | *s = '\0'; |
| 41 | 40 | ||
| 42 | return buf; | 41 | return(buf); |
| 43 | } | 42 | } |
diff --git a/src/lib/libc/stdlib/labs.3 b/src/lib/libc/stdlib/labs.3 index 28e4d2053c..a38c64b1af 100644 --- a/src/lib/libc/stdlib/labs.3 +++ b/src/lib/libc/stdlib/labs.3 | |||
| @@ -13,11 +13,7 @@ | |||
| 13 | .\" 2. Redistributions in binary form must reproduce the above copyright | 13 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 14 | .\" notice, this list of conditions and the following disclaimer in the | 14 | .\" notice, this list of conditions and the following disclaimer in the |
| 15 | .\" documentation and/or other materials provided with the distribution. | 15 | .\" documentation and/or other materials provided with the distribution. |
| 16 | .\" 3. All advertising materials mentioning features or use of this software | 16 | .\" 3. Neither the name of the University nor the names of its contributors |
| 17 | .\" must display the following acknowledgement: | ||
| 18 | .\" This product includes software developed by the University of | ||
| 19 | .\" California, Berkeley and its contributors. | ||
| 20 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 21 | .\" may be used to endorse or promote products derived from this software | 17 | .\" may be used to endorse or promote products derived from this software |
| 22 | .\" without specific prior written permission. | 18 | .\" without specific prior written permission. |
| 23 | .\" | 19 | .\" |
| @@ -33,35 +29,41 @@ | |||
| 33 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 29 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 34 | .\" SUCH DAMAGE. | 30 | .\" SUCH DAMAGE. |
| 35 | .\" | 31 | .\" |
| 36 | .\" from: @(#)labs.3 5.3 (Berkeley) 6/29/91 | 32 | .\" $OpenBSD: labs.3,v 1.12 2014/01/19 05:21:12 schwarze Exp $ |
| 37 | .\" $Id: labs.3,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $ | ||
| 38 | .\" | 33 | .\" |
| 39 | .Dd June 29, 1991 | 34 | .Dd $Mdocdate: January 19 2014 $ |
| 40 | .Dt LABS 3 | 35 | .Dt LABS 3 |
| 41 | .Os | 36 | .Os |
| 42 | .Sh NAME | 37 | .Sh NAME |
| 43 | .Nm labs | 38 | .Nm labs , |
| 39 | .Nm llabs | ||
| 44 | .Nd return the absolute value of a long integer | 40 | .Nd return the absolute value of a long integer |
| 45 | .Sh SYNOPSIS | 41 | .Sh SYNOPSIS |
| 46 | .Fd #include <stdlib.h> | 42 | .In stdlib.h |
| 47 | .Ft long | 43 | .Ft long |
| 48 | .Fn labs "long j" | 44 | .Fn labs "long i" |
| 45 | .Ft long long | ||
| 46 | .Fn llabs "long long j" | ||
| 49 | .Sh DESCRIPTION | 47 | .Sh DESCRIPTION |
| 50 | The | 48 | The |
| 51 | .Fn labs | 49 | .Fn labs |
| 52 | function | 50 | function returns the absolute value of the long integer |
| 53 | returns the absolute value of the long integer | 51 | .Fa i . |
| 54 | .Ar j . | 52 | The |
| 53 | .Fn llabs | ||
| 54 | function returns the absolute value of the long long integer | ||
| 55 | .Fa j . | ||
| 55 | .Sh SEE ALSO | 56 | .Sh SEE ALSO |
| 56 | .Xr abs 3 , | 57 | .Xr abs 3 , |
| 57 | .Xr floor 3 , | ||
| 58 | .Xr cabs 3 , | 58 | .Xr cabs 3 , |
| 59 | .Xr math 3 | 59 | .Xr floor 3 , |
| 60 | .Xr imaxabs 3 | ||
| 60 | .Sh STANDARDS | 61 | .Sh STANDARDS |
| 61 | The | 62 | The |
| 62 | .Fn labs | 63 | .Fn labs |
| 63 | function | 64 | and |
| 64 | conforms to | 65 | .Fn llabs |
| 65 | .St -ansiC . | 66 | functions conform to |
| 67 | .St -ansiC-99 . | ||
| 66 | .Sh BUGS | 68 | .Sh BUGS |
| 67 | The absolute value of the most negative integer remains negative. | 69 | The absolute value of the most negative integer remains negative. |
diff --git a/src/lib/libc/stdlib/labs.c b/src/lib/libc/stdlib/labs.c index ccf1415792..ca60b9aba2 100644 --- a/src/lib/libc/stdlib/labs.c +++ b/src/lib/libc/stdlib/labs.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: labs.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */ | ||
| 1 | /*- | 2 | /*- |
| 2 | * Copyright (c) 1990 The Regents of the University of California. | 3 | * Copyright (c) 1990 The Regents of the University of California. |
| 3 | * All rights reserved. | 4 | * All rights reserved. |
| @@ -10,11 +11,7 @@ | |||
| 10 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the |
| 12 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. Neither the name of the University nor the names of its contributors |
| 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 | 15 | * may be used to endorse or promote products derived from this software |
| 19 | * without specific prior written permission. | 16 | * without specific prior written permission. |
| 20 | * | 17 | * |
| @@ -31,16 +28,10 @@ | |||
| 31 | * SUCH DAMAGE. | 28 | * SUCH DAMAGE. |
| 32 | */ | 29 | */ |
| 33 | 30 | ||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 35 | /*static char *sccsid = "from: @(#)labs.c 5.2 (Berkeley) 5/17/90";*/ | ||
| 36 | static char *rcsid = "$Id: labs.c,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $"; | ||
| 37 | #endif /* LIBC_SCCS and not lint */ | ||
| 38 | |||
| 39 | #include <stdlib.h> | 31 | #include <stdlib.h> |
| 40 | 32 | ||
| 41 | long | 33 | long |
| 42 | labs(j) | 34 | labs(long j) |
| 43 | long j; | ||
| 44 | { | 35 | { |
| 45 | return(j < 0 ? -j : j); | 36 | return(j < 0 ? -j : j); |
| 46 | } | 37 | } |
diff --git a/src/lib/libc/stdlib/lcong48.c b/src/lib/libc/stdlib/lcong48.c index 965d46b17a..2cf5c271ba 100644 --- a/src/lib/libc/stdlib/lcong48.c +++ b/src/lib/libc/stdlib/lcong48.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: lcong48.c,v 1.3 2005/08/08 08:05:36 espie Exp $ */ | ||
| 1 | /* | 2 | /* |
| 2 | * Copyright (c) 1993 Martin Birgmeier | 3 | * Copyright (c) 1993 Martin Birgmeier |
| 3 | * All rights reserved. | 4 | * All rights reserved. |
diff --git a/src/lib/libc/stdlib/ldiv.3 b/src/lib/libc/stdlib/ldiv.3 index a7b5ccf878..a8835ab6ac 100644 --- a/src/lib/libc/stdlib/ldiv.3 +++ b/src/lib/libc/stdlib/ldiv.3 | |||
| @@ -13,11 +13,7 @@ | |||
| 13 | .\" 2. Redistributions in binary form must reproduce the above copyright | 13 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 14 | .\" notice, this list of conditions and the following disclaimer in the | 14 | .\" notice, this list of conditions and the following disclaimer in the |
| 15 | .\" documentation and/or other materials provided with the distribution. | 15 | .\" documentation and/or other materials provided with the distribution. |
| 16 | .\" 3. All advertising materials mentioning features or use of this software | 16 | .\" 3. Neither the name of the University nor the names of its contributors |
| 17 | .\" must display the following acknowledgement: | ||
| 18 | .\" This product includes software developed by the University of | ||
| 19 | .\" California, Berkeley and its contributors. | ||
| 20 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 21 | .\" may be used to endorse or promote products derived from this software | 17 | .\" may be used to endorse or promote products derived from this software |
| 22 | .\" without specific prior written permission. | 18 | .\" without specific prior written permission. |
| 23 | .\" | 19 | .\" |
| @@ -33,40 +29,44 @@ | |||
| 33 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 29 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 34 | .\" SUCH DAMAGE. | 30 | .\" SUCH DAMAGE. |
| 35 | .\" | 31 | .\" |
| 36 | .\" from: @(#)ldiv.3 5.3 (Berkeley) 6/29/91 | 32 | .\" $OpenBSD: ldiv.3,v 1.12 2013/07/17 05:42:11 schwarze Exp $ |
| 37 | .\" $Id: ldiv.3,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $ | ||
| 38 | .\" | 33 | .\" |
| 39 | .Dd June 29, 1991 | 34 | .Dd $Mdocdate: July 17 2013 $ |
| 40 | .Dt LDIV 3 | 35 | .Dt LDIV 3 |
| 41 | .Os | 36 | .Os |
| 42 | .Sh NAME | 37 | .Sh NAME |
| 43 | .Nm ldiv | 38 | .Nm ldiv |
| 44 | .Nd return quotient and remainder from division | 39 | .Nd return quotient and remainder from division |
| 45 | .Sh SYNOPSIS | 40 | .Sh SYNOPSIS |
| 46 | .Fd #include <stdlib.h> | 41 | .In stdlib.h |
| 47 | .Ft ldiv_t | 42 | .Ft ldiv_t |
| 48 | .Fn ldiv "long num" "long denom" | 43 | .Fn ldiv "long num" "long denom" |
| 49 | .Sh DESCRIPTION | 44 | .Sh DESCRIPTION |
| 50 | The | 45 | The |
| 51 | .Fn ldiv | 46 | .Fn ldiv |
| 52 | function | 47 | function computes the value |
| 53 | computes the value | 48 | .Fa num Ns / Ns Fa denom |
| 54 | .Ar num/denom | ||
| 55 | and returns the quotient and remainder in a structure named | 49 | and returns the quotient and remainder in a structure named |
| 56 | .Ar ldiv_t | 50 | .Li ldiv_t |
| 57 | that contains two | 51 | that contains two |
| 58 | .Em long integer | 52 | .Li long integer |
| 59 | members named | 53 | members named |
| 60 | .Ar quot | 54 | .Fa quot |
| 61 | and | 55 | and |
| 62 | .Ar rem . | 56 | .Fa rem . |
| 63 | .Sh SEE ALSO | 57 | .Sh SEE ALSO |
| 64 | .Xr div 3 , | 58 | .Xr div 3 , |
| 65 | .Xr qdiv 3 , | 59 | .Xr imaxdiv 3 , |
| 66 | .Xr math 3 | 60 | .Xr lldiv 3 , |
| 61 | .Xr qdiv 3 | ||
| 67 | .Sh STANDARDS | 62 | .Sh STANDARDS |
| 68 | The | 63 | The |
| 69 | .Fn ldiv | 64 | .Fn ldiv |
| 70 | function | 65 | function conforms to |
| 71 | conforms to | ||
| 72 | .St -ansiC . | 66 | .St -ansiC . |
| 67 | .Sh HISTORY | ||
| 68 | An | ||
| 69 | .Fn ldiv | ||
| 70 | function with similar functionality, but a different calling convention, | ||
| 71 | first appeared in | ||
| 72 | .At v4 . | ||
diff --git a/src/lib/libc/stdlib/ldiv.c b/src/lib/libc/stdlib/ldiv.c index f7074507e5..775065f525 100644 --- a/src/lib/libc/stdlib/ldiv.c +++ b/src/lib/libc/stdlib/ldiv.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: ldiv.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */ | ||
| 1 | /* | 2 | /* |
| 2 | * Copyright (c) 1990 Regents of the University of California. | 3 | * Copyright (c) 1990 Regents of the University of California. |
| 3 | * All rights reserved. | 4 | * All rights reserved. |
| @@ -13,11 +14,7 @@ | |||
| 13 | * 2. Redistributions in binary form must reproduce the above copyright | 14 | * 2. Redistributions in binary form must reproduce the above copyright |
| 14 | * notice, this list of conditions and the following disclaimer in the | 15 | * notice, this list of conditions and the following disclaimer in the |
| 15 | * documentation and/or other materials provided with the distribution. | 16 | * documentation and/or other materials provided with the distribution. |
| 16 | * 3. All advertising materials mentioning features or use of this software | 17 | * 3. Neither the name of the University nor the names of its contributors |
| 17 | * must display the following acknowledgement: | ||
| 18 | * This product includes software developed by the University of | ||
| 19 | * California, Berkeley and its contributors. | ||
| 20 | * 4. Neither the name of the University nor the names of its contributors | ||
| 21 | * may be used to endorse or promote products derived from this software | 18 | * may be used to endorse or promote products derived from this software |
| 22 | * without specific prior written permission. | 19 | * without specific prior written permission. |
| 23 | * | 20 | * |
| @@ -34,16 +31,10 @@ | |||
| 34 | * SUCH DAMAGE. | 31 | * SUCH DAMAGE. |
| 35 | */ | 32 | */ |
| 36 | 33 | ||
| 37 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 38 | /*static char *sccsid = "from: @(#)ldiv.c 5.2 (Berkeley) 4/16/91";*/ | ||
| 39 | static char *rcsid = "$Id: ldiv.c,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $"; | ||
| 40 | #endif /* LIBC_SCCS and not lint */ | ||
| 41 | |||
| 42 | #include <stdlib.h> /* ldiv_t */ | 34 | #include <stdlib.h> /* ldiv_t */ |
| 43 | 35 | ||
| 44 | ldiv_t | 36 | ldiv_t |
| 45 | ldiv(num, denom) | 37 | ldiv(long num, long denom) |
| 46 | long num, denom; | ||
| 47 | { | 38 | { |
| 48 | ldiv_t r; | 39 | ldiv_t r; |
| 49 | 40 | ||
diff --git a/src/lib/libc/stdlib/llabs.c b/src/lib/libc/stdlib/llabs.c new file mode 100644 index 0000000000..fc2cd8261c --- /dev/null +++ b/src/lib/libc/stdlib/llabs.c | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | /* $OpenBSD: llabs.c,v 1.3 2007/01/08 19:39:25 deraadt Exp $ */ | ||
| 2 | |||
| 3 | /*- | ||
| 4 | * Copyright (c) 1990 The Regents of the University of California. | ||
| 5 | * All rights reserved. | ||
| 6 | * | ||
| 7 | * Redistribution and use in source and binary forms, with or without | ||
| 8 | * modification, are permitted provided that the following conditions | ||
| 9 | * are met: | ||
| 10 | * 1. Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 13 | * notice, this list of conditions and the following disclaimer in the | ||
| 14 | * documentation and/or other materials provided with the distribution. | ||
| 15 | * 3. Neither the name of the University nor the names of its contributors | ||
| 16 | * may be used to endorse or promote products derived from this software | ||
| 17 | * without specific prior written permission. | ||
| 18 | * | ||
| 19 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
| 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
| 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 29 | * SUCH DAMAGE. | ||
| 30 | */ | ||
| 31 | |||
| 32 | #include <stdlib.h> | ||
| 33 | |||
| 34 | long long | ||
| 35 | llabs(long long j) | ||
| 36 | { | ||
| 37 | return (j < 0 ? -j : j); | ||
| 38 | } | ||
diff --git a/src/lib/libc/stdlib/lldiv.3 b/src/lib/libc/stdlib/lldiv.3 new file mode 100644 index 0000000000..9181f8b7c5 --- /dev/null +++ b/src/lib/libc/stdlib/lldiv.3 | |||
| @@ -0,0 +1,66 @@ | |||
| 1 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. | ||
| 2 | .\" All rights reserved. | ||
| 3 | .\" | ||
| 4 | .\" This code is derived from software contributed to Berkeley by | ||
| 5 | .\" Chris Torek and the American National Standards Committee X3, | ||
| 6 | .\" on Information Processing Systems. | ||
| 7 | .\" | ||
| 8 | .\" Redistribution and use in source and binary forms, with or without | ||
| 9 | .\" modification, are permitted provided that the following conditions | ||
| 10 | .\" are met: | ||
| 11 | .\" 1. Redistributions of source code must retain the above copyright | ||
| 12 | .\" notice, this list of conditions and the following disclaimer. | ||
| 13 | .\" 2. Redistributions in binary form must reproduce the above copyright | ||
| 14 | .\" notice, this list of conditions and the following disclaimer in the | ||
| 15 | .\" documentation and/or other materials provided with the distribution. | ||
| 16 | .\" 3. 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: lldiv.3,v 1.4 2013/06/05 03:39:23 tedu Exp $ | ||
| 33 | .\" | ||
| 34 | .Dd $Mdocdate: June 5 2013 $ | ||
| 35 | .Dt LLDIV 3 | ||
| 36 | .Os | ||
| 37 | .Sh NAME | ||
| 38 | .Nm lldiv | ||
| 39 | .Nd return quotient and remainder from division | ||
| 40 | .Sh SYNOPSIS | ||
| 41 | .In stdlib.h | ||
| 42 | .Ft lldiv_t | ||
| 43 | .Fn lldiv "long long num" "long long denom" | ||
| 44 | .Sh DESCRIPTION | ||
| 45 | The | ||
| 46 | .Fn lldiv | ||
| 47 | function computes the value | ||
| 48 | .Fa num Ns / Ns Fa denom | ||
| 49 | and returns the quotient and remainder in a structure named | ||
| 50 | .Li lldiv_t | ||
| 51 | that contains two | ||
| 52 | .Li long long integer | ||
| 53 | members named | ||
| 54 | .Fa quot | ||
| 55 | and | ||
| 56 | .Fa rem . | ||
| 57 | .Sh SEE ALSO | ||
| 58 | .Xr div 3 , | ||
| 59 | .Xr imaxdiv 3 , | ||
| 60 | .Xr ldiv 3 , | ||
| 61 | .Xr qdiv 3 | ||
| 62 | .Sh STANDARDS | ||
| 63 | The | ||
| 64 | .Fn lldiv | ||
| 65 | function conforms to | ||
| 66 | .St -ansiC-99 . | ||
diff --git a/src/lib/libc/stdlib/lldiv.c b/src/lib/libc/stdlib/lldiv.c new file mode 100644 index 0000000000..e8d6c978b3 --- /dev/null +++ b/src/lib/libc/stdlib/lldiv.c | |||
| @@ -0,0 +1,50 @@ | |||
| 1 | /* $OpenBSD: lldiv.c,v 1.1 2006/01/13 17:58:09 millert Exp $ */ | ||
| 2 | /* | ||
| 3 | * Copyright (c) 1990 Regents of the University of California. | ||
| 4 | * 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. 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 | #include <stdlib.h> /* lldiv_t */ | ||
| 35 | |||
| 36 | lldiv_t | ||
| 37 | lldiv(long long num, long long denom) | ||
| 38 | { | ||
| 39 | lldiv_t r; | ||
| 40 | |||
| 41 | /* see div.c for comments */ | ||
| 42 | |||
| 43 | r.quot = num / denom; | ||
| 44 | r.rem = num % denom; | ||
| 45 | if (num >= 0 && r.rem < 0) { | ||
| 46 | r.quot++; | ||
| 47 | r.rem -= denom; | ||
| 48 | } | ||
| 49 | return (r); | ||
| 50 | } | ||
diff --git a/src/lib/libc/stdlib/lrand48.c b/src/lib/libc/stdlib/lrand48.c index 8e7f26237f..21beb858ca 100644 --- a/src/lib/libc/stdlib/lrand48.c +++ b/src/lib/libc/stdlib/lrand48.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: lrand48.c,v 1.3 2005/08/08 08:05:36 espie Exp $ */ | ||
| 1 | /* | 2 | /* |
| 2 | * Copyright (c) 1993 Martin Birgmeier | 3 | * Copyright (c) 1993 Martin Birgmeier |
| 3 | * All rights reserved. | 4 | * All rights reserved. |
diff --git a/src/lib/libc/stdlib/lsearch.3 b/src/lib/libc/stdlib/lsearch.3 new file mode 100644 index 0000000000..c5a55980e1 --- /dev/null +++ b/src/lib/libc/stdlib/lsearch.3 | |||
| @@ -0,0 +1,108 @@ | |||
| 1 | .\" $OpenBSD: lsearch.3,v 1.10 2013/06/05 03:39:23 tedu Exp $ | ||
| 2 | .\" | ||
| 3 | .\" Copyright (c) 1989, 1991, 1993 | ||
| 4 | .\" The Regents of the University of California. All rights reserved. | ||
| 5 | .\" | ||
| 6 | .\" Redistribution and use in source and binary forms, with or without | ||
| 7 | .\" modification, are permitted provided that the following conditions | ||
| 8 | .\" are met: | ||
| 9 | .\" 1. Redistributions of source code must retain the above copyright | ||
| 10 | .\" notice, this list of conditions and the following disclaimer. | ||
| 11 | .\" 2. Redistributions in binary form must reproduce the above copyright | ||
| 12 | .\" notice, this list of conditions and the following disclaimer in the | ||
| 13 | .\" documentation and/or other materials provided with the distribution. | ||
| 14 | .\" 3. Neither the name of the University nor the names of its contributors | ||
| 15 | .\" may be used to endorse or promote products derived from this software | ||
| 16 | .\" without specific prior written permission. | ||
| 17 | .\" | ||
| 18 | .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
| 19 | .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 20 | .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 21 | .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
| 22 | .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 23 | .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 24 | .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 25 | .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 26 | .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 27 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 28 | .\" SUCH DAMAGE. | ||
| 29 | .\" | ||
| 30 | .\" @(#)lsearch.3 8.1 (Berkeley) 6/4/93 | ||
| 31 | .\" | ||
| 32 | .Dd $Mdocdate: June 5 2013 $ | ||
| 33 | .Dt LSEARCH 3 | ||
| 34 | .Os | ||
| 35 | .Sh NAME | ||
| 36 | .Nm lsearch , | ||
| 37 | .Nm lfind | ||
| 38 | .Nd linear searching routines | ||
| 39 | .Sh SYNOPSIS | ||
| 40 | .In search.h | ||
| 41 | .Ft char * | ||
| 42 | .Fn lsearch "const void *key" "const void *base" "size_t *nelp" \ | ||
| 43 | "size_t width" "int (*compar)(const void *, const void *)" | ||
| 44 | .Ft char * | ||
| 45 | .Fn lfind "const void *key" "const void *base" "size_t *nelp" \ | ||
| 46 | "size_t width" "int (*compar)(const void *, const void *)" | ||
| 47 | .Sh DESCRIPTION | ||
| 48 | The functions | ||
| 49 | .Fn lsearch | ||
| 50 | and | ||
| 51 | .Fn lfind | ||
| 52 | provide basic linear searching functionality. | ||
| 53 | .Pp | ||
| 54 | .Fa base | ||
| 55 | is the pointer to the beginning of an array. | ||
| 56 | The argument | ||
| 57 | .Fa nelp | ||
| 58 | is the current number of elements in the array, where each element | ||
| 59 | is | ||
| 60 | .Fa width | ||
| 61 | bytes long. | ||
| 62 | The | ||
| 63 | .Fa compar | ||
| 64 | function | ||
| 65 | is a comparison routine which is used to compare two elements. | ||
| 66 | It takes two arguments which point to the | ||
| 67 | .Fa key | ||
| 68 | object and to an array member, in that order, and must return an integer | ||
| 69 | less than, equivalent to, or greater than zero if the | ||
| 70 | .Fa key | ||
| 71 | object is considered, respectively, to be less than, equal to, or greater | ||
| 72 | than the array member. | ||
| 73 | .Pp | ||
| 74 | The | ||
| 75 | .Fn lsearch | ||
| 76 | and | ||
| 77 | .Fn lfind | ||
| 78 | functions | ||
| 79 | return a pointer into the array referenced by | ||
| 80 | .Fa base | ||
| 81 | where | ||
| 82 | .Fa key | ||
| 83 | is located. | ||
| 84 | If | ||
| 85 | .Fa key | ||
| 86 | does not exist, | ||
| 87 | .Fn lfind | ||
| 88 | will return a null pointer and | ||
| 89 | .Fn lsearch | ||
| 90 | will add it to the array. | ||
| 91 | When an element is added to the array by | ||
| 92 | .Fn lsearch , | ||
| 93 | the location referenced by the argument | ||
| 94 | .Fa nelp | ||
| 95 | is incremented by one. | ||
| 96 | .Sh SEE ALSO | ||
| 97 | .Xr bsearch 3 , | ||
| 98 | .Xr db 3 | ||
| 99 | .Sh STANDARDS | ||
| 100 | The | ||
| 101 | .Fn lsearch | ||
| 102 | and | ||
| 103 | .Fn lfind | ||
| 104 | functions conform to the | ||
| 105 | .St -p1003.1-2001 | ||
| 106 | and | ||
| 107 | .St -xpg4.3 | ||
| 108 | specifications. | ||
diff --git a/src/lib/libc/stdlib/lsearch.c b/src/lib/libc/stdlib/lsearch.c new file mode 100644 index 0000000000..a01d80e008 --- /dev/null +++ b/src/lib/libc/stdlib/lsearch.c | |||
| @@ -0,0 +1,84 @@ | |||
| 1 | /* $OpenBSD: lsearch.c,v 1.4 2009/10/27 23:59:59 deraadt Exp $ */ | ||
| 2 | |||
| 3 | /* | ||
| 4 | * Copyright (c) 1989, 1993 | ||
| 5 | * The Regents of the University of California. All rights reserved. | ||
| 6 | * | ||
| 7 | * This code is derived from software contributed to Berkeley by | ||
| 8 | * Roger L. Snyder. | ||
| 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. 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 | |||
| 35 | #include <sys/types.h> | ||
| 36 | #include <string.h> | ||
| 37 | #include <search.h> | ||
| 38 | |||
| 39 | typedef int (*cmp_fn_t)(const void *, const void *); | ||
| 40 | static void *linear_base(const void *, const void *, size_t *, size_t, | ||
| 41 | cmp_fn_t, int); | ||
| 42 | |||
| 43 | void * | ||
| 44 | lsearch(const void *key, const void *base, size_t *nelp, size_t width, | ||
| 45 | cmp_fn_t compar) | ||
| 46 | { | ||
| 47 | |||
| 48 | return(linear_base(key, base, nelp, width, compar, 1)); | ||
| 49 | } | ||
| 50 | |||
| 51 | void * | ||
| 52 | lfind(const void *key, const void *base, size_t *nelp, size_t width, | ||
| 53 | cmp_fn_t compar) | ||
| 54 | { | ||
| 55 | return(linear_base(key, base, nelp, width, compar, 0)); | ||
| 56 | } | ||
| 57 | |||
| 58 | static void * | ||
| 59 | linear_base(const void *key, const void *base, size_t *nelp, size_t width, | ||
| 60 | cmp_fn_t compar, int add_flag) | ||
| 61 | { | ||
| 62 | const char *element, *end; | ||
| 63 | |||
| 64 | end = (const char *)base + *nelp * width; | ||
| 65 | for (element = base; element < end; element += width) | ||
| 66 | if (!compar(key, element)) /* key found */ | ||
| 67 | return((void *)element); | ||
| 68 | |||
| 69 | if (!add_flag) /* key not found */ | ||
| 70 | return(NULL); | ||
| 71 | |||
| 72 | /* | ||
| 73 | * The UNIX System User's Manual, 1986 edition claims that | ||
| 74 | * a NULL pointer is returned by lsearch with errno set | ||
| 75 | * appropriately, if there is not enough room in the table | ||
| 76 | * to add a new item. This can't be done as none of these | ||
| 77 | * routines have any method of determining the size of the | ||
| 78 | * table. This comment isn't in the 1986-87 System V | ||
| 79 | * manual. | ||
| 80 | */ | ||
| 81 | ++*nelp; | ||
| 82 | memcpy((void *)end, key, width); | ||
| 83 | return((void *)end); | ||
| 84 | } | ||
diff --git a/src/lib/libc/stdlib/malloc.3 b/src/lib/libc/stdlib/malloc.3 index 3bbf2bf65e..414f0a9770 100644 --- a/src/lib/libc/stdlib/malloc.3 +++ b/src/lib/libc/stdlib/malloc.3 | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | .\" Copyright (c) 1980, 1991 Regents of the University of California. | 1 | .\" |
| 2 | .\" All rights reserved. | 2 | .\" Copyright (c) 1980, 1991, 1993 |
| 3 | .\" The Regents of the University of California. All rights reserved. | ||
| 3 | .\" | 4 | .\" |
| 4 | .\" This code is derived from software contributed to Berkeley by | 5 | .\" This code is derived from software contributed to Berkeley by |
| 5 | .\" the American National Standards Committee X3, on Information | 6 | .\" the American National Standards Committee X3, on Information |
| @@ -13,11 +14,7 @@ | |||
| 13 | .\" 2. Redistributions in binary form must reproduce the above copyright | 14 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 14 | .\" notice, this list of conditions and the following disclaimer in the | 15 | .\" notice, this list of conditions and the following disclaimer in the |
| 15 | .\" documentation and/or other materials provided with the distribution. | 16 | .\" documentation and/or other materials provided with the distribution. |
| 16 | .\" 3. All advertising materials mentioning features or use of this software | 17 | .\" 3. Neither the name of the University nor the names of its contributors |
| 17 | .\" must display the following acknowledgement: | ||
| 18 | .\" This product includes software developed by the University of | ||
| 19 | .\" California, Berkeley and its contributors. | ||
| 20 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 21 | .\" may be used to endorse or promote products derived from this software | 18 | .\" may be used to endorse or promote products derived from this software |
| 22 | .\" without specific prior written permission. | 19 | .\" without specific prior written permission. |
| 23 | .\" | 20 | .\" |
| @@ -33,19 +30,32 @@ | |||
| 33 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 30 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 34 | .\" SUCH DAMAGE. | 31 | .\" SUCH DAMAGE. |
| 35 | .\" | 32 | .\" |
| 36 | .\" from: @(#)malloc.3 6.7 (Berkeley) 6/29/91 | 33 | .\" $OpenBSD: malloc.3,v 1.73 2013/07/18 10:14:49 schwarze Exp $ |
| 37 | .\" $Id: malloc.3,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $ | ||
| 38 | .\" | 34 | .\" |
| 39 | .Dd June 29, 1991 | 35 | .Dd $Mdocdate: July 18 2013 $ |
| 40 | .Dt MALLOC 3 | 36 | .Dt MALLOC 3 |
| 41 | .Os BSD 4 | 37 | .Os |
| 42 | .Sh NAME | 38 | .Sh NAME |
| 43 | .Nm malloc | 39 | .Nm malloc , |
| 44 | .Nd general memory allocation function | 40 | .Nm calloc , |
| 41 | .Nm realloc , | ||
| 42 | .Nm free , | ||
| 43 | .Nm cfree | ||
| 44 | .Nd memory allocation and deallocation | ||
| 45 | .Sh SYNOPSIS | 45 | .Sh SYNOPSIS |
| 46 | .Fd #include <stdlib.h> | 46 | .In stdlib.h |
| 47 | .Ft void * | 47 | .Ft void * |
| 48 | .Fn malloc "size_t size" | 48 | .Fn malloc "size_t size" |
| 49 | .Ft void * | ||
| 50 | .Fn calloc "size_t nmemb" "size_t size" | ||
| 51 | .Ft void * | ||
| 52 | .Fn realloc "void *ptr" "size_t size" | ||
| 53 | .Ft void | ||
| 54 | .Fn free "void *ptr" | ||
| 55 | .Ft void | ||
| 56 | .Fn cfree "void *ptr" | ||
| 57 | .Ft char * | ||
| 58 | .Va malloc_options ; | ||
| 49 | .Sh DESCRIPTION | 59 | .Sh DESCRIPTION |
| 50 | The | 60 | The |
| 51 | .Fn malloc | 61 | .Fn malloc |
| @@ -59,33 +69,416 @@ space from the appropriate list. | |||
| 59 | .Pp | 69 | .Pp |
| 60 | The allocated space is | 70 | The allocated space is |
| 61 | suitably aligned (after possible pointer | 71 | suitably aligned (after possible pointer |
| 62 | coercion) for storage of any type of object. If the space is of | 72 | coercion) for storage of any type of object. |
| 73 | If the space is of | ||
| 63 | .Em pagesize | 74 | .Em pagesize |
| 64 | or larger, the memory returned will be page-aligned. | 75 | or larger, the memory returned will be page-aligned. |
| 76 | .Pp | ||
| 77 | Allocation of a zero size object returns a pointer to a zero size object. | ||
| 78 | This zero size object is access protected, so any access to it will | ||
| 79 | generate an exception (SIGSEGV). | ||
| 80 | Many zero-sized objects can be placed consecutively in shared | ||
| 81 | protected pages. | ||
| 82 | The minimum size of the protection on each object is suitably aligned and | ||
| 83 | sized as previously stated, but the protection may extend further depending | ||
| 84 | on where in a protected zone the object lands. | ||
| 85 | .Pp | ||
| 86 | When using | ||
| 87 | .Fn malloc | ||
| 88 | be careful to avoid the following idiom: | ||
| 89 | .Bd -literal -offset indent | ||
| 90 | if ((p = malloc(num * size)) == NULL) | ||
| 91 | err(1, "malloc"); | ||
| 92 | .Ed | ||
| 93 | .Pp | ||
| 94 | The multiplication may lead to an integer overflow. | ||
| 95 | To avoid this, | ||
| 96 | .Fn calloc | ||
| 97 | is recommended. | ||
| 98 | .Pp | ||
| 99 | If | ||
| 100 | .Fn malloc | ||
| 101 | must be used, be sure to test for overflow: | ||
| 102 | .Bd -literal -offset indent | ||
| 103 | if (size && num > SIZE_MAX / size) { | ||
| 104 | errno = ENOMEM; | ||
| 105 | err(1, "overflow"); | ||
| 106 | } | ||
| 107 | .Ed | ||
| 108 | .Pp | ||
| 109 | The | ||
| 110 | .Fn calloc | ||
| 111 | function allocates space for an array of | ||
| 112 | .Fa nmemb | ||
| 113 | objects, each of whose size is | ||
| 114 | .Fa size . | ||
| 115 | The space is initialized to zero. | ||
| 116 | The use of | ||
| 117 | .Fn calloc | ||
| 118 | is strongly encouraged when allocating multiple sized objects | ||
| 119 | in order to avoid possible integer overflows. | ||
| 120 | .Pp | ||
| 121 | The | ||
| 122 | .Fn free | ||
| 123 | function causes the space pointed to by | ||
| 124 | .Fa ptr | ||
| 125 | to be either placed on a list of free pages to make it available for future | ||
| 126 | allocation or, if required, to be returned to the kernel using | ||
| 127 | .Xr munmap 2 . | ||
| 128 | If | ||
| 129 | .Fa ptr | ||
| 130 | is a null pointer, no action occurs. | ||
| 131 | .Pp | ||
| 132 | A | ||
| 133 | .Fn cfree | ||
| 134 | function is also provided for compatibility with old systems and other | ||
| 135 | .Nm malloc | ||
| 136 | libraries; it is simply an alias for | ||
| 137 | .Fn free . | ||
| 138 | .Pp | ||
| 139 | The | ||
| 140 | .Fn realloc | ||
| 141 | function changes the size of the object pointed to by | ||
| 142 | .Fa ptr | ||
| 143 | to | ||
| 144 | .Fa size | ||
| 145 | bytes and returns a pointer to the (possibly moved) object. | ||
| 146 | The contents of the object are unchanged up to the lesser | ||
| 147 | of the new and old sizes. | ||
| 148 | If the new size is larger, the value of the newly allocated portion | ||
| 149 | of the object is indeterminate and uninitialized. | ||
| 150 | If | ||
| 151 | .Fa ptr | ||
| 152 | is a null pointer, the | ||
| 153 | .Fn realloc | ||
| 154 | function behaves like the | ||
| 155 | .Fn malloc | ||
| 156 | function for the specified size. | ||
| 157 | If the space cannot be allocated, the object | ||
| 158 | pointed to by | ||
| 159 | .Fa ptr | ||
| 160 | is unchanged. | ||
| 161 | If | ||
| 162 | .Fa size | ||
| 163 | is zero and | ||
| 164 | .Fa ptr | ||
| 165 | is not a null pointer, the object it points to is freed and a new zero size | ||
| 166 | object is returned. | ||
| 167 | .Pp | ||
| 168 | When using | ||
| 169 | .Fn realloc | ||
| 170 | be careful to avoid the following idiom: | ||
| 171 | .Bd -literal -offset indent | ||
| 172 | size += 50; | ||
| 173 | if ((p = realloc(p, size)) == NULL) | ||
| 174 | return (NULL); | ||
| 175 | .Ed | ||
| 176 | .Pp | ||
| 177 | Do not adjust the variable describing how much memory has been allocated | ||
| 178 | until the allocation has been successful. | ||
| 179 | This can cause aberrant program behavior if the incorrect size value is used. | ||
| 180 | In most cases, the above sample will also result in a leak of memory. | ||
| 181 | As stated earlier, a return value of | ||
| 182 | .Dv NULL | ||
| 183 | indicates that the old object still remains allocated. | ||
| 184 | Better code looks like this: | ||
| 185 | .Bd -literal -offset indent | ||
| 186 | newsize = size + 50; | ||
| 187 | if ((newp = realloc(p, newsize)) == NULL) { | ||
| 188 | free(p); | ||
| 189 | p = NULL; | ||
| 190 | size = 0; | ||
| 191 | return (NULL); | ||
| 192 | } | ||
| 193 | p = newp; | ||
| 194 | size = newsize; | ||
| 195 | .Ed | ||
| 196 | .Pp | ||
| 197 | As with | ||
| 198 | .Fn malloc | ||
| 199 | it is important to ensure the new size value will not overflow; | ||
| 200 | i.e. avoid allocations like the following: | ||
| 201 | .Bd -literal -offset indent | ||
| 202 | if ((newp = realloc(p, num * size)) == NULL) { | ||
| 203 | ... | ||
| 204 | .Ed | ||
| 205 | .Sh MALLOC_OPTIONS | ||
| 206 | Malloc will first look for a symbolic link called | ||
| 207 | .Pa /etc/malloc.conf | ||
| 208 | and next check the environment for a variable called | ||
| 209 | .Ev MALLOC_OPTIONS | ||
| 210 | and finally for the global variable | ||
| 211 | .Va malloc_options | ||
| 212 | and scan them for flags in that order. | ||
| 213 | Flags are single letters, uppercase means on, lowercase means off. | ||
| 214 | .Bl -tag -width indent | ||
| 215 | .It Cm A | ||
| 216 | .Dq Abort . | ||
| 217 | .Fn malloc | ||
| 218 | will coredump the process, rather than tolerate internal | ||
| 219 | inconsistencies or incorrect usage. | ||
| 220 | This is the default and a very handy debugging aid, | ||
| 221 | since the core file represents the time of failure, | ||
| 222 | rather than when the bogus pointer was used. | ||
| 223 | .It Cm D | ||
| 224 | .Dq Dump . | ||
| 225 | .Fn malloc | ||
| 226 | will dump statistics to the file | ||
| 227 | .Pa ./malloc.out , | ||
| 228 | if it already exists, | ||
| 229 | at exit. | ||
| 230 | This option requires the library to have been compiled with -DMALLOC_STATS in | ||
| 231 | order to have any effect. | ||
| 232 | .It Cm F | ||
| 233 | .Dq Freeguard . | ||
| 234 | Enable use after free detection. | ||
| 235 | Unused pages on the freelist are read and write protected to | ||
| 236 | cause a segmentation fault upon access. | ||
| 237 | This will also switch off the delayed freeing of chunks, | ||
| 238 | reducing random behaviour but detecting double | ||
| 239 | .Fn free | ||
| 240 | calls as early as possible. | ||
| 241 | This option is intended for debugging rather than improved security | ||
| 242 | (use the | ||
| 243 | .Cm U | ||
| 244 | option for security). | ||
| 245 | .It Cm G | ||
| 246 | .Dq Guard . | ||
| 247 | Enable guard pages. | ||
| 248 | Each page size or larger allocation is followed by a guard page that will | ||
| 249 | cause a segmentation fault upon any access. | ||
| 250 | .It Cm H | ||
| 251 | .Dq Hint . | ||
| 252 | Pass a hint to the kernel about pages we don't use. | ||
| 253 | If the machine is paging a lot this may help a bit. | ||
| 254 | .It Cm J | ||
| 255 | .Dq Junk . | ||
| 256 | Fill some junk into the area allocated. | ||
| 257 | Currently junk is bytes of 0xd0 when allocating; this is pronounced | ||
| 258 | .Dq Duh . | ||
| 259 | \&:-) | ||
| 260 | Freed chunks are filled with 0xdf. | ||
| 261 | .It Cm P | ||
| 262 | .Dq Move allocations within a page. | ||
| 263 | Allocations larger than half a page but smaller than a page | ||
| 264 | are aligned to the end of a page to catch buffer overruns in more | ||
| 265 | cases. | ||
| 266 | This is the default. | ||
| 267 | .It Cm R | ||
| 268 | .Dq realloc . | ||
| 269 | Always reallocate when | ||
| 270 | .Fn realloc | ||
| 271 | is called, even if the initial allocation was big enough. | ||
| 272 | This can substantially aid in compacting memory. | ||
| 273 | .\".Pp | ||
| 274 | .\".It Cm U | ||
| 275 | .\".Dq utrace . | ||
| 276 | .\"Generate entries for | ||
| 277 | .\".Xr ktrace 1 | ||
| 278 | .\"for all operations. | ||
| 279 | .\"Consult the source for this one. | ||
| 280 | .It Cm S | ||
| 281 | Enable all options suitable for security auditing. | ||
| 282 | .It Cm U | ||
| 283 | .Dq Free unmap . | ||
| 284 | Enable use after free protection for larger allocations. | ||
| 285 | Unused pages on the freelist are read and write protected to | ||
| 286 | cause a segmentation fault upon access. | ||
| 287 | .It Cm X | ||
| 288 | .Dq xmalloc . | ||
| 289 | Rather than return failure, | ||
| 290 | .Xr abort 3 | ||
| 291 | the program with a diagnostic message on stderr. | ||
| 292 | It is the intention that this option be set at compile time by | ||
| 293 | including in the source: | ||
| 294 | .Bd -literal -offset indent | ||
| 295 | extern char *malloc_options; | ||
| 296 | malloc_options = "X"; | ||
| 297 | .Ed | ||
| 298 | .Pp | ||
| 299 | Note that this will cause code that is supposed to handle | ||
| 300 | out-of-memory conditions gracefully to abort instead. | ||
| 301 | .It Cm Z | ||
| 302 | .Dq Zero . | ||
| 303 | Fill some junk into the area allocated (see | ||
| 304 | .Cm J ) , | ||
| 305 | except for the exact length the user asked for, which is zeroed. | ||
| 306 | .It Cm < | ||
| 307 | .Dq Half the cache size . | ||
| 308 | Decrease the size of the free page cache by a factor of two. | ||
| 309 | .It Cm > | ||
| 310 | .Dq Double the cache size . | ||
| 311 | Increase the size of the free page cache by a factor of two. | ||
| 312 | .El | ||
| 313 | .Pp | ||
| 314 | So to set a systemwide reduction of the cache to a quarter of the | ||
| 315 | default size and use guard pages: | ||
| 316 | .Dl # ln -s 'G\*(Lt\*(Lt' /etc/malloc.conf | ||
| 317 | .Pp | ||
| 318 | The flags are mostly for testing and debugging. | ||
| 319 | If a program changes behavior if any of these options (except | ||
| 320 | .Cm X ) | ||
| 321 | are used, | ||
| 322 | it is buggy. | ||
| 323 | .Pp | ||
| 324 | The default number of free pages cached is 64. | ||
| 65 | .Sh RETURN VALUES | 325 | .Sh RETURN VALUES |
| 66 | The | 326 | The |
| 67 | .Fn malloc | 327 | .Fn malloc |
| 68 | function returns | 328 | and |
| 69 | a pointer to the allocated space if successful; otherwise | 329 | .Fn calloc |
| 70 | a null pointer is returned. | 330 | functions return a pointer to the allocated space if successful; otherwise, |
| 331 | a null pointer is returned and | ||
| 332 | .Va errno | ||
| 333 | is set to | ||
| 334 | .Er ENOMEM . | ||
| 335 | .Pp | ||
| 336 | The | ||
| 337 | .Fn free | ||
| 338 | and | ||
| 339 | .Fn cfree | ||
| 340 | functions return no value. | ||
| 341 | .Pp | ||
| 342 | The | ||
| 343 | .Fn realloc | ||
| 344 | function returns a pointer to the (possibly moved) allocated space | ||
| 345 | if successful; otherwise, a null pointer is returned and | ||
| 346 | .Va errno | ||
| 347 | is set to | ||
| 348 | .Er ENOMEM . | ||
| 349 | .Sh ENVIRONMENT | ||
| 350 | .Bl -tag -width Ev | ||
| 351 | .It Ev MALLOC_OPTIONS | ||
| 352 | See above. | ||
| 353 | .El | ||
| 354 | .Sh FILES | ||
| 355 | .Bl -tag -width "/etc/malloc.conf" | ||
| 356 | .It Pa /etc/malloc.conf | ||
| 357 | symbolic link to filename containing option flags | ||
| 358 | .El | ||
| 359 | .Sh DIAGNOSTICS | ||
| 360 | If | ||
| 361 | .Fn malloc , | ||
| 362 | .Fn calloc , | ||
| 363 | .Fn realloc , | ||
| 364 | or | ||
| 365 | .Fn free | ||
| 366 | detect an error condition, | ||
| 367 | a message will be printed to file descriptor | ||
| 368 | 2 (not using stdio). | ||
| 369 | Errors will result in the process being aborted, | ||
| 370 | unless the | ||
| 371 | .Cm a | ||
| 372 | option has been specified. | ||
| 373 | .Pp | ||
| 374 | Here is a brief description of the error messages and what they mean: | ||
| 375 | .Bl -tag -width Ds | ||
| 376 | .It Dq out of memory | ||
| 377 | If the | ||
| 378 | .Cm X | ||
| 379 | option is specified it is an error for | ||
| 380 | .Fn malloc , | ||
| 381 | .Fn calloc , | ||
| 382 | or | ||
| 383 | .Fn realloc | ||
| 384 | to return | ||
| 385 | .Dv NULL . | ||
| 386 | .It Dq malloc init mmap failed | ||
| 387 | This is a rather weird condition that is most likely to indicate a | ||
| 388 | seriously overloaded system or a ulimit restriction. | ||
| 389 | .It Dq bogus pointer (double free?) | ||
| 390 | An attempt to | ||
| 391 | .Fn free | ||
| 392 | or | ||
| 393 | .Fn realloc | ||
| 394 | an unallocated pointer was made. | ||
| 395 | .It Dq chunk is already free | ||
| 396 | There was an attempt to free a chunk that had already been freed. | ||
| 397 | .It Dq modified chunk-pointer | ||
| 398 | The pointer passed to | ||
| 399 | .Fn free | ||
| 400 | or | ||
| 401 | .Fn realloc | ||
| 402 | has been modified. | ||
| 403 | .It Dq recursive call | ||
| 404 | An attempt was made to call recursively into these functions, i.e., from a | ||
| 405 | signal handler. | ||
| 406 | This behavior is not supported. | ||
| 407 | In particular, signal handlers should | ||
| 408 | .Em not | ||
| 409 | use any of the | ||
| 410 | .Fn malloc | ||
| 411 | functions nor utilize any other functions which may call | ||
| 412 | .Fn malloc | ||
| 413 | (e.g., | ||
| 414 | .Xr stdio 3 | ||
| 415 | routines). | ||
| 416 | .It Dq unknown char in MALLOC_OPTIONS | ||
| 417 | We found something we didn't understand. | ||
| 418 | .It Dq malloc cache overflow/underflow | ||
| 419 | The internal malloc page cache has been corrupted. | ||
| 420 | .It Dq malloc free slot lost | ||
| 421 | The internal malloc page cache has been corrupted. | ||
| 422 | .It Dq guard size | ||
| 423 | An inconsistent guard size was detected. | ||
| 424 | .It any other error | ||
| 425 | .Fn malloc | ||
| 426 | detected an internal error; | ||
| 427 | consult sources and/or wizards. | ||
| 428 | .El | ||
| 71 | .Sh SEE ALSO | 429 | .Sh SEE ALSO |
| 72 | .Xr brk 2 , | 430 | .Xr brk 2 , |
| 73 | .Xr getpagesize 2 , | 431 | .Xr mmap 2 , |
| 74 | .Xr free 3 , | 432 | .Xr munmap 2 , |
| 75 | .Xr calloc 3 , | ||
| 76 | .Xr alloca 3 , | 433 | .Xr alloca 3 , |
| 77 | .Xr realloc 3 , | 434 | .Xr getpagesize 3 , |
| 78 | .Xr memory 3 | 435 | .Xr posix_memalign 3 |
| 79 | .Sh STANDARDS | 436 | .Sh STANDARDS |
| 80 | The | 437 | The |
| 81 | .Fn malloc | 438 | .Fn malloc |
| 82 | function conforms to | 439 | function conforms to |
| 83 | .St -ansiC . | 440 | .St -ansiC . |
| 84 | .Sh BUGS | 441 | .Sh HISTORY |
| 85 | The current implementation of | 442 | A |
| 86 | .Xr malloc | 443 | .Fn free |
| 87 | does not always fail gracefully when system | 444 | internal kernel function and a predecessor to |
| 88 | memory limits are approached. | 445 | .Fn malloc , |
| 89 | It may fail to allocate memory when larger free blocks could be broken | 446 | .Fn alloc , |
| 90 | up, or when limits are exceeded because the size is rounded up. | 447 | first appeared in |
| 91 | It is optimized for sizes that are powers of two. | 448 | .At v1 . |
| 449 | C library functions | ||
| 450 | .Fn alloc | ||
| 451 | and | ||
| 452 | .Fn free | ||
| 453 | appeared in | ||
| 454 | .At v6 . | ||
| 455 | The functions | ||
| 456 | .Fn malloc , | ||
| 457 | .Fn calloc , | ||
| 458 | and | ||
| 459 | .Fn realloc | ||
| 460 | first appeared in | ||
| 461 | .At v7 . | ||
| 462 | .Pp | ||
| 463 | A new implementation by Chris Kingsley was introduced in | ||
| 464 | .Bx 4.2 , | ||
| 465 | followed by a complete rewrite by Poul-Henning Kamp which appeared in | ||
| 466 | .Fx 2.2 | ||
| 467 | and was included in | ||
| 468 | .Ox 2.0 . | ||
| 469 | These implementations were all | ||
| 470 | .Xr sbrk 2 | ||
| 471 | based. | ||
| 472 | In | ||
| 473 | .Ox 3.8 , | ||
| 474 | Thierry Deval rewrote | ||
| 475 | .Nm | ||
| 476 | to use the | ||
| 477 | .Xr mmap 2 | ||
| 478 | system call, | ||
| 479 | making the page addresses returned by | ||
| 480 | .Nm | ||
| 481 | random. | ||
| 482 | A rewrite by Otto Moerbeek introducing a new central data structure and more | ||
| 483 | randomization appeared in | ||
| 484 | .Ox 4.4 . | ||
diff --git a/src/lib/libc/stdlib/malloc.c b/src/lib/libc/stdlib/malloc.c index 3c57fad024..446a1ca254 100644 --- a/src/lib/libc/stdlib/malloc.c +++ b/src/lib/libc/stdlib/malloc.c | |||
| @@ -1,421 +1,1820 @@ | |||
| 1 | /* $OpenBSD: malloc.c,v 1.152 2014/04/03 16:18:11 schwarze Exp $ */ | ||
| 1 | /* | 2 | /* |
| 2 | * Copyright (c) 1983 Regents of the University of California. | 3 | * Copyright (c) 2008, 2010, 2011 Otto Moerbeek <otto@drijf.net> |
| 3 | * All rights reserved. | 4 | * Copyright (c) 2012 Matthew Dempsky <matthew@openbsd.org> |
| 5 | * Copyright (c) 2008 Damien Miller <djm@openbsd.org> | ||
| 6 | * Copyright (c) 2000 Poul-Henning Kamp <phk@FreeBSD.org> | ||
| 4 | * | 7 | * |
| 5 | * Redistribution and use in source and binary forms, with or without | 8 | * Permission to use, copy, modify, and distribute this software for any |
| 6 | * modification, are permitted provided that the following conditions | 9 | * purpose with or without fee is hereby granted, provided that the above |
| 7 | * are met: | 10 | * copyright notice and this permission notice appear in all copies. |
| 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 | * | 11 | * |
| 21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | 12 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
| 22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 13 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
| 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 14 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
| 24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 15 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
| 25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 16 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
| 26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 17 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
| 27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 18 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
| 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 | */ | 19 | */ |
| 33 | 20 | ||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 35 | /*static char *sccsid = "from: @(#)malloc.c 5.11 (Berkeley) 2/23/91";*/ | ||
| 36 | static char *rcsid = "$Id: malloc.c,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $"; | ||
| 37 | #endif /* LIBC_SCCS and not lint */ | ||
| 38 | |||
| 39 | /* | 21 | /* |
| 40 | * malloc.c (Caltech) 2/21/82 | 22 | * If we meet some day, and you think this stuff is worth it, you |
| 41 | * Chris Kingsley, kingsley@cit-20. | 23 | * can buy me a beer in return. Poul-Henning Kamp |
| 42 | * | ||
| 43 | * This is a very fast storage allocator. It allocates blocks of a small | ||
| 44 | * number of different sizes, and keeps free lists of each size. Blocks that | ||
| 45 | * don't exactly fit are passed up to the next larger size. In this | ||
| 46 | * implementation, the available sizes are 2^n-4 (or 2^n-10) bytes long. | ||
| 47 | * This is designed for use in a virtual memory environment. | ||
| 48 | */ | 24 | */ |
| 49 | 25 | ||
| 26 | /* #define MALLOC_STATS */ | ||
| 27 | |||
| 50 | #include <sys/types.h> | 28 | #include <sys/types.h> |
| 29 | #include <sys/param.h> | ||
| 30 | #include <sys/queue.h> | ||
| 31 | #include <sys/mman.h> | ||
| 32 | #include <sys/uio.h> | ||
| 33 | #include <errno.h> | ||
| 34 | #include <stdint.h> | ||
| 51 | #include <stdlib.h> | 35 | #include <stdlib.h> |
| 52 | #include <string.h> | 36 | #include <string.h> |
| 37 | #include <stdio.h> | ||
| 53 | #include <unistd.h> | 38 | #include <unistd.h> |
| 54 | 39 | ||
| 55 | #define NULL 0 | 40 | #ifdef MALLOC_STATS |
| 41 | #include <sys/tree.h> | ||
| 42 | #include <fcntl.h> | ||
| 43 | #endif | ||
| 44 | |||
| 45 | #include "thread_private.h" | ||
| 46 | |||
| 47 | #if defined(__sparc__) && !defined(__sparcv9__) | ||
| 48 | #define MALLOC_PAGESHIFT (13U) | ||
| 49 | #elif defined(__mips64__) | ||
| 50 | #define MALLOC_PAGESHIFT (14U) | ||
| 51 | #else | ||
| 52 | #define MALLOC_PAGESHIFT (PAGE_SHIFT) | ||
| 53 | #endif | ||
| 54 | |||
| 55 | #define MALLOC_MINSHIFT 4 | ||
| 56 | #define MALLOC_MAXSHIFT (MALLOC_PAGESHIFT - 1) | ||
| 57 | #define MALLOC_PAGESIZE (1UL << MALLOC_PAGESHIFT) | ||
| 58 | #define MALLOC_MINSIZE (1UL << MALLOC_MINSHIFT) | ||
| 59 | #define MALLOC_PAGEMASK (MALLOC_PAGESIZE - 1) | ||
| 60 | #define MASK_POINTER(p) ((void *)(((uintptr_t)(p)) & ~MALLOC_PAGEMASK)) | ||
| 61 | |||
| 62 | #define MALLOC_MAXCHUNK (1 << MALLOC_MAXSHIFT) | ||
| 63 | #define MALLOC_MAXCACHE 256 | ||
| 64 | #define MALLOC_DELAYED_CHUNKS 15 /* max of getrnibble() */ | ||
| 65 | #define MALLOC_INITIAL_REGIONS 512 | ||
| 66 | #define MALLOC_DEFAULT_CACHE 64 | ||
| 67 | |||
| 68 | /* | ||
| 69 | * When the P option is active, we move allocations between half a page | ||
| 70 | * and a whole page towards the end, subject to alignment constraints. | ||
| 71 | * This is the extra headroom we allow. Set to zero to be the most | ||
| 72 | * strict. | ||
| 73 | */ | ||
| 74 | #define MALLOC_LEEWAY 0 | ||
| 56 | 75 | ||
| 57 | static void morecore(); | 76 | #define PAGEROUND(x) (((x) + (MALLOC_PAGEMASK)) & ~MALLOC_PAGEMASK) |
| 58 | static int findbucket(); | ||
| 59 | 77 | ||
| 60 | /* | 78 | /* |
| 61 | * The overhead on a block is at least 4 bytes. When free, this space | 79 | * What to use for Junk. This is the byte value we use to fill with |
| 62 | * contains a pointer to the next free block, and the bottom two bits must | 80 | * when the 'J' option is enabled. Use SOME_JUNK right after alloc, |
| 63 | * be zero. When in use, the first byte is set to MAGIC, and the second | 81 | * and SOME_FREEJUNK right before free. |
| 64 | * byte is the size index. The remaining bytes are for alignment. | ||
| 65 | * If range checking is enabled then a second word holds the size of the | ||
| 66 | * requested block, less 1, rounded up to a multiple of sizeof(RMAGIC). | ||
| 67 | * The order of elements is critical: ov_magic must overlay the low order | ||
| 68 | * bits of ov_next, and ov_magic can not be a valid ov_next bit pattern. | ||
| 69 | */ | 82 | */ |
| 70 | union overhead { | 83 | #define SOME_JUNK 0xd0 /* as in "Duh" :-) */ |
| 71 | union overhead *ov_next; /* when free */ | 84 | #define SOME_FREEJUNK 0xdf |
| 72 | struct { | 85 | |
| 73 | u_char ovu_magic; /* magic number */ | 86 | #define MMAP(sz) mmap(NULL, (size_t)(sz), PROT_READ | PROT_WRITE, \ |
| 74 | u_char ovu_index; /* bucket # */ | 87 | MAP_ANON | MAP_PRIVATE, -1, (off_t) 0) |
| 75 | #ifdef RCHECK | 88 | |
| 76 | u_short ovu_rmagic; /* range magic number */ | 89 | #define MMAPA(a,sz) mmap((a), (size_t)(sz), PROT_READ | PROT_WRITE, \ |
| 77 | u_long ovu_size; /* actual block size */ | 90 | MAP_ANON | MAP_PRIVATE, -1, (off_t) 0) |
| 91 | |||
| 92 | #define MQUERY(a, sz) mquery((a), (size_t)(sz), PROT_READ | PROT_WRITE, \ | ||
| 93 | MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, (off_t)0) | ||
| 94 | |||
| 95 | struct region_info { | ||
| 96 | void *p; /* page; low bits used to mark chunks */ | ||
| 97 | uintptr_t size; /* size for pages, or chunk_info pointer */ | ||
| 98 | #ifdef MALLOC_STATS | ||
| 99 | void *f; /* where allocated from */ | ||
| 78 | #endif | 100 | #endif |
| 79 | } ovu; | ||
| 80 | #define ov_magic ovu.ovu_magic | ||
| 81 | #define ov_index ovu.ovu_index | ||
| 82 | #define ov_rmagic ovu.ovu_rmagic | ||
| 83 | #define ov_size ovu.ovu_size | ||
| 84 | }; | 101 | }; |
| 85 | 102 | ||
| 86 | #define MAGIC 0xef /* magic # on accounting info */ | 103 | LIST_HEAD(chunk_head, chunk_info); |
| 87 | #define RMAGIC 0x5555 /* magic # on range info */ | ||
| 88 | 104 | ||
| 89 | #ifdef RCHECK | 105 | struct dir_info { |
| 90 | #define RSLOP sizeof (u_short) | 106 | u_int32_t canary1; |
| 107 | struct region_info *r; /* region slots */ | ||
| 108 | size_t regions_total; /* number of region slots */ | ||
| 109 | size_t regions_free; /* number of free slots */ | ||
| 110 | /* lists of free chunk info structs */ | ||
| 111 | struct chunk_head chunk_info_list[MALLOC_MAXSHIFT + 1]; | ||
| 112 | /* lists of chunks with free slots */ | ||
| 113 | struct chunk_head chunk_dir[MALLOC_MAXSHIFT + 1]; | ||
| 114 | size_t free_regions_size; /* free pages cached */ | ||
| 115 | /* free pages cache */ | ||
| 116 | struct region_info free_regions[MALLOC_MAXCACHE]; | ||
| 117 | /* delayed free chunk slots */ | ||
| 118 | void *delayed_chunks[MALLOC_DELAYED_CHUNKS + 1]; | ||
| 119 | u_short chunk_start; | ||
| 120 | #ifdef MALLOC_STATS | ||
| 121 | size_t inserts; | ||
| 122 | size_t insert_collisions; | ||
| 123 | size_t finds; | ||
| 124 | size_t find_collisions; | ||
| 125 | size_t deletes; | ||
| 126 | size_t delete_moves; | ||
| 127 | size_t cheap_realloc_tries; | ||
| 128 | size_t cheap_reallocs; | ||
| 129 | #define STATS_INC(x) ((x)++) | ||
| 130 | #define STATS_ZERO(x) ((x) = 0) | ||
| 131 | #define STATS_SETF(x,y) ((x)->f = (y)) | ||
| 91 | #else | 132 | #else |
| 92 | #define RSLOP 0 | 133 | #define STATS_INC(x) /* nothing */ |
| 93 | #endif | 134 | #define STATS_ZERO(x) /* nothing */ |
| 135 | #define STATS_SETF(x,y) /* nothing */ | ||
| 136 | #endif /* MALLOC_STATS */ | ||
| 137 | u_int32_t canary2; | ||
| 138 | }; | ||
| 139 | #define DIR_INFO_RSZ ((sizeof(struct dir_info) + MALLOC_PAGEMASK) & \ | ||
| 140 | ~MALLOC_PAGEMASK) | ||
| 94 | 141 | ||
| 95 | /* | 142 | /* |
| 96 | * nextf[i] is the pointer to the next free block of size 2^(i+3). The | 143 | * This structure describes a page worth of chunks. |
| 97 | * smallest allocatable block is 8 bytes. The overhead information | 144 | * |
| 98 | * precedes the data area returned to the user. | 145 | * How many bits per u_short in the bitmap |
| 99 | */ | 146 | */ |
| 100 | #define NBUCKETS 30 | 147 | #define MALLOC_BITS (NBBY * sizeof(u_short)) |
| 101 | static union overhead *nextf[NBUCKETS]; | 148 | struct chunk_info { |
| 102 | extern char *sbrk(); | 149 | LIST_ENTRY(chunk_info) entries; |
| 150 | void *page; /* pointer to the page */ | ||
| 151 | u_int32_t canary; | ||
| 152 | u_short size; /* size of this page's chunks */ | ||
| 153 | u_short shift; /* how far to shift for this size */ | ||
| 154 | u_short free; /* how many free chunks */ | ||
| 155 | u_short total; /* how many chunk */ | ||
| 156 | /* which chunks are free */ | ||
| 157 | u_short bits[1]; | ||
| 158 | }; | ||
| 159 | |||
| 160 | struct malloc_readonly { | ||
| 161 | struct dir_info *g_pool; /* Main bookkeeping information */ | ||
| 162 | int malloc_abort; /* abort() on error */ | ||
| 163 | int malloc_freenow; /* Free quickly - disable chunk rnd */ | ||
| 164 | int malloc_freeunmap; /* mprotect free pages PROT_NONE? */ | ||
| 165 | int malloc_hint; /* call madvice on free pages? */ | ||
| 166 | int malloc_junk; /* junk fill? */ | ||
| 167 | int malloc_move; /* move allocations to end of page? */ | ||
| 168 | int malloc_realloc; /* always realloc? */ | ||
| 169 | int malloc_xmalloc; /* xmalloc behaviour? */ | ||
| 170 | int malloc_zero; /* zero fill? */ | ||
| 171 | size_t malloc_guard; /* use guard pages after allocations? */ | ||
| 172 | u_int malloc_cache; /* free pages we cache */ | ||
| 173 | #ifdef MALLOC_STATS | ||
| 174 | int malloc_stats; /* dump statistics at end */ | ||
| 175 | #endif | ||
| 176 | u_int32_t malloc_canary; /* Matched against ones in g_pool */ | ||
| 177 | }; | ||
| 103 | 178 | ||
| 104 | static int pagesz; /* page size */ | 179 | /* This object is mapped PROT_READ after initialisation to prevent tampering */ |
| 105 | static int pagebucket; /* page size bucket */ | 180 | static union { |
| 181 | struct malloc_readonly mopts; | ||
| 182 | u_char _pad[MALLOC_PAGESIZE]; | ||
| 183 | } malloc_readonly __attribute__((aligned(MALLOC_PAGESIZE))); | ||
| 184 | #define mopts malloc_readonly.mopts | ||
| 185 | #define g_pool mopts.g_pool | ||
| 106 | 186 | ||
| 107 | #ifdef MSTATS | 187 | char *malloc_options; /* compile-time options */ |
| 108 | /* | 188 | |
| 109 | * nmalloc[i] is the difference between the number of mallocs and frees | 189 | static char *malloc_func; /* current function */ |
| 110 | * for a given block size. | 190 | static int malloc_active; /* status of malloc */ |
| 191 | |||
| 192 | static size_t malloc_guarded; /* bytes used for guards */ | ||
| 193 | static size_t malloc_used; /* bytes allocated */ | ||
| 194 | |||
| 195 | static size_t rnibblesused; /* random nibbles used */ | ||
| 196 | static u_char rbytes[512]; /* random bytes */ | ||
| 197 | static u_char getrnibble(void); | ||
| 198 | |||
| 199 | extern char *__progname; | ||
| 200 | |||
| 201 | #ifdef MALLOC_STATS | ||
| 202 | void malloc_dump(int); | ||
| 203 | static void malloc_exit(void); | ||
| 204 | #define CALLER __builtin_return_address(0) | ||
| 205 | #else | ||
| 206 | #define CALLER NULL | ||
| 207 | #endif | ||
| 208 | |||
| 209 | /* low bits of r->p determine size: 0 means >= page size and p->size holding | ||
| 210 | * real size, otherwise r->size is a shift count, or 1 for malloc(0) | ||
| 111 | */ | 211 | */ |
| 112 | static u_int nmalloc[NBUCKETS]; | 212 | #define REALSIZE(sz, r) \ |
| 113 | #include <stdio.h> | 213 | (sz) = (uintptr_t)(r)->p & MALLOC_PAGEMASK, \ |
| 214 | (sz) = ((sz) == 0 ? (r)->size : ((sz) == 1 ? 0 : (1 << ((sz)-1)))) | ||
| 215 | |||
| 216 | static inline size_t | ||
| 217 | hash(void *p) | ||
| 218 | { | ||
| 219 | size_t sum; | ||
| 220 | union { | ||
| 221 | uintptr_t p; | ||
| 222 | unsigned short a[sizeof(void *) / sizeof(short)]; | ||
| 223 | } u; | ||
| 224 | u.p = (uintptr_t)p >> MALLOC_PAGESHIFT; | ||
| 225 | sum = u.a[0]; | ||
| 226 | sum = (sum << 7) - sum + u.a[1]; | ||
| 227 | #ifdef __LP64__ | ||
| 228 | sum = (sum << 7) - sum + u.a[2]; | ||
| 229 | sum = (sum << 7) - sum + u.a[3]; | ||
| 114 | #endif | 230 | #endif |
| 231 | return sum; | ||
| 232 | } | ||
| 115 | 233 | ||
| 116 | #if defined(DEBUG) || defined(RCHECK) | 234 | static void |
| 117 | #define ASSERT(p) if (!(p)) botch("p") | 235 | wrterror(char *msg, void *p) |
| 118 | #include <stdio.h> | ||
| 119 | static | ||
| 120 | botch(s) | ||
| 121 | char *s; | ||
| 122 | { | 236 | { |
| 123 | fprintf(stderr, "\r\nassertion botched: %s\r\n", s); | 237 | char *q = " error: "; |
| 124 | (void) fflush(stderr); /* just in case user buffered it */ | 238 | struct iovec iov[6]; |
| 125 | abort(); | 239 | char buf[20]; |
| 240 | int saved_errno = errno; | ||
| 241 | |||
| 242 | iov[0].iov_base = __progname; | ||
| 243 | iov[0].iov_len = strlen(__progname); | ||
| 244 | iov[1].iov_base = malloc_func; | ||
| 245 | iov[1].iov_len = strlen(malloc_func); | ||
| 246 | iov[2].iov_base = q; | ||
| 247 | iov[2].iov_len = strlen(q); | ||
| 248 | iov[3].iov_base = msg; | ||
| 249 | iov[3].iov_len = strlen(msg); | ||
| 250 | iov[4].iov_base = buf; | ||
| 251 | if (p == NULL) | ||
| 252 | iov[4].iov_len = 0; | ||
| 253 | else { | ||
| 254 | snprintf(buf, sizeof(buf), " %p", p); | ||
| 255 | iov[4].iov_len = strlen(buf); | ||
| 256 | } | ||
| 257 | iov[5].iov_base = "\n"; | ||
| 258 | iov[5].iov_len = 1; | ||
| 259 | writev(STDERR_FILENO, iov, 6); | ||
| 260 | |||
| 261 | #ifdef MALLOC_STATS | ||
| 262 | if (mopts.malloc_stats) | ||
| 263 | malloc_dump(STDERR_FILENO); | ||
| 264 | #endif /* MALLOC_STATS */ | ||
| 265 | |||
| 266 | errno = saved_errno; | ||
| 267 | if (mopts.malloc_abort) | ||
| 268 | abort(); | ||
| 126 | } | 269 | } |
| 127 | #else | ||
| 128 | #define ASSERT(p) | ||
| 129 | #endif | ||
| 130 | 270 | ||
| 131 | void * | 271 | static void |
| 132 | malloc(nbytes) | 272 | rbytes_init(void) |
| 133 | size_t nbytes; | 273 | { |
| 274 | arc4random_buf(rbytes, sizeof(rbytes)); | ||
| 275 | rnibblesused = 0; | ||
| 276 | } | ||
| 277 | |||
| 278 | static inline u_char | ||
| 279 | getrnibble(void) | ||
| 280 | { | ||
| 281 | u_char x; | ||
| 282 | |||
| 283 | if (rnibblesused >= 2 * sizeof(rbytes)) | ||
| 284 | rbytes_init(); | ||
| 285 | x = rbytes[rnibblesused++ / 2]; | ||
| 286 | return (rnibblesused & 1 ? x & 0xf : x >> 4); | ||
| 287 | } | ||
| 288 | |||
| 289 | /* | ||
| 290 | * Cache maintenance. We keep at most malloc_cache pages cached. | ||
| 291 | * If the cache is becoming full, unmap pages in the cache for real, | ||
| 292 | * and then add the region to the cache | ||
| 293 | * Opposed to the regular region data structure, the sizes in the | ||
| 294 | * cache are in MALLOC_PAGESIZE units. | ||
| 295 | */ | ||
| 296 | static void | ||
| 297 | unmap(struct dir_info *d, void *p, size_t sz) | ||
| 298 | { | ||
| 299 | size_t psz = sz >> MALLOC_PAGESHIFT; | ||
| 300 | size_t rsz, tounmap; | ||
| 301 | struct region_info *r; | ||
| 302 | u_int i, offset; | ||
| 303 | |||
| 304 | if (sz != PAGEROUND(sz)) { | ||
| 305 | wrterror("munmap round", NULL); | ||
| 306 | return; | ||
| 307 | } | ||
| 308 | |||
| 309 | if (psz > mopts.malloc_cache) { | ||
| 310 | if (munmap(p, sz)) | ||
| 311 | wrterror("munmap", p); | ||
| 312 | malloc_used -= sz; | ||
| 313 | return; | ||
| 314 | } | ||
| 315 | tounmap = 0; | ||
| 316 | rsz = mopts.malloc_cache - d->free_regions_size; | ||
| 317 | if (psz > rsz) | ||
| 318 | tounmap = psz - rsz; | ||
| 319 | offset = getrnibble() + (getrnibble() << 4); | ||
| 320 | for (i = 0; tounmap > 0 && i < mopts.malloc_cache; i++) { | ||
| 321 | r = &d->free_regions[(i + offset) & (mopts.malloc_cache - 1)]; | ||
| 322 | if (r->p != NULL) { | ||
| 323 | rsz = r->size << MALLOC_PAGESHIFT; | ||
| 324 | if (munmap(r->p, rsz)) | ||
| 325 | wrterror("munmap", r->p); | ||
| 326 | r->p = NULL; | ||
| 327 | if (tounmap > r->size) | ||
| 328 | tounmap -= r->size; | ||
| 329 | else | ||
| 330 | tounmap = 0; | ||
| 331 | d->free_regions_size -= r->size; | ||
| 332 | r->size = 0; | ||
| 333 | malloc_used -= rsz; | ||
| 334 | } | ||
| 335 | } | ||
| 336 | if (tounmap > 0) | ||
| 337 | wrterror("malloc cache underflow", NULL); | ||
| 338 | for (i = 0; i < mopts.malloc_cache; i++) { | ||
| 339 | r = &d->free_regions[(i + offset) & (mopts.malloc_cache - 1)]; | ||
| 340 | if (r->p == NULL) { | ||
| 341 | if (mopts.malloc_hint) | ||
| 342 | madvise(p, sz, MADV_FREE); | ||
| 343 | if (mopts.malloc_freeunmap) | ||
| 344 | mprotect(p, sz, PROT_NONE); | ||
| 345 | r->p = p; | ||
| 346 | r->size = psz; | ||
| 347 | d->free_regions_size += psz; | ||
| 348 | break; | ||
| 349 | } | ||
| 350 | } | ||
| 351 | if (i == mopts.malloc_cache) | ||
| 352 | wrterror("malloc free slot lost", NULL); | ||
| 353 | if (d->free_regions_size > mopts.malloc_cache) | ||
| 354 | wrterror("malloc cache overflow", NULL); | ||
| 355 | } | ||
| 356 | |||
| 357 | static void | ||
| 358 | zapcacheregion(struct dir_info *d, void *p, size_t len) | ||
| 359 | { | ||
| 360 | u_int i; | ||
| 361 | struct region_info *r; | ||
| 362 | size_t rsz; | ||
| 363 | |||
| 364 | for (i = 0; i < mopts.malloc_cache; i++) { | ||
| 365 | r = &d->free_regions[i]; | ||
| 366 | if (r->p >= p && r->p <= (void *)((char *)p + len)) { | ||
| 367 | rsz = r->size << MALLOC_PAGESHIFT; | ||
| 368 | if (munmap(r->p, rsz)) | ||
| 369 | wrterror("munmap", r->p); | ||
| 370 | r->p = NULL; | ||
| 371 | d->free_regions_size -= r->size; | ||
| 372 | r->size = 0; | ||
| 373 | malloc_used -= rsz; | ||
| 374 | } | ||
| 375 | } | ||
| 376 | } | ||
| 377 | |||
| 378 | static void * | ||
| 379 | map(struct dir_info *d, size_t sz, int zero_fill) | ||
| 134 | { | 380 | { |
| 135 | register union overhead *op; | 381 | size_t psz = sz >> MALLOC_PAGESHIFT; |
| 136 | register long bucket, n; | 382 | struct region_info *r, *big = NULL; |
| 137 | register unsigned amt; | 383 | u_int i, offset; |
| 384 | void *p; | ||
| 385 | |||
| 386 | if (mopts.malloc_canary != (d->canary1 ^ (u_int32_t)(uintptr_t)d) || | ||
| 387 | d->canary1 != ~d->canary2) | ||
| 388 | wrterror("internal struct corrupt", NULL); | ||
| 389 | if (sz != PAGEROUND(sz)) { | ||
| 390 | wrterror("map round", NULL); | ||
| 391 | return MAP_FAILED; | ||
| 392 | } | ||
| 393 | if (psz > d->free_regions_size) { | ||
| 394 | p = MMAP(sz); | ||
| 395 | if (p != MAP_FAILED) | ||
| 396 | malloc_used += sz; | ||
| 397 | /* zero fill not needed */ | ||
| 398 | return p; | ||
| 399 | } | ||
| 400 | offset = getrnibble() + (getrnibble() << 4); | ||
| 401 | for (i = 0; i < mopts.malloc_cache; i++) { | ||
| 402 | r = &d->free_regions[(i + offset) & (mopts.malloc_cache - 1)]; | ||
| 403 | if (r->p != NULL) { | ||
| 404 | if (r->size == psz) { | ||
| 405 | p = r->p; | ||
| 406 | if (mopts.malloc_freeunmap) | ||
| 407 | mprotect(p, sz, PROT_READ | PROT_WRITE); | ||
| 408 | if (mopts.malloc_hint) | ||
| 409 | madvise(p, sz, MADV_NORMAL); | ||
| 410 | r->p = NULL; | ||
| 411 | r->size = 0; | ||
| 412 | d->free_regions_size -= psz; | ||
| 413 | if (zero_fill) | ||
| 414 | memset(p, 0, sz); | ||
| 415 | else if (mopts.malloc_junk && | ||
| 416 | mopts.malloc_freeunmap) | ||
| 417 | memset(p, SOME_FREEJUNK, sz); | ||
| 418 | return p; | ||
| 419 | } else if (r->size > psz) | ||
| 420 | big = r; | ||
| 421 | } | ||
| 422 | } | ||
| 423 | if (big != NULL) { | ||
| 424 | r = big; | ||
| 425 | p = (char *)r->p + ((r->size - psz) << MALLOC_PAGESHIFT); | ||
| 426 | if (mopts.malloc_freeunmap) | ||
| 427 | mprotect(p, sz, PROT_READ | PROT_WRITE); | ||
| 428 | if (mopts.malloc_hint) | ||
| 429 | madvise(p, sz, MADV_NORMAL); | ||
| 430 | r->size -= psz; | ||
| 431 | d->free_regions_size -= psz; | ||
| 432 | if (zero_fill) | ||
| 433 | memset(p, 0, sz); | ||
| 434 | else if (mopts.malloc_junk && mopts.malloc_freeunmap) | ||
| 435 | memset(p, SOME_FREEJUNK, sz); | ||
| 436 | return p; | ||
| 437 | } | ||
| 438 | p = MMAP(sz); | ||
| 439 | if (p != MAP_FAILED) | ||
| 440 | malloc_used += sz; | ||
| 441 | if (d->free_regions_size > mopts.malloc_cache) | ||
| 442 | wrterror("malloc cache", NULL); | ||
| 443 | /* zero fill not needed */ | ||
| 444 | return p; | ||
| 445 | } | ||
| 446 | |||
| 447 | /* | ||
| 448 | * Initialize a dir_info, which should have been cleared by caller | ||
| 449 | */ | ||
| 450 | static int | ||
| 451 | omalloc_init(struct dir_info **dp) | ||
| 452 | { | ||
| 453 | char *p, b[64]; | ||
| 454 | int i, j; | ||
| 455 | size_t d_avail, regioninfo_size; | ||
| 456 | struct dir_info *d; | ||
| 457 | |||
| 458 | rbytes_init(); | ||
| 138 | 459 | ||
| 139 | /* | 460 | /* |
| 140 | * First time malloc is called, setup page size and | 461 | * Default options |
| 141 | * align break pointer so all data will be page aligned. | ||
| 142 | */ | 462 | */ |
| 143 | if (pagesz == 0) { | 463 | mopts.malloc_abort = 1; |
| 144 | pagesz = n = getpagesize(); | 464 | mopts.malloc_move = 1; |
| 145 | op = (union overhead *)sbrk(0); | 465 | mopts.malloc_cache = MALLOC_DEFAULT_CACHE; |
| 146 | n = n - sizeof (*op) - ((long)op & (n - 1)); | 466 | |
| 147 | if (n < 0) | 467 | for (i = 0; i < 3; i++) { |
| 148 | n += pagesz; | 468 | switch (i) { |
| 149 | if (n) { | 469 | case 0: |
| 150 | if (sbrk(n) == (char *)-1) | 470 | j = readlink("/etc/malloc.conf", b, sizeof b - 1); |
| 151 | return (NULL); | 471 | if (j <= 0) |
| 472 | continue; | ||
| 473 | b[j] = '\0'; | ||
| 474 | p = b; | ||
| 475 | break; | ||
| 476 | case 1: | ||
| 477 | if (issetugid() == 0) | ||
| 478 | p = getenv("MALLOC_OPTIONS"); | ||
| 479 | else | ||
| 480 | continue; | ||
| 481 | break; | ||
| 482 | case 2: | ||
| 483 | p = malloc_options; | ||
| 484 | break; | ||
| 485 | default: | ||
| 486 | p = NULL; | ||
| 152 | } | 487 | } |
| 153 | bucket = 0; | 488 | |
| 154 | amt = 8; | 489 | for (; p != NULL && *p != '\0'; p++) { |
| 155 | while (pagesz > amt) { | 490 | switch (*p) { |
| 156 | amt <<= 1; | 491 | case '>': |
| 157 | bucket++; | 492 | mopts.malloc_cache <<= 1; |
| 493 | if (mopts.malloc_cache > MALLOC_MAXCACHE) | ||
| 494 | mopts.malloc_cache = MALLOC_MAXCACHE; | ||
| 495 | break; | ||
| 496 | case '<': | ||
| 497 | mopts.malloc_cache >>= 1; | ||
| 498 | break; | ||
| 499 | case 'a': | ||
| 500 | mopts.malloc_abort = 0; | ||
| 501 | break; | ||
| 502 | case 'A': | ||
| 503 | mopts.malloc_abort = 1; | ||
| 504 | break; | ||
| 505 | #ifdef MALLOC_STATS | ||
| 506 | case 'd': | ||
| 507 | mopts.malloc_stats = 0; | ||
| 508 | break; | ||
| 509 | case 'D': | ||
| 510 | mopts.malloc_stats = 1; | ||
| 511 | break; | ||
| 512 | #endif /* MALLOC_STATS */ | ||
| 513 | case 'f': | ||
| 514 | mopts.malloc_freenow = 0; | ||
| 515 | mopts.malloc_freeunmap = 0; | ||
| 516 | break; | ||
| 517 | case 'F': | ||
| 518 | mopts.malloc_freenow = 1; | ||
| 519 | mopts.malloc_freeunmap = 1; | ||
| 520 | break; | ||
| 521 | case 'g': | ||
| 522 | mopts.malloc_guard = 0; | ||
| 523 | break; | ||
| 524 | case 'G': | ||
| 525 | mopts.malloc_guard = MALLOC_PAGESIZE; | ||
| 526 | break; | ||
| 527 | case 'h': | ||
| 528 | mopts.malloc_hint = 0; | ||
| 529 | break; | ||
| 530 | case 'H': | ||
| 531 | mopts.malloc_hint = 1; | ||
| 532 | break; | ||
| 533 | case 'j': | ||
| 534 | mopts.malloc_junk = 0; | ||
| 535 | break; | ||
| 536 | case 'J': | ||
| 537 | mopts.malloc_junk = 1; | ||
| 538 | break; | ||
| 539 | case 'n': | ||
| 540 | case 'N': | ||
| 541 | break; | ||
| 542 | case 'p': | ||
| 543 | mopts.malloc_move = 0; | ||
| 544 | break; | ||
| 545 | case 'P': | ||
| 546 | mopts.malloc_move = 1; | ||
| 547 | break; | ||
| 548 | case 'r': | ||
| 549 | mopts.malloc_realloc = 0; | ||
| 550 | break; | ||
| 551 | case 'R': | ||
| 552 | mopts.malloc_realloc = 1; | ||
| 553 | break; | ||
| 554 | case 's': | ||
| 555 | mopts.malloc_freeunmap = mopts.malloc_junk = 0; | ||
| 556 | mopts.malloc_guard = 0; | ||
| 557 | mopts.malloc_cache = MALLOC_DEFAULT_CACHE; | ||
| 558 | break; | ||
| 559 | case 'S': | ||
| 560 | mopts.malloc_freeunmap = mopts.malloc_junk = 1; | ||
| 561 | mopts.malloc_guard = MALLOC_PAGESIZE; | ||
| 562 | mopts.malloc_cache = 0; | ||
| 563 | break; | ||
| 564 | case 'u': | ||
| 565 | mopts.malloc_freeunmap = 0; | ||
| 566 | break; | ||
| 567 | case 'U': | ||
| 568 | mopts.malloc_freeunmap = 1; | ||
| 569 | break; | ||
| 570 | case 'x': | ||
| 571 | mopts.malloc_xmalloc = 0; | ||
| 572 | break; | ||
| 573 | case 'X': | ||
| 574 | mopts.malloc_xmalloc = 1; | ||
| 575 | break; | ||
| 576 | case 'z': | ||
| 577 | mopts.malloc_zero = 0; | ||
| 578 | break; | ||
| 579 | case 'Z': | ||
| 580 | mopts.malloc_zero = 1; | ||
| 581 | break; | ||
| 582 | default: { | ||
| 583 | static const char q[] = "malloc() warning: " | ||
| 584 | "unknown char in MALLOC_OPTIONS\n"; | ||
| 585 | write(STDERR_FILENO, q, sizeof(q) - 1); | ||
| 586 | break; | ||
| 587 | } | ||
| 588 | } | ||
| 158 | } | 589 | } |
| 159 | pagebucket = bucket; | ||
| 160 | } | 590 | } |
| 591 | |||
| 161 | /* | 592 | /* |
| 162 | * Convert amount of memory requested into closest block size | 593 | * We want junk in the entire allocation, and zero only in the part |
| 163 | * stored in hash buckets which satisfies request. | 594 | * the user asked for. |
| 164 | * Account for space used per block for accounting. | ||
| 165 | */ | 595 | */ |
| 166 | if (nbytes <= (n = pagesz - sizeof (*op) - RSLOP)) { | 596 | if (mopts.malloc_zero) |
| 167 | #ifndef RCHECK | 597 | mopts.malloc_junk = 1; |
| 168 | amt = 8; /* size of first bucket */ | 598 | |
| 169 | bucket = 0; | 599 | #ifdef MALLOC_STATS |
| 170 | #else | 600 | if (mopts.malloc_stats && (atexit(malloc_exit) == -1)) { |
| 171 | amt = 16; /* size of first bucket */ | 601 | static const char q[] = "malloc() warning: atexit(2) failed." |
| 172 | bucket = 1; | 602 | " Will not be able to dump stats on exit\n"; |
| 173 | #endif | 603 | write(STDERR_FILENO, q, sizeof(q) - 1); |
| 174 | n = -((long)sizeof (*op) + RSLOP); | ||
| 175 | } else { | ||
| 176 | amt = pagesz; | ||
| 177 | bucket = pagebucket; | ||
| 178 | } | ||
| 179 | while (nbytes > amt + n) { | ||
| 180 | amt <<= 1; | ||
| 181 | if (amt == 0) | ||
| 182 | return (NULL); | ||
| 183 | bucket++; | ||
| 184 | } | 604 | } |
| 605 | #endif /* MALLOC_STATS */ | ||
| 606 | |||
| 607 | while ((mopts.malloc_canary = arc4random()) == 0) | ||
| 608 | ; | ||
| 609 | |||
| 185 | /* | 610 | /* |
| 186 | * If nothing in hash bucket right now, | 611 | * Allocate dir_info with a guard page on either side. Also |
| 187 | * request more memory from the system. | 612 | * randomise offset inside the page at which the dir_info |
| 613 | * lies (subject to alignment by 1 << MALLOC_MINSHIFT) | ||
| 188 | */ | 614 | */ |
| 189 | if ((op = nextf[bucket]) == NULL) { | 615 | if ((p = MMAP(DIR_INFO_RSZ + (MALLOC_PAGESIZE * 2))) == MAP_FAILED) |
| 190 | morecore(bucket); | 616 | return -1; |
| 191 | if ((op = nextf[bucket]) == NULL) | 617 | mprotect(p, MALLOC_PAGESIZE, PROT_NONE); |
| 192 | return (NULL); | 618 | mprotect(p + MALLOC_PAGESIZE + DIR_INFO_RSZ, |
| 193 | } | 619 | MALLOC_PAGESIZE, PROT_NONE); |
| 194 | /* remove from linked list */ | 620 | d_avail = (DIR_INFO_RSZ - sizeof(*d)) >> MALLOC_MINSHIFT; |
| 195 | nextf[bucket] = op->ov_next; | 621 | d = (struct dir_info *)(p + MALLOC_PAGESIZE + |
| 196 | op->ov_magic = MAGIC; | 622 | (arc4random_uniform(d_avail) << MALLOC_MINSHIFT)); |
| 197 | op->ov_index = bucket; | 623 | |
| 198 | #ifdef MSTATS | 624 | d->regions_free = d->regions_total = MALLOC_INITIAL_REGIONS; |
| 199 | nmalloc[bucket]++; | 625 | regioninfo_size = d->regions_total * sizeof(struct region_info); |
| 200 | #endif | 626 | d->r = MMAP(regioninfo_size); |
| 201 | #ifdef RCHECK | 627 | if (d->r == MAP_FAILED) { |
| 628 | wrterror("malloc init mmap failed", NULL); | ||
| 629 | d->regions_total = 0; | ||
| 630 | return 1; | ||
| 631 | } | ||
| 632 | for (i = 0; i <= MALLOC_MAXSHIFT; i++) { | ||
| 633 | LIST_INIT(&d->chunk_info_list[i]); | ||
| 634 | LIST_INIT(&d->chunk_dir[i]); | ||
| 635 | } | ||
| 636 | malloc_used += regioninfo_size; | ||
| 637 | d->canary1 = mopts.malloc_canary ^ (u_int32_t)(uintptr_t)d; | ||
| 638 | d->canary2 = ~d->canary1; | ||
| 639 | |||
| 640 | *dp = d; | ||
| 641 | |||
| 202 | /* | 642 | /* |
| 203 | * Record allocated size of block and | 643 | * Options have been set and will never be reset. |
| 204 | * bound space with magic numbers. | 644 | * Prevent further tampering with them. |
| 205 | */ | 645 | */ |
| 206 | op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1); | 646 | if (((uintptr_t)&malloc_readonly & MALLOC_PAGEMASK) == 0) |
| 207 | op->ov_rmagic = RMAGIC; | 647 | mprotect(&malloc_readonly, sizeof(malloc_readonly), PROT_READ); |
| 208 | *(u_short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC; | 648 | |
| 649 | return 0; | ||
| 650 | } | ||
| 651 | |||
| 652 | static int | ||
| 653 | omalloc_grow(struct dir_info *d) | ||
| 654 | { | ||
| 655 | size_t newtotal; | ||
| 656 | size_t newsize; | ||
| 657 | size_t mask; | ||
| 658 | size_t i; | ||
| 659 | struct region_info *p; | ||
| 660 | |||
| 661 | if (d->regions_total > SIZE_MAX / sizeof(struct region_info) / 2 ) | ||
| 662 | return 1; | ||
| 663 | |||
| 664 | newtotal = d->regions_total * 2; | ||
| 665 | newsize = newtotal * sizeof(struct region_info); | ||
| 666 | mask = newtotal - 1; | ||
| 667 | |||
| 668 | p = MMAP(newsize); | ||
| 669 | if (p == MAP_FAILED) | ||
| 670 | return 1; | ||
| 671 | |||
| 672 | malloc_used += newsize; | ||
| 673 | memset(p, 0, newsize); | ||
| 674 | STATS_ZERO(d->inserts); | ||
| 675 | STATS_ZERO(d->insert_collisions); | ||
| 676 | for (i = 0; i < d->regions_total; i++) { | ||
| 677 | void *q = d->r[i].p; | ||
| 678 | if (q != NULL) { | ||
| 679 | size_t index = hash(q) & mask; | ||
| 680 | STATS_INC(d->inserts); | ||
| 681 | while (p[index].p != NULL) { | ||
| 682 | index = (index - 1) & mask; | ||
| 683 | STATS_INC(d->insert_collisions); | ||
| 684 | } | ||
| 685 | p[index] = d->r[i]; | ||
| 686 | } | ||
| 687 | } | ||
| 688 | /* avoid pages containing meta info to end up in cache */ | ||
| 689 | if (munmap(d->r, d->regions_total * sizeof(struct region_info))) | ||
| 690 | wrterror("munmap", d->r); | ||
| 691 | else | ||
| 692 | malloc_used -= d->regions_total * sizeof(struct region_info); | ||
| 693 | d->regions_free = d->regions_free + d->regions_total; | ||
| 694 | d->regions_total = newtotal; | ||
| 695 | d->r = p; | ||
| 696 | return 0; | ||
| 697 | } | ||
| 698 | |||
| 699 | static struct chunk_info * | ||
| 700 | alloc_chunk_info(struct dir_info *d, int bits) | ||
| 701 | { | ||
| 702 | struct chunk_info *p; | ||
| 703 | size_t size, count; | ||
| 704 | |||
| 705 | if (bits == 0) | ||
| 706 | count = MALLOC_PAGESIZE / MALLOC_MINSIZE; | ||
| 707 | else | ||
| 708 | count = MALLOC_PAGESIZE >> bits; | ||
| 709 | |||
| 710 | size = howmany(count, MALLOC_BITS); | ||
| 711 | size = sizeof(struct chunk_info) + (size - 1) * sizeof(u_short); | ||
| 712 | size = ALIGN(size); | ||
| 713 | |||
| 714 | if (LIST_EMPTY(&d->chunk_info_list[bits])) { | ||
| 715 | char *q; | ||
| 716 | int i; | ||
| 717 | |||
| 718 | q = MMAP(MALLOC_PAGESIZE); | ||
| 719 | if (q == MAP_FAILED) | ||
| 720 | return NULL; | ||
| 721 | malloc_used += MALLOC_PAGESIZE; | ||
| 722 | count = MALLOC_PAGESIZE / size; | ||
| 723 | for (i = 0; i < count; i++, q += size) | ||
| 724 | LIST_INSERT_HEAD(&d->chunk_info_list[bits], | ||
| 725 | (struct chunk_info *)q, entries); | ||
| 726 | } | ||
| 727 | p = LIST_FIRST(&d->chunk_info_list[bits]); | ||
| 728 | LIST_REMOVE(p, entries); | ||
| 729 | memset(p, 0, size); | ||
| 730 | p->canary = d->canary1; | ||
| 731 | return p; | ||
| 732 | } | ||
| 733 | |||
| 734 | |||
| 735 | /* | ||
| 736 | * The hashtable uses the assumption that p is never NULL. This holds since | ||
| 737 | * non-MAP_FIXED mappings with hint 0 start at BRKSIZ. | ||
| 738 | */ | ||
| 739 | static int | ||
| 740 | insert(struct dir_info *d, void *p, size_t sz, void *f) | ||
| 741 | { | ||
| 742 | size_t index; | ||
| 743 | size_t mask; | ||
| 744 | void *q; | ||
| 745 | |||
| 746 | if (d->regions_free * 4 < d->regions_total) { | ||
| 747 | if (omalloc_grow(d)) | ||
| 748 | return 1; | ||
| 749 | } | ||
| 750 | mask = d->regions_total - 1; | ||
| 751 | index = hash(p) & mask; | ||
| 752 | q = d->r[index].p; | ||
| 753 | STATS_INC(d->inserts); | ||
| 754 | while (q != NULL) { | ||
| 755 | index = (index - 1) & mask; | ||
| 756 | q = d->r[index].p; | ||
| 757 | STATS_INC(d->insert_collisions); | ||
| 758 | } | ||
| 759 | d->r[index].p = p; | ||
| 760 | d->r[index].size = sz; | ||
| 761 | #ifdef MALLOC_STATS | ||
| 762 | d->r[index].f = f; | ||
| 209 | #endif | 763 | #endif |
| 210 | return ((char *)(op + 1)); | 764 | d->regions_free--; |
| 765 | return 0; | ||
| 211 | } | 766 | } |
| 212 | 767 | ||
| 768 | static struct region_info * | ||
| 769 | find(struct dir_info *d, void *p) | ||
| 770 | { | ||
| 771 | size_t index; | ||
| 772 | size_t mask = d->regions_total - 1; | ||
| 773 | void *q, *r; | ||
| 774 | |||
| 775 | if (mopts.malloc_canary != (d->canary1 ^ (u_int32_t)(uintptr_t)d) || | ||
| 776 | d->canary1 != ~d->canary2) | ||
| 777 | wrterror("internal struct corrupt", NULL); | ||
| 778 | p = MASK_POINTER(p); | ||
| 779 | index = hash(p) & mask; | ||
| 780 | r = d->r[index].p; | ||
| 781 | q = MASK_POINTER(r); | ||
| 782 | STATS_INC(d->finds); | ||
| 783 | while (q != p && r != NULL) { | ||
| 784 | index = (index - 1) & mask; | ||
| 785 | r = d->r[index].p; | ||
| 786 | q = MASK_POINTER(r); | ||
| 787 | STATS_INC(d->find_collisions); | ||
| 788 | } | ||
| 789 | return (q == p && r != NULL) ? &d->r[index] : NULL; | ||
| 790 | } | ||
| 791 | |||
| 792 | static void | ||
| 793 | delete(struct dir_info *d, struct region_info *ri) | ||
| 794 | { | ||
| 795 | /* algorithm R, Knuth Vol III section 6.4 */ | ||
| 796 | size_t mask = d->regions_total - 1; | ||
| 797 | size_t i, j, r; | ||
| 798 | |||
| 799 | if (d->regions_total & (d->regions_total - 1)) | ||
| 800 | wrterror("regions_total not 2^x", NULL); | ||
| 801 | d->regions_free++; | ||
| 802 | STATS_INC(g_pool->deletes); | ||
| 803 | |||
| 804 | i = ri - d->r; | ||
| 805 | for (;;) { | ||
| 806 | d->r[i].p = NULL; | ||
| 807 | d->r[i].size = 0; | ||
| 808 | j = i; | ||
| 809 | for (;;) { | ||
| 810 | i = (i - 1) & mask; | ||
| 811 | if (d->r[i].p == NULL) | ||
| 812 | return; | ||
| 813 | r = hash(d->r[i].p) & mask; | ||
| 814 | if ((i <= r && r < j) || (r < j && j < i) || | ||
| 815 | (j < i && i <= r)) | ||
| 816 | continue; | ||
| 817 | d->r[j] = d->r[i]; | ||
| 818 | STATS_INC(g_pool->delete_moves); | ||
| 819 | break; | ||
| 820 | } | ||
| 821 | |||
| 822 | } | ||
| 823 | } | ||
| 824 | |||
| 213 | /* | 825 | /* |
| 214 | * Allocate more memory to the indicated bucket. | 826 | * Allocate a page of chunks |
| 215 | */ | 827 | */ |
| 216 | static void | 828 | static struct chunk_info * |
| 217 | morecore(bucket) | 829 | omalloc_make_chunks(struct dir_info *d, int bits) |
| 218 | int bucket; | ||
| 219 | { | 830 | { |
| 220 | register union overhead *op; | 831 | struct chunk_info *bp; |
| 221 | register long sz; /* size of desired block */ | 832 | void *pp; |
| 222 | long amt; /* amount to allocate */ | 833 | int i, k; |
| 223 | int nblks; /* how many blocks we get */ | ||
| 224 | 834 | ||
| 225 | /* | 835 | /* Allocate a new bucket */ |
| 226 | * sbrk_size <= 0 only for big, FLUFFY, requests (about | 836 | pp = map(d, MALLOC_PAGESIZE, 0); |
| 227 | * 2^30 bytes on a VAX, I think) or for a negative arg. | 837 | if (pp == MAP_FAILED) |
| 228 | */ | 838 | return NULL; |
| 229 | sz = 1 << (bucket + 3); | 839 | |
| 230 | #ifdef DEBUG | 840 | bp = alloc_chunk_info(d, bits); |
| 231 | ASSERT(sz > 0); | 841 | if (bp == NULL) { |
| 232 | #else | 842 | unmap(d, pp, MALLOC_PAGESIZE); |
| 233 | if (sz <= 0) | 843 | return NULL; |
| 234 | return; | 844 | } |
| 235 | #endif | 845 | |
| 236 | if (sz < pagesz) { | 846 | /* memory protect the page allocated in the malloc(0) case */ |
| 237 | amt = pagesz; | 847 | if (bits == 0) { |
| 238 | nblks = amt / sz; | 848 | bp->size = 0; |
| 849 | bp->shift = 1; | ||
| 850 | i = MALLOC_MINSIZE - 1; | ||
| 851 | while (i >>= 1) | ||
| 852 | bp->shift++; | ||
| 853 | bp->total = bp->free = MALLOC_PAGESIZE >> bp->shift; | ||
| 854 | bp->page = pp; | ||
| 855 | |||
| 856 | k = mprotect(pp, MALLOC_PAGESIZE, PROT_NONE); | ||
| 857 | if (k < 0) { | ||
| 858 | unmap(d, pp, MALLOC_PAGESIZE); | ||
| 859 | LIST_INSERT_HEAD(&d->chunk_info_list[0], bp, entries); | ||
| 860 | return NULL; | ||
| 861 | } | ||
| 239 | } else { | 862 | } else { |
| 240 | amt = sz + pagesz; | 863 | bp->size = 1U << bits; |
| 241 | nblks = 1; | 864 | bp->shift = bits; |
| 865 | bp->total = bp->free = MALLOC_PAGESIZE >> bits; | ||
| 866 | bp->page = pp; | ||
| 242 | } | 867 | } |
| 243 | op = (union overhead *)sbrk(amt); | 868 | |
| 244 | /* no more room! */ | 869 | /* set all valid bits in the bitmap */ |
| 245 | if ((long)op == -1) | 870 | k = bp->total; |
| 246 | return; | 871 | i = 0; |
| 247 | /* | 872 | |
| 248 | * Add new memory allocated to that on | 873 | /* Do a bunch at a time */ |
| 249 | * free list for this hash bucket. | 874 | for (; (k - i) >= MALLOC_BITS; i += MALLOC_BITS) |
| 250 | */ | 875 | bp->bits[i / MALLOC_BITS] = (u_short)~0U; |
| 251 | nextf[bucket] = op; | 876 | |
| 252 | while (--nblks > 0) { | 877 | for (; i < k; i++) |
| 253 | op->ov_next = (union overhead *)((caddr_t)op + sz); | 878 | bp->bits[i / MALLOC_BITS] |= (u_short)1U << (i % MALLOC_BITS); |
| 254 | op = (union overhead *)((caddr_t)op + sz); | 879 | |
| 255 | } | 880 | LIST_INSERT_HEAD(&d->chunk_dir[bits], bp, entries); |
| 881 | |||
| 882 | bits++; | ||
| 883 | if ((uintptr_t)pp & bits) | ||
| 884 | wrterror("pp & bits", pp); | ||
| 885 | |||
| 886 | insert(d, (void *)((uintptr_t)pp | bits), (uintptr_t)bp, NULL); | ||
| 887 | return bp; | ||
| 256 | } | 888 | } |
| 257 | 889 | ||
| 258 | void | 890 | |
| 259 | free(cp) | 891 | /* |
| 260 | void *cp; | 892 | * Allocate a chunk |
| 261 | { | 893 | */ |
| 262 | register long size; | 894 | static void * |
| 263 | register union overhead *op; | 895 | malloc_bytes(struct dir_info *d, size_t size, void *f) |
| 264 | 896 | { | |
| 265 | if (cp == NULL) | 897 | int i, j; |
| 266 | return; | 898 | size_t k; |
| 267 | op = (union overhead *)((caddr_t)cp - sizeof (union overhead)); | 899 | u_short u, *lp; |
| 268 | #ifdef DEBUG | 900 | struct chunk_info *bp; |
| 269 | ASSERT(op->ov_magic == MAGIC); /* make sure it was in use */ | 901 | |
| 270 | #else | 902 | if (mopts.malloc_canary != (d->canary1 ^ (u_int32_t)(uintptr_t)d) || |
| 271 | if (op->ov_magic != MAGIC) | 903 | d->canary1 != ~d->canary2) |
| 272 | return; /* sanity */ | 904 | wrterror("internal struct corrupt", NULL); |
| 273 | #endif | 905 | /* Don't bother with anything less than this */ |
| 274 | #ifdef RCHECK | 906 | /* unless we have a malloc(0) requests */ |
| 275 | ASSERT(op->ov_rmagic == RMAGIC); | 907 | if (size != 0 && size < MALLOC_MINSIZE) |
| 276 | ASSERT(*(u_short *)((caddr_t)(op + 1) + op->ov_size) == RMAGIC); | 908 | size = MALLOC_MINSIZE; |
| 277 | #endif | 909 | |
| 278 | size = op->ov_index; | 910 | /* Find the right bucket */ |
| 279 | ASSERT(size < NBUCKETS); | 911 | if (size == 0) |
| 280 | op->ov_next = nextf[size]; /* also clobbers ov_magic */ | 912 | j = 0; |
| 281 | nextf[size] = op; | 913 | else { |
| 282 | #ifdef MSTATS | 914 | j = MALLOC_MINSHIFT; |
| 283 | nmalloc[size]--; | 915 | i = (size - 1) >> (MALLOC_MINSHIFT - 1); |
| 916 | while (i >>= 1) | ||
| 917 | j++; | ||
| 918 | } | ||
| 919 | |||
| 920 | /* If it's empty, make a page more of that size chunks */ | ||
| 921 | if (LIST_EMPTY(&d->chunk_dir[j])) { | ||
| 922 | bp = omalloc_make_chunks(d, j); | ||
| 923 | if (bp == NULL) | ||
| 924 | return NULL; | ||
| 925 | } else | ||
| 926 | bp = LIST_FIRST(&d->chunk_dir[j]); | ||
| 927 | |||
| 928 | if (bp->canary != d->canary1) | ||
| 929 | wrterror("chunk info corrupted", NULL); | ||
| 930 | |||
| 931 | i = d->chunk_start; | ||
| 932 | if (bp->free > 1) | ||
| 933 | i += getrnibble(); | ||
| 934 | if (i >= bp->total) | ||
| 935 | i &= bp->total - 1; | ||
| 936 | for (;;) { | ||
| 937 | for (;;) { | ||
| 938 | lp = &bp->bits[i / MALLOC_BITS]; | ||
| 939 | if (!*lp) { | ||
| 940 | i += MALLOC_BITS; | ||
| 941 | i &= ~(MALLOC_BITS - 1); | ||
| 942 | if (i >= bp->total) | ||
| 943 | i = 0; | ||
| 944 | } else | ||
| 945 | break; | ||
| 946 | } | ||
| 947 | k = i % MALLOC_BITS; | ||
| 948 | u = 1 << k; | ||
| 949 | if (*lp & u) | ||
| 950 | break; | ||
| 951 | if (++i >= bp->total) | ||
| 952 | i = 0; | ||
| 953 | } | ||
| 954 | d->chunk_start += i + 1; | ||
| 955 | #ifdef MALLOC_STATS | ||
| 956 | if (i == 0) { | ||
| 957 | struct region_info *r = find(d, bp->page); | ||
| 958 | r->f = f; | ||
| 959 | } | ||
| 284 | #endif | 960 | #endif |
| 961 | |||
| 962 | *lp ^= u; | ||
| 963 | |||
| 964 | /* If there are no more free, remove from free-list */ | ||
| 965 | if (!--bp->free) | ||
| 966 | LIST_REMOVE(bp, entries); | ||
| 967 | |||
| 968 | /* Adjust to the real offset of that chunk */ | ||
| 969 | k += (lp - bp->bits) * MALLOC_BITS; | ||
| 970 | k <<= bp->shift; | ||
| 971 | |||
| 972 | if (mopts.malloc_junk && bp->size > 0) | ||
| 973 | memset((char *)bp->page + k, SOME_JUNK, bp->size); | ||
| 974 | return ((char *)bp->page + k); | ||
| 975 | } | ||
| 976 | |||
| 977 | |||
| 978 | /* | ||
| 979 | * Free a chunk, and possibly the page it's on, if the page becomes empty. | ||
| 980 | */ | ||
| 981 | static void | ||
| 982 | free_bytes(struct dir_info *d, struct region_info *r, void *ptr) | ||
| 983 | { | ||
| 984 | struct chunk_head *mp; | ||
| 985 | struct chunk_info *info; | ||
| 986 | int i; | ||
| 987 | |||
| 988 | info = (struct chunk_info *)r->size; | ||
| 989 | if (info->canary != d->canary1) | ||
| 990 | wrterror("chunk info corrupted", NULL); | ||
| 991 | |||
| 992 | /* Find the chunk number on the page */ | ||
| 993 | i = ((uintptr_t)ptr & MALLOC_PAGEMASK) >> info->shift; | ||
| 994 | |||
| 995 | if ((uintptr_t)ptr & ((1U << (info->shift)) - 1)) { | ||
| 996 | wrterror("modified chunk-pointer", ptr); | ||
| 997 | return; | ||
| 998 | } | ||
| 999 | if (info->bits[i / MALLOC_BITS] & (1U << (i % MALLOC_BITS))) { | ||
| 1000 | wrterror("chunk is already free", ptr); | ||
| 1001 | return; | ||
| 1002 | } | ||
| 1003 | |||
| 1004 | info->bits[i / MALLOC_BITS] |= 1U << (i % MALLOC_BITS); | ||
| 1005 | info->free++; | ||
| 1006 | |||
| 1007 | if (info->size != 0) | ||
| 1008 | mp = d->chunk_dir + info->shift; | ||
| 1009 | else | ||
| 1010 | mp = d->chunk_dir; | ||
| 1011 | |||
| 1012 | if (info->free == 1) { | ||
| 1013 | /* Page became non-full */ | ||
| 1014 | LIST_INSERT_HEAD(mp, info, entries); | ||
| 1015 | return; | ||
| 1016 | } | ||
| 1017 | if (info->free != info->total) | ||
| 1018 | return; | ||
| 1019 | |||
| 1020 | LIST_REMOVE(info, entries); | ||
| 1021 | |||
| 1022 | if (info->size == 0 && !mopts.malloc_freeunmap) | ||
| 1023 | mprotect(info->page, MALLOC_PAGESIZE, PROT_READ | PROT_WRITE); | ||
| 1024 | unmap(d, info->page, MALLOC_PAGESIZE); | ||
| 1025 | |||
| 1026 | delete(d, r); | ||
| 1027 | if (info->size != 0) | ||
| 1028 | mp = &d->chunk_info_list[info->shift]; | ||
| 1029 | else | ||
| 1030 | mp = &d->chunk_info_list[0]; | ||
| 1031 | LIST_INSERT_HEAD(mp, info, entries); | ||
| 1032 | } | ||
| 1033 | |||
| 1034 | |||
| 1035 | |||
| 1036 | static void * | ||
| 1037 | omalloc(size_t sz, int zero_fill, void *f) | ||
| 1038 | { | ||
| 1039 | void *p; | ||
| 1040 | size_t psz; | ||
| 1041 | |||
| 1042 | if (sz > MALLOC_MAXCHUNK) { | ||
| 1043 | if (sz >= SIZE_MAX - mopts.malloc_guard - MALLOC_PAGESIZE) { | ||
| 1044 | errno = ENOMEM; | ||
| 1045 | return NULL; | ||
| 1046 | } | ||
| 1047 | sz += mopts.malloc_guard; | ||
| 1048 | psz = PAGEROUND(sz); | ||
| 1049 | p = map(g_pool, psz, zero_fill); | ||
| 1050 | if (p == MAP_FAILED) { | ||
| 1051 | errno = ENOMEM; | ||
| 1052 | return NULL; | ||
| 1053 | } | ||
| 1054 | if (insert(g_pool, p, sz, f)) { | ||
| 1055 | unmap(g_pool, p, psz); | ||
| 1056 | errno = ENOMEM; | ||
| 1057 | return NULL; | ||
| 1058 | } | ||
| 1059 | if (mopts.malloc_guard) { | ||
| 1060 | if (mprotect((char *)p + psz - mopts.malloc_guard, | ||
| 1061 | mopts.malloc_guard, PROT_NONE)) | ||
| 1062 | wrterror("mprotect", NULL); | ||
| 1063 | malloc_guarded += mopts.malloc_guard; | ||
| 1064 | } | ||
| 1065 | |||
| 1066 | if (mopts.malloc_move && | ||
| 1067 | sz - mopts.malloc_guard < MALLOC_PAGESIZE - | ||
| 1068 | MALLOC_LEEWAY) { | ||
| 1069 | /* fill whole allocation */ | ||
| 1070 | if (mopts.malloc_junk) | ||
| 1071 | memset(p, SOME_JUNK, psz - mopts.malloc_guard); | ||
| 1072 | /* shift towards the end */ | ||
| 1073 | p = ((char *)p) + ((MALLOC_PAGESIZE - MALLOC_LEEWAY - | ||
| 1074 | (sz - mopts.malloc_guard)) & ~(MALLOC_MINSIZE-1)); | ||
| 1075 | /* fill zeros if needed and overwritten above */ | ||
| 1076 | if (zero_fill && mopts.malloc_junk) | ||
| 1077 | memset(p, 0, sz - mopts.malloc_guard); | ||
| 1078 | } else { | ||
| 1079 | if (mopts.malloc_junk) { | ||
| 1080 | if (zero_fill) | ||
| 1081 | memset((char *)p + sz - mopts.malloc_guard, | ||
| 1082 | SOME_JUNK, psz - sz); | ||
| 1083 | else | ||
| 1084 | memset(p, SOME_JUNK, | ||
| 1085 | psz - mopts.malloc_guard); | ||
| 1086 | } | ||
| 1087 | } | ||
| 1088 | |||
| 1089 | } else { | ||
| 1090 | /* takes care of SOME_JUNK */ | ||
| 1091 | p = malloc_bytes(g_pool, sz, f); | ||
| 1092 | if (zero_fill && p != NULL && sz > 0) | ||
| 1093 | memset(p, 0, sz); | ||
| 1094 | } | ||
| 1095 | |||
| 1096 | return p; | ||
| 285 | } | 1097 | } |
| 286 | 1098 | ||
| 287 | /* | 1099 | /* |
| 288 | * When a program attempts "storage compaction" as mentioned in the | 1100 | * Common function for handling recursion. Only |
| 289 | * old malloc man page, it realloc's an already freed block. Usually | 1101 | * print the error message once, to avoid making the problem |
| 290 | * this is the last block it freed; occasionally it might be farther | 1102 | * potentially worse. |
| 291 | * back. We have to search all the free lists for the block in order | ||
| 292 | * to determine its bucket: 1st we make one pass thru the lists | ||
| 293 | * checking only the first block in each; if that fails we search | ||
| 294 | * ``realloc_srchlen'' blocks in each list for a match (the variable | ||
| 295 | * is extern so the caller can modify it). If that fails we just copy | ||
| 296 | * however many bytes was given to realloc() and hope it's not huge. | ||
| 297 | */ | 1103 | */ |
| 298 | int realloc_srchlen = 4; /* 4 should be plenty, -1 =>'s whole list */ | 1104 | static void |
| 1105 | malloc_recurse(void) | ||
| 1106 | { | ||
| 1107 | static int noprint; | ||
| 1108 | |||
| 1109 | if (noprint == 0) { | ||
| 1110 | noprint = 1; | ||
| 1111 | wrterror("recursive call", NULL); | ||
| 1112 | } | ||
| 1113 | malloc_active--; | ||
| 1114 | _MALLOC_UNLOCK(); | ||
| 1115 | errno = EDEADLK; | ||
| 1116 | } | ||
| 1117 | |||
| 1118 | static int | ||
| 1119 | malloc_init(void) | ||
| 1120 | { | ||
| 1121 | if (omalloc_init(&g_pool)) { | ||
| 1122 | _MALLOC_UNLOCK(); | ||
| 1123 | if (mopts.malloc_xmalloc) | ||
| 1124 | wrterror("out of memory", NULL); | ||
| 1125 | errno = ENOMEM; | ||
| 1126 | return -1; | ||
| 1127 | } | ||
| 1128 | return 0; | ||
| 1129 | } | ||
| 299 | 1130 | ||
| 300 | void * | 1131 | void * |
| 301 | realloc(cp, nbytes) | 1132 | malloc(size_t size) |
| 302 | void *cp; | 1133 | { |
| 303 | size_t nbytes; | 1134 | void *r; |
| 304 | { | 1135 | int saved_errno = errno; |
| 305 | register u_long onb; | 1136 | |
| 306 | register long i; | 1137 | _MALLOC_LOCK(); |
| 307 | union overhead *op; | 1138 | malloc_func = " in malloc():"; |
| 308 | char *res; | 1139 | if (g_pool == NULL) { |
| 309 | int was_alloced = 0; | 1140 | if (malloc_init() != 0) |
| 310 | 1141 | return NULL; | |
| 311 | if (cp == NULL) | 1142 | } |
| 312 | return (malloc(nbytes)); | 1143 | if (malloc_active++) { |
| 313 | op = (union overhead *)((caddr_t)cp - sizeof (union overhead)); | 1144 | malloc_recurse(); |
| 314 | if (op->ov_magic == MAGIC) { | 1145 | return NULL; |
| 315 | was_alloced++; | 1146 | } |
| 316 | i = op->ov_index; | 1147 | r = omalloc(size, mopts.malloc_zero, CALLER); |
| 1148 | malloc_active--; | ||
| 1149 | _MALLOC_UNLOCK(); | ||
| 1150 | if (r == NULL && mopts.malloc_xmalloc) { | ||
| 1151 | wrterror("out of memory", NULL); | ||
| 1152 | errno = ENOMEM; | ||
| 1153 | } | ||
| 1154 | if (r != NULL) | ||
| 1155 | errno = saved_errno; | ||
| 1156 | return r; | ||
| 1157 | } | ||
| 1158 | |||
| 1159 | static void | ||
| 1160 | ofree(void *p) | ||
| 1161 | { | ||
| 1162 | struct region_info *r; | ||
| 1163 | size_t sz; | ||
| 1164 | |||
| 1165 | r = find(g_pool, p); | ||
| 1166 | if (r == NULL) { | ||
| 1167 | wrterror("bogus pointer (double free?)", p); | ||
| 1168 | return; | ||
| 1169 | } | ||
| 1170 | REALSIZE(sz, r); | ||
| 1171 | if (sz > MALLOC_MAXCHUNK) { | ||
| 1172 | if (sz - mopts.malloc_guard >= MALLOC_PAGESIZE - | ||
| 1173 | MALLOC_LEEWAY) { | ||
| 1174 | if (r->p != p) { | ||
| 1175 | wrterror("bogus pointer", p); | ||
| 1176 | return; | ||
| 1177 | } | ||
| 1178 | } else { | ||
| 1179 | #if notyetbecause_of_realloc | ||
| 1180 | /* shifted towards the end */ | ||
| 1181 | if (p != ((char *)r->p) + ((MALLOC_PAGESIZE - | ||
| 1182 | MALLOC_MINSIZE - sz - mopts.malloc_guard) & | ||
| 1183 | ~(MALLOC_MINSIZE-1))) { | ||
| 1184 | } | ||
| 1185 | #endif | ||
| 1186 | p = r->p; | ||
| 1187 | } | ||
| 1188 | if (mopts.malloc_guard) { | ||
| 1189 | if (sz < mopts.malloc_guard) | ||
| 1190 | wrterror("guard size", NULL); | ||
| 1191 | if (!mopts.malloc_freeunmap) { | ||
| 1192 | if (mprotect((char *)p + PAGEROUND(sz) - | ||
| 1193 | mopts.malloc_guard, mopts.malloc_guard, | ||
| 1194 | PROT_READ | PROT_WRITE)) | ||
| 1195 | wrterror("mprotect", NULL); | ||
| 1196 | } | ||
| 1197 | malloc_guarded -= mopts.malloc_guard; | ||
| 1198 | } | ||
| 1199 | if (mopts.malloc_junk && !mopts.malloc_freeunmap) | ||
| 1200 | memset(p, SOME_FREEJUNK, | ||
| 1201 | PAGEROUND(sz) - mopts.malloc_guard); | ||
| 1202 | unmap(g_pool, p, PAGEROUND(sz)); | ||
| 1203 | delete(g_pool, r); | ||
| 1204 | } else { | ||
| 1205 | void *tmp; | ||
| 1206 | int i; | ||
| 1207 | |||
| 1208 | if (mopts.malloc_junk && sz > 0) | ||
| 1209 | memset(p, SOME_FREEJUNK, sz); | ||
| 1210 | if (!mopts.malloc_freenow) { | ||
| 1211 | i = getrnibble(); | ||
| 1212 | tmp = p; | ||
| 1213 | p = g_pool->delayed_chunks[i]; | ||
| 1214 | g_pool->delayed_chunks[i] = tmp; | ||
| 1215 | } | ||
| 1216 | if (p != NULL) { | ||
| 1217 | r = find(g_pool, p); | ||
| 1218 | if (r == NULL) { | ||
| 1219 | wrterror("bogus pointer (double free?)", p); | ||
| 1220 | return; | ||
| 1221 | } | ||
| 1222 | free_bytes(g_pool, r, p); | ||
| 1223 | } | ||
| 1224 | } | ||
| 1225 | } | ||
| 1226 | |||
| 1227 | void | ||
| 1228 | free(void *ptr) | ||
| 1229 | { | ||
| 1230 | int saved_errno = errno; | ||
| 1231 | |||
| 1232 | /* This is legal. */ | ||
| 1233 | if (ptr == NULL) | ||
| 1234 | return; | ||
| 1235 | |||
| 1236 | _MALLOC_LOCK(); | ||
| 1237 | malloc_func = " in free():"; | ||
| 1238 | if (g_pool == NULL) { | ||
| 1239 | _MALLOC_UNLOCK(); | ||
| 1240 | wrterror("free() called before allocation", NULL); | ||
| 1241 | return; | ||
| 1242 | } | ||
| 1243 | if (malloc_active++) { | ||
| 1244 | malloc_recurse(); | ||
| 1245 | return; | ||
| 1246 | } | ||
| 1247 | ofree(ptr); | ||
| 1248 | malloc_active--; | ||
| 1249 | _MALLOC_UNLOCK(); | ||
| 1250 | errno = saved_errno; | ||
| 1251 | } | ||
| 1252 | |||
| 1253 | |||
| 1254 | static void * | ||
| 1255 | orealloc(void *p, size_t newsz, void *f) | ||
| 1256 | { | ||
| 1257 | struct region_info *r; | ||
| 1258 | size_t oldsz, goldsz, gnewsz; | ||
| 1259 | void *q; | ||
| 1260 | |||
| 1261 | if (p == NULL) | ||
| 1262 | return omalloc(newsz, 0, f); | ||
| 1263 | |||
| 1264 | r = find(g_pool, p); | ||
| 1265 | if (r == NULL) { | ||
| 1266 | wrterror("bogus pointer (double free?)", p); | ||
| 1267 | return NULL; | ||
| 1268 | } | ||
| 1269 | if (newsz >= SIZE_MAX - mopts.malloc_guard - MALLOC_PAGESIZE) { | ||
| 1270 | errno = ENOMEM; | ||
| 1271 | return NULL; | ||
| 1272 | } | ||
| 1273 | |||
| 1274 | REALSIZE(oldsz, r); | ||
| 1275 | goldsz = oldsz; | ||
| 1276 | if (oldsz > MALLOC_MAXCHUNK) { | ||
| 1277 | if (oldsz < mopts.malloc_guard) | ||
| 1278 | wrterror("guard size", NULL); | ||
| 1279 | oldsz -= mopts.malloc_guard; | ||
| 1280 | } | ||
| 1281 | |||
| 1282 | gnewsz = newsz; | ||
| 1283 | if (gnewsz > MALLOC_MAXCHUNK) | ||
| 1284 | gnewsz += mopts.malloc_guard; | ||
| 1285 | |||
| 1286 | if (newsz > MALLOC_MAXCHUNK && oldsz > MALLOC_MAXCHUNK && p == r->p && | ||
| 1287 | !mopts.malloc_realloc) { | ||
| 1288 | size_t roldsz = PAGEROUND(goldsz); | ||
| 1289 | size_t rnewsz = PAGEROUND(gnewsz); | ||
| 1290 | |||
| 1291 | if (rnewsz > roldsz) { | ||
| 1292 | if (!mopts.malloc_guard) { | ||
| 1293 | void *hint = (char *)p + roldsz; | ||
| 1294 | size_t needed = rnewsz - roldsz; | ||
| 1295 | |||
| 1296 | STATS_INC(g_pool->cheap_realloc_tries); | ||
| 1297 | zapcacheregion(g_pool, hint, needed); | ||
| 1298 | q = MQUERY(hint, needed); | ||
| 1299 | if (q == hint) | ||
| 1300 | q = MMAPA(hint, needed); | ||
| 1301 | else | ||
| 1302 | q = MAP_FAILED; | ||
| 1303 | if (q == hint) { | ||
| 1304 | malloc_used += needed; | ||
| 1305 | if (mopts.malloc_junk) | ||
| 1306 | memset(q, SOME_JUNK, needed); | ||
| 1307 | r->size = newsz; | ||
| 1308 | STATS_SETF(r, f); | ||
| 1309 | STATS_INC(g_pool->cheap_reallocs); | ||
| 1310 | return p; | ||
| 1311 | } else if (q != MAP_FAILED) { | ||
| 1312 | if (munmap(q, needed)) | ||
| 1313 | wrterror("munmap", q); | ||
| 1314 | } | ||
| 1315 | } | ||
| 1316 | } else if (rnewsz < roldsz) { | ||
| 1317 | if (mopts.malloc_guard) { | ||
| 1318 | if (mprotect((char *)p + roldsz - | ||
| 1319 | mopts.malloc_guard, mopts.malloc_guard, | ||
| 1320 | PROT_READ | PROT_WRITE)) | ||
| 1321 | wrterror("mprotect", NULL); | ||
| 1322 | if (mprotect((char *)p + rnewsz - | ||
| 1323 | mopts.malloc_guard, mopts.malloc_guard, | ||
| 1324 | PROT_NONE)) | ||
| 1325 | wrterror("mprotect", NULL); | ||
| 1326 | } | ||
| 1327 | unmap(g_pool, (char *)p + rnewsz, roldsz - rnewsz); | ||
| 1328 | r->size = gnewsz; | ||
| 1329 | STATS_SETF(r, f); | ||
| 1330 | return p; | ||
| 1331 | } else { | ||
| 1332 | if (newsz > oldsz && mopts.malloc_junk) | ||
| 1333 | memset((char *)p + newsz, SOME_JUNK, | ||
| 1334 | rnewsz - mopts.malloc_guard - newsz); | ||
| 1335 | r->size = gnewsz; | ||
| 1336 | STATS_SETF(r, f); | ||
| 1337 | return p; | ||
| 1338 | } | ||
| 1339 | } | ||
| 1340 | if (newsz <= oldsz && newsz > oldsz / 2 && !mopts.malloc_realloc) { | ||
| 1341 | if (mopts.malloc_junk && newsz > 0) | ||
| 1342 | memset((char *)p + newsz, SOME_JUNK, oldsz - newsz); | ||
| 1343 | STATS_SETF(r, f); | ||
| 1344 | return p; | ||
| 1345 | } else if (newsz != oldsz || mopts.malloc_realloc) { | ||
| 1346 | q = omalloc(newsz, 0, f); | ||
| 1347 | if (q == NULL) | ||
| 1348 | return NULL; | ||
| 1349 | if (newsz != 0 && oldsz != 0) | ||
| 1350 | memcpy(q, p, oldsz < newsz ? oldsz : newsz); | ||
| 1351 | ofree(p); | ||
| 1352 | return q; | ||
| 317 | } else { | 1353 | } else { |
| 1354 | STATS_SETF(r, f); | ||
| 1355 | return p; | ||
| 1356 | } | ||
| 1357 | } | ||
| 1358 | |||
| 1359 | void * | ||
| 1360 | realloc(void *ptr, size_t size) | ||
| 1361 | { | ||
| 1362 | void *r; | ||
| 1363 | int saved_errno = errno; | ||
| 1364 | |||
| 1365 | _MALLOC_LOCK(); | ||
| 1366 | malloc_func = " in realloc():"; | ||
| 1367 | if (g_pool == NULL) { | ||
| 1368 | if (malloc_init() != 0) | ||
| 1369 | return NULL; | ||
| 1370 | } | ||
| 1371 | if (malloc_active++) { | ||
| 1372 | malloc_recurse(); | ||
| 1373 | return NULL; | ||
| 1374 | } | ||
| 1375 | r = orealloc(ptr, size, CALLER); | ||
| 1376 | |||
| 1377 | malloc_active--; | ||
| 1378 | _MALLOC_UNLOCK(); | ||
| 1379 | if (r == NULL && mopts.malloc_xmalloc) { | ||
| 1380 | wrterror("out of memory", NULL); | ||
| 1381 | errno = ENOMEM; | ||
| 1382 | } | ||
| 1383 | if (r != NULL) | ||
| 1384 | errno = saved_errno; | ||
| 1385 | return r; | ||
| 1386 | } | ||
| 1387 | |||
| 1388 | |||
| 1389 | #define MUL_NO_OVERFLOW (1UL << (sizeof(size_t) * 4)) | ||
| 1390 | |||
| 1391 | void * | ||
| 1392 | calloc(size_t nmemb, size_t size) | ||
| 1393 | { | ||
| 1394 | void *r; | ||
| 1395 | int saved_errno = errno; | ||
| 1396 | |||
| 1397 | _MALLOC_LOCK(); | ||
| 1398 | malloc_func = " in calloc():"; | ||
| 1399 | if (g_pool == NULL) { | ||
| 1400 | if (malloc_init() != 0) | ||
| 1401 | return NULL; | ||
| 1402 | } | ||
| 1403 | if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && | ||
| 1404 | nmemb > 0 && SIZE_MAX / nmemb < size) { | ||
| 1405 | _MALLOC_UNLOCK(); | ||
| 1406 | if (mopts.malloc_xmalloc) | ||
| 1407 | wrterror("out of memory", NULL); | ||
| 1408 | errno = ENOMEM; | ||
| 1409 | return NULL; | ||
| 1410 | } | ||
| 1411 | |||
| 1412 | if (malloc_active++) { | ||
| 1413 | malloc_recurse(); | ||
| 1414 | return NULL; | ||
| 1415 | } | ||
| 1416 | |||
| 1417 | size *= nmemb; | ||
| 1418 | r = omalloc(size, 1, CALLER); | ||
| 1419 | |||
| 1420 | malloc_active--; | ||
| 1421 | _MALLOC_UNLOCK(); | ||
| 1422 | if (r == NULL && mopts.malloc_xmalloc) { | ||
| 1423 | wrterror("out of memory", NULL); | ||
| 1424 | errno = ENOMEM; | ||
| 1425 | } | ||
| 1426 | if (r != NULL) | ||
| 1427 | errno = saved_errno; | ||
| 1428 | return r; | ||
| 1429 | } | ||
| 1430 | |||
| 1431 | static void * | ||
| 1432 | mapalign(struct dir_info *d, size_t alignment, size_t sz, int zero_fill) | ||
| 1433 | { | ||
| 1434 | char *p, *q; | ||
| 1435 | |||
| 1436 | if (alignment < MALLOC_PAGESIZE || ((alignment - 1) & alignment) != 0) { | ||
| 1437 | wrterror("mapalign bad alignment", NULL); | ||
| 1438 | return MAP_FAILED; | ||
| 1439 | } | ||
| 1440 | if (sz != PAGEROUND(sz)) { | ||
| 1441 | wrterror("mapalign round", NULL); | ||
| 1442 | return MAP_FAILED; | ||
| 1443 | } | ||
| 1444 | |||
| 1445 | /* Allocate sz + alignment bytes of memory, which must include a | ||
| 1446 | * subrange of size bytes that is properly aligned. Unmap the | ||
| 1447 | * other bytes, and then return that subrange. | ||
| 1448 | */ | ||
| 1449 | |||
| 1450 | /* We need sz + alignment to fit into a size_t. */ | ||
| 1451 | if (alignment > SIZE_MAX - sz) | ||
| 1452 | return MAP_FAILED; | ||
| 1453 | |||
| 1454 | p = map(d, sz + alignment, zero_fill); | ||
| 1455 | if (p == MAP_FAILED) | ||
| 1456 | return MAP_FAILED; | ||
| 1457 | q = (char *)(((uintptr_t)p + alignment - 1) & ~(alignment - 1)); | ||
| 1458 | if (q != p) { | ||
| 1459 | if (munmap(p, q - p)) | ||
| 1460 | wrterror("munmap", p); | ||
| 1461 | } | ||
| 1462 | if (munmap(q + sz, alignment - (q - p))) | ||
| 1463 | wrterror("munmap", q + sz); | ||
| 1464 | malloc_used -= alignment; | ||
| 1465 | |||
| 1466 | return q; | ||
| 1467 | } | ||
| 1468 | |||
| 1469 | static void * | ||
| 1470 | omemalign(size_t alignment, size_t sz, int zero_fill, void *f) | ||
| 1471 | { | ||
| 1472 | size_t psz; | ||
| 1473 | void *p; | ||
| 1474 | |||
| 1475 | if (alignment <= MALLOC_PAGESIZE) { | ||
| 318 | /* | 1476 | /* |
| 319 | * Already free, doing "compaction". | 1477 | * max(size, alignment) is enough to assure the requested alignment, |
| 320 | * | 1478 | * since the allocator always allocates power-of-two blocks. |
| 321 | * Search for the old block of memory on the | ||
| 322 | * free list. First, check the most common | ||
| 323 | * case (last element free'd), then (this failing) | ||
| 324 | * the last ``realloc_srchlen'' items free'd. | ||
| 325 | * If all lookups fail, then assume the size of | ||
| 326 | * the memory block being realloc'd is the | ||
| 327 | * largest possible (so that all "nbytes" of new | ||
| 328 | * memory are copied into). Note that this could cause | ||
| 329 | * a memory fault if the old area was tiny, and the moon | ||
| 330 | * is gibbous. However, that is very unlikely. | ||
| 331 | */ | 1479 | */ |
| 332 | if ((i = findbucket(op, 1)) < 0 && | 1480 | if (sz < alignment) |
| 333 | (i = findbucket(op, realloc_srchlen)) < 0) | 1481 | sz = alignment; |
| 334 | i = NBUCKETS; | 1482 | return omalloc(sz, zero_fill, f); |
| 335 | } | 1483 | } |
| 336 | onb = 1 << (i + 3); | 1484 | |
| 337 | if (onb < pagesz) | 1485 | if (sz >= SIZE_MAX - mopts.malloc_guard - MALLOC_PAGESIZE) { |
| 338 | onb -= sizeof (*op) + RSLOP; | 1486 | errno = ENOMEM; |
| 339 | else | 1487 | return NULL; |
| 340 | onb += pagesz - sizeof (*op) - RSLOP; | 1488 | } |
| 341 | /* avoid the copy if same size block */ | 1489 | |
| 342 | if (was_alloced) { | 1490 | sz += mopts.malloc_guard; |
| 343 | if (i) { | 1491 | psz = PAGEROUND(sz); |
| 344 | i = 1 << (i + 2); | 1492 | |
| 345 | if (i < pagesz) | 1493 | p = mapalign(g_pool, alignment, psz, zero_fill); |
| 346 | i -= sizeof (*op) + RSLOP; | 1494 | if (p == NULL) { |
| 347 | else | 1495 | errno = ENOMEM; |
| 348 | i += pagesz - sizeof (*op) - RSLOP; | 1496 | return NULL; |
| 1497 | } | ||
| 1498 | |||
| 1499 | if (insert(g_pool, p, sz, f)) { | ||
| 1500 | unmap(g_pool, p, psz); | ||
| 1501 | errno = ENOMEM; | ||
| 1502 | return NULL; | ||
| 1503 | } | ||
| 1504 | |||
| 1505 | if (mopts.malloc_guard) { | ||
| 1506 | if (mprotect((char *)p + psz - mopts.malloc_guard, | ||
| 1507 | mopts.malloc_guard, PROT_NONE)) | ||
| 1508 | wrterror("mprotect", NULL); | ||
| 1509 | malloc_guarded += mopts.malloc_guard; | ||
| 1510 | } | ||
| 1511 | |||
| 1512 | if (mopts.malloc_junk) { | ||
| 1513 | if (zero_fill) | ||
| 1514 | memset((char *)p + sz - mopts.malloc_guard, | ||
| 1515 | SOME_JUNK, psz - sz); | ||
| 1516 | else | ||
| 1517 | memset(p, SOME_JUNK, psz - mopts.malloc_guard); | ||
| 1518 | } | ||
| 1519 | |||
| 1520 | return p; | ||
| 1521 | } | ||
| 1522 | |||
| 1523 | int | ||
| 1524 | posix_memalign(void **memptr, size_t alignment, size_t size) | ||
| 1525 | { | ||
| 1526 | int res, saved_errno = errno; | ||
| 1527 | void *r; | ||
| 1528 | |||
| 1529 | /* Make sure that alignment is a large enough power of 2. */ | ||
| 1530 | if (((alignment - 1) & alignment) != 0 || alignment < sizeof(void *)) | ||
| 1531 | return EINVAL; | ||
| 1532 | |||
| 1533 | _MALLOC_LOCK(); | ||
| 1534 | malloc_func = " in posix_memalign():"; | ||
| 1535 | if (g_pool == NULL) { | ||
| 1536 | if (malloc_init() != 0) | ||
| 1537 | goto err; | ||
| 1538 | } | ||
| 1539 | if (malloc_active++) { | ||
| 1540 | malloc_recurse(); | ||
| 1541 | goto err; | ||
| 1542 | } | ||
| 1543 | r = omemalign(alignment, size, mopts.malloc_zero, CALLER); | ||
| 1544 | malloc_active--; | ||
| 1545 | _MALLOC_UNLOCK(); | ||
| 1546 | if (r == NULL) { | ||
| 1547 | if (mopts.malloc_xmalloc) { | ||
| 1548 | wrterror("out of memory", NULL); | ||
| 1549 | errno = ENOMEM; | ||
| 349 | } | 1550 | } |
| 350 | if (nbytes <= onb && nbytes > i) { | 1551 | goto err; |
| 351 | #ifdef RCHECK | ||
| 352 | op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1); | ||
| 353 | *(u_short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC; | ||
| 354 | #endif | ||
| 355 | return(cp); | ||
| 356 | } else | ||
| 357 | free(cp); | ||
| 358 | } | 1552 | } |
| 359 | if ((res = malloc(nbytes)) == NULL) | 1553 | errno = saved_errno; |
| 360 | return (NULL); | 1554 | *memptr = r; |
| 361 | if (cp != res) /* common optimization if "compacting" */ | 1555 | return 0; |
| 362 | bcopy(cp, res, (nbytes < onb) ? nbytes : onb); | 1556 | |
| 363 | return (res); | 1557 | err: |
| 1558 | res = errno; | ||
| 1559 | errno = saved_errno; | ||
| 1560 | return res; | ||
| 364 | } | 1561 | } |
| 365 | 1562 | ||
| 366 | /* | 1563 | #ifdef MALLOC_STATS |
| 367 | * Search ``srchlen'' elements of each free list for a block whose | 1564 | |
| 368 | * header starts at ``freep''. If srchlen is -1 search the whole list. | 1565 | struct malloc_leak { |
| 369 | * Return bucket number, or -1 if not found. | 1566 | void (*f)(); |
| 370 | */ | 1567 | size_t total_size; |
| 371 | static | 1568 | int count; |
| 372 | findbucket(freep, srchlen) | 1569 | }; |
| 373 | union overhead *freep; | 1570 | |
| 374 | int srchlen; | 1571 | struct leaknode { |
| 1572 | RB_ENTRY(leaknode) entry; | ||
| 1573 | struct malloc_leak d; | ||
| 1574 | }; | ||
| 1575 | |||
| 1576 | static int | ||
| 1577 | leakcmp(struct leaknode *e1, struct leaknode *e2) | ||
| 375 | { | 1578 | { |
| 376 | register union overhead *p; | 1579 | return e1->d.f < e2->d.f ? -1 : e1->d.f > e2->d.f; |
| 377 | register int i, j; | 1580 | } |
| 378 | 1581 | ||
| 379 | for (i = 0; i < NBUCKETS; i++) { | 1582 | static RB_HEAD(leaktree, leaknode) leakhead; |
| 380 | j = 0; | 1583 | RB_GENERATE_STATIC(leaktree, leaknode, entry, leakcmp) |
| 381 | for (p = nextf[i]; p && j != srchlen; p = p->ov_next) { | 1584 | |
| 382 | if (p == freep) | 1585 | static void |
| 383 | return (i); | 1586 | putleakinfo(void *f, size_t sz, int cnt) |
| 384 | j++; | 1587 | { |
| 1588 | struct leaknode key, *p; | ||
| 1589 | static struct leaknode *page; | ||
| 1590 | static int used; | ||
| 1591 | |||
| 1592 | if (cnt == 0) | ||
| 1593 | return; | ||
| 1594 | |||
| 1595 | key.d.f = f; | ||
| 1596 | p = RB_FIND(leaktree, &leakhead, &key); | ||
| 1597 | if (p == NULL) { | ||
| 1598 | if (page == NULL || | ||
| 1599 | used >= MALLOC_PAGESIZE / sizeof(struct leaknode)) { | ||
| 1600 | page = MMAP(MALLOC_PAGESIZE); | ||
| 1601 | if (page == MAP_FAILED) | ||
| 1602 | return; | ||
| 1603 | used = 0; | ||
| 385 | } | 1604 | } |
| 1605 | p = &page[used++]; | ||
| 1606 | p->d.f = f; | ||
| 1607 | p->d.total_size = sz * cnt; | ||
| 1608 | p->d.count = cnt; | ||
| 1609 | RB_INSERT(leaktree, &leakhead, p); | ||
| 1610 | } else { | ||
| 1611 | p->d.total_size += sz * cnt; | ||
| 1612 | p->d.count += cnt; | ||
| 386 | } | 1613 | } |
| 387 | return (-1); | ||
| 388 | } | 1614 | } |
| 389 | 1615 | ||
| 390 | #ifdef MSTATS | 1616 | static struct malloc_leak *malloc_leaks; |
| 391 | /* | 1617 | |
| 392 | * mstats - print out statistics about malloc | 1618 | static void |
| 393 | * | 1619 | dump_leaks(int fd) |
| 394 | * Prints two lines of numbers, one showing the length of the free list | 1620 | { |
| 395 | * for each size category, the second showing the number of mallocs - | 1621 | struct leaknode *p; |
| 396 | * frees for each size category. | 1622 | char buf[64]; |
| 397 | */ | 1623 | int i = 0; |
| 398 | mstats(s) | 1624 | |
| 399 | char *s; | 1625 | snprintf(buf, sizeof(buf), "Leak report\n"); |
| 400 | { | 1626 | write(fd, buf, strlen(buf)); |
| 401 | register int i, j; | 1627 | snprintf(buf, sizeof(buf), " f sum # avg\n"); |
| 402 | register union overhead *p; | 1628 | write(fd, buf, strlen(buf)); |
| 403 | int totfree = 0, | 1629 | /* XXX only one page of summary */ |
| 404 | totused = 0; | 1630 | if (malloc_leaks == NULL) |
| 405 | 1631 | malloc_leaks = MMAP(MALLOC_PAGESIZE); | |
| 406 | fprintf(stderr, "Memory allocation statistics %s\nfree:\t", s); | 1632 | if (malloc_leaks != MAP_FAILED) |
| 407 | for (i = 0; i < NBUCKETS; i++) { | 1633 | memset(malloc_leaks, 0, MALLOC_PAGESIZE); |
| 408 | for (j = 0, p = nextf[i]; p; p = p->ov_next, j++) | 1634 | RB_FOREACH(p, leaktree, &leakhead) { |
| 409 | ; | 1635 | snprintf(buf, sizeof(buf), "%12p %7zu %6u %6zu\n", p->d.f, |
| 410 | fprintf(stderr, " %d", j); | 1636 | p->d.total_size, p->d.count, p->d.total_size / p->d.count); |
| 411 | totfree += j * (1 << (i + 3)); | 1637 | write(fd, buf, strlen(buf)); |
| 412 | } | 1638 | if (malloc_leaks == MAP_FAILED || |
| 413 | fprintf(stderr, "\nused:\t"); | 1639 | i >= MALLOC_PAGESIZE / sizeof(struct malloc_leak)) |
| 414 | for (i = 0; i < NBUCKETS; i++) { | 1640 | continue; |
| 415 | fprintf(stderr, " %d", nmalloc[i]); | 1641 | malloc_leaks[i].f = p->d.f; |
| 416 | totused += nmalloc[i] * (1 << (i + 3)); | 1642 | malloc_leaks[i].total_size = p->d.total_size; |
| 417 | } | 1643 | malloc_leaks[i].count = p->d.count; |
| 418 | fprintf(stderr, "\n\tTotal in use: %d, total free: %d\n", | 1644 | i++; |
| 419 | totused, totfree); | 1645 | } |
| 420 | } | 1646 | } |
| 421 | #endif | 1647 | |
| 1648 | static void | ||
| 1649 | dump_chunk(int fd, struct chunk_info *p, void *f, int fromfreelist) | ||
| 1650 | { | ||
| 1651 | char buf[64]; | ||
| 1652 | |||
| 1653 | while (p != NULL) { | ||
| 1654 | snprintf(buf, sizeof(buf), "chunk %12p %12p %4d %d/%d\n", | ||
| 1655 | p->page, ((p->bits[0] & 1) ? NULL : f), | ||
| 1656 | p->size, p->free, p->total); | ||
| 1657 | write(fd, buf, strlen(buf)); | ||
| 1658 | if (!fromfreelist) { | ||
| 1659 | if (p->bits[0] & 1) | ||
| 1660 | putleakinfo(NULL, p->size, p->total - p->free); | ||
| 1661 | else { | ||
| 1662 | putleakinfo(f, p->size, 1); | ||
| 1663 | putleakinfo(NULL, p->size, | ||
| 1664 | p->total - p->free - 1); | ||
| 1665 | } | ||
| 1666 | break; | ||
| 1667 | } | ||
| 1668 | p = LIST_NEXT(p, entries); | ||
| 1669 | if (p != NULL) { | ||
| 1670 | snprintf(buf, sizeof(buf), " "); | ||
| 1671 | write(fd, buf, strlen(buf)); | ||
| 1672 | } | ||
| 1673 | } | ||
| 1674 | } | ||
| 1675 | |||
| 1676 | static void | ||
| 1677 | dump_free_chunk_info(int fd, struct dir_info *d) | ||
| 1678 | { | ||
| 1679 | char buf[64]; | ||
| 1680 | int i, count; | ||
| 1681 | |||
| 1682 | snprintf(buf, sizeof(buf), "Free chunk structs:\n"); | ||
| 1683 | write(fd, buf, strlen(buf)); | ||
| 1684 | for (i = 0; i <= MALLOC_MAXSHIFT; i++) { | ||
| 1685 | struct chunk_info *p; | ||
| 1686 | |||
| 1687 | count = 0; | ||
| 1688 | LIST_FOREACH(p, &d->chunk_info_list[i], entries) | ||
| 1689 | count++; | ||
| 1690 | p = LIST_FIRST(&d->chunk_dir[i]); | ||
| 1691 | if (p == NULL && count == 0) | ||
| 1692 | continue; | ||
| 1693 | snprintf(buf, sizeof(buf), "%2d) %3d ", i, count); | ||
| 1694 | write(fd, buf, strlen(buf)); | ||
| 1695 | if (p != NULL) | ||
| 1696 | dump_chunk(fd, p, NULL, 1); | ||
| 1697 | else | ||
| 1698 | write(fd, "\n", 1); | ||
| 1699 | } | ||
| 1700 | |||
| 1701 | } | ||
| 1702 | |||
| 1703 | static void | ||
| 1704 | dump_free_page_info(int fd, struct dir_info *d) | ||
| 1705 | { | ||
| 1706 | char buf[64]; | ||
| 1707 | int i; | ||
| 1708 | |||
| 1709 | snprintf(buf, sizeof(buf), "Free pages cached: %zu\n", | ||
| 1710 | d->free_regions_size); | ||
| 1711 | write(fd, buf, strlen(buf)); | ||
| 1712 | for (i = 0; i < mopts.malloc_cache; i++) { | ||
| 1713 | if (d->free_regions[i].p != NULL) { | ||
| 1714 | snprintf(buf, sizeof(buf), "%2d) ", i); | ||
| 1715 | write(fd, buf, strlen(buf)); | ||
| 1716 | snprintf(buf, sizeof(buf), "free at %p: %zu\n", | ||
| 1717 | d->free_regions[i].p, d->free_regions[i].size); | ||
| 1718 | write(fd, buf, strlen(buf)); | ||
| 1719 | } | ||
| 1720 | } | ||
| 1721 | } | ||
| 1722 | |||
| 1723 | static void | ||
| 1724 | malloc_dump1(int fd, struct dir_info *d) | ||
| 1725 | { | ||
| 1726 | char buf[64]; | ||
| 1727 | size_t i, realsize; | ||
| 1728 | |||
| 1729 | snprintf(buf, sizeof(buf), "Malloc dir of %s at %p\n", __progname, d); | ||
| 1730 | write(fd, buf, strlen(buf)); | ||
| 1731 | if (d == NULL) | ||
| 1732 | return; | ||
| 1733 | snprintf(buf, sizeof(buf), "Region slots free %zu/%zu\n", | ||
| 1734 | d->regions_free, d->regions_total); | ||
| 1735 | write(fd, buf, strlen(buf)); | ||
| 1736 | snprintf(buf, sizeof(buf), "Finds %zu/%zu\n", d->finds, | ||
| 1737 | d->find_collisions); | ||
| 1738 | write(fd, buf, strlen(buf)); | ||
| 1739 | snprintf(buf, sizeof(buf), "Inserts %zu/%zu\n", d->inserts, | ||
| 1740 | d->insert_collisions); | ||
| 1741 | write(fd, buf, strlen(buf)); | ||
| 1742 | snprintf(buf, sizeof(buf), "Deletes %zu/%zu\n", d->deletes, | ||
| 1743 | d->delete_moves); | ||
| 1744 | write(fd, buf, strlen(buf)); | ||
| 1745 | snprintf(buf, sizeof(buf), "Cheap reallocs %zu/%zu\n", | ||
| 1746 | d->cheap_reallocs, d->cheap_realloc_tries); | ||
| 1747 | write(fd, buf, strlen(buf)); | ||
| 1748 | dump_free_chunk_info(fd, d); | ||
| 1749 | dump_free_page_info(fd, d); | ||
| 1750 | snprintf(buf, sizeof(buf), | ||
| 1751 | "slot) hash d type page f size [free/n]\n"); | ||
| 1752 | write(fd, buf, strlen(buf)); | ||
| 1753 | for (i = 0; i < d->regions_total; i++) { | ||
| 1754 | if (d->r[i].p != NULL) { | ||
| 1755 | size_t h = hash(d->r[i].p) & | ||
| 1756 | (d->regions_total - 1); | ||
| 1757 | snprintf(buf, sizeof(buf), "%4zx) #%4zx %zd ", | ||
| 1758 | i, h, h - i); | ||
| 1759 | write(fd, buf, strlen(buf)); | ||
| 1760 | REALSIZE(realsize, &d->r[i]); | ||
| 1761 | if (realsize > MALLOC_MAXCHUNK) { | ||
| 1762 | putleakinfo(d->r[i].f, realsize, 1); | ||
| 1763 | snprintf(buf, sizeof(buf), | ||
| 1764 | "pages %12p %12p %zu\n", d->r[i].p, | ||
| 1765 | d->r[i].f, realsize); | ||
| 1766 | write(fd, buf, strlen(buf)); | ||
| 1767 | } else | ||
| 1768 | dump_chunk(fd, | ||
| 1769 | (struct chunk_info *)d->r[i].size, | ||
| 1770 | d->r[i].f, 0); | ||
| 1771 | } | ||
| 1772 | } | ||
| 1773 | snprintf(buf, sizeof(buf), "In use %zu\n", malloc_used); | ||
| 1774 | write(fd, buf, strlen(buf)); | ||
| 1775 | snprintf(buf, sizeof(buf), "Guarded %zu\n", malloc_guarded); | ||
| 1776 | write(fd, buf, strlen(buf)); | ||
| 1777 | dump_leaks(fd); | ||
| 1778 | write(fd, "\n", 1); | ||
| 1779 | } | ||
| 1780 | |||
| 1781 | void | ||
| 1782 | malloc_dump(int fd) | ||
| 1783 | { | ||
| 1784 | int i; | ||
| 1785 | void *p; | ||
| 1786 | struct region_info *r; | ||
| 1787 | int saved_errno = errno; | ||
| 1788 | |||
| 1789 | for (i = 0; i <= MALLOC_DELAYED_CHUNKS; i++) { | ||
| 1790 | p = g_pool->delayed_chunks[i]; | ||
| 1791 | if (p == NULL) | ||
| 1792 | continue; | ||
| 1793 | r = find(g_pool, p); | ||
| 1794 | if (r == NULL) | ||
| 1795 | wrterror("bogus pointer in malloc_dump", p); | ||
| 1796 | free_bytes(g_pool, r, p); | ||
| 1797 | g_pool->delayed_chunks[i] = NULL; | ||
| 1798 | } | ||
| 1799 | /* XXX leak when run multiple times */ | ||
| 1800 | RB_INIT(&leakhead); | ||
| 1801 | malloc_dump1(fd, g_pool); | ||
| 1802 | errno = saved_errno; | ||
| 1803 | } | ||
| 1804 | |||
| 1805 | static void | ||
| 1806 | malloc_exit(void) | ||
| 1807 | { | ||
| 1808 | static const char q[] = "malloc() warning: Couldn't dump stats\n"; | ||
| 1809 | int save_errno = errno, fd; | ||
| 1810 | |||
| 1811 | fd = open("malloc.out", O_RDWR|O_APPEND); | ||
| 1812 | if (fd != -1) { | ||
| 1813 | malloc_dump(fd); | ||
| 1814 | close(fd); | ||
| 1815 | } else | ||
| 1816 | write(STDERR_FILENO, q, sizeof(q) - 1); | ||
| 1817 | errno = save_errno; | ||
| 1818 | } | ||
| 1819 | |||
| 1820 | #endif /* MALLOC_STATS */ | ||
diff --git a/src/lib/libc/stdlib/merge.c b/src/lib/libc/stdlib/merge.c index 381fdc0830..43ef8b08e2 100644 --- a/src/lib/libc/stdlib/merge.c +++ b/src/lib/libc/stdlib/merge.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: merge.c,v 1.9 2011/03/06 00:55:38 deraadt Exp $ */ | ||
| 1 | /*- | 2 | /*- |
| 2 | * Copyright (c) 1992, 1993 | 3 | * Copyright (c) 1992, 1993 |
| 3 | * The Regents of the University of California. All rights reserved. | 4 | * The Regents of the University of California. All rights reserved. |
| @@ -13,11 +14,7 @@ | |||
| 13 | * 2. Redistributions in binary form must reproduce the above copyright | 14 | * 2. Redistributions in binary form must reproduce the above copyright |
| 14 | * notice, this list of conditions and the following disclaimer in the | 15 | * notice, this list of conditions and the following disclaimer in the |
| 15 | * documentation and/or other materials provided with the distribution. | 16 | * documentation and/or other materials provided with the distribution. |
| 16 | * 3. All advertising materials mentioning features or use of this software | 17 | * 3. Neither the name of the University nor the names of its contributors |
| 17 | * must display the following acknowledgement: | ||
| 18 | * This product includes software developed by the University of | ||
| 19 | * California, Berkeley and its contributors. | ||
| 20 | * 4. Neither the name of the University nor the names of its contributors | ||
| 21 | * may be used to endorse or promote products derived from this software | 18 | * may be used to endorse or promote products derived from this software |
| 22 | * without specific prior written permission. | 19 | * without specific prior written permission. |
| 23 | * | 20 | * |
| @@ -34,11 +31,6 @@ | |||
| 34 | * SUCH DAMAGE. | 31 | * SUCH DAMAGE. |
| 35 | */ | 32 | */ |
| 36 | 33 | ||
| 37 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 38 | /*static char sccsid[] = "from: @(#)merge.c 8.2 (Berkeley) 2/14/94";*/ | ||
| 39 | static char *rcsid = "$Id: merge.c,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $"; | ||
| 40 | #endif /* LIBC_SCCS and not lint */ | ||
| 41 | |||
| 42 | /* | 34 | /* |
| 43 | * Hybrid exponential search/linear search merge sort with hybrid | 35 | * Hybrid exponential search/linear search merge sort with hybrid |
| 44 | * natural/pairwise first pass. Requires about .3% more comparisons | 36 | * natural/pairwise first pass. Requires about .3% more comparisons |
| @@ -59,8 +51,8 @@ static char *rcsid = "$Id: merge.c,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $"; | |||
| 59 | #include <stdlib.h> | 51 | #include <stdlib.h> |
| 60 | #include <string.h> | 52 | #include <string.h> |
| 61 | 53 | ||
| 62 | static void setup __P((u_char *, u_char *, size_t, size_t, int (*)())); | 54 | static void setup(u_char *, u_char *, size_t, size_t, int (*)()); |
| 63 | static void insertionsort __P((u_char *, size_t, size_t, int (*)())); | 55 | static void insertionsort(u_char *, size_t, size_t, int (*)()); |
| 64 | 56 | ||
| 65 | #define ISIZE sizeof(int) | 57 | #define ISIZE sizeof(int) |
| 66 | #define PSIZE sizeof(u_char *) | 58 | #define PSIZE sizeof(u_char *) |
| @@ -96,15 +88,12 @@ static void insertionsort __P((u_char *, size_t, size_t, int (*)())); | |||
| 96 | * Arguments are as for qsort. | 88 | * Arguments are as for qsort. |
| 97 | */ | 89 | */ |
| 98 | int | 90 | int |
| 99 | mergesort(base, nmemb, size, cmp) | 91 | mergesort(void *base, size_t nmemb, size_t size, |
| 100 | void *base; | 92 | int (*cmp)(const void *, const void *)) |
| 101 | size_t nmemb; | ||
| 102 | register size_t size; | ||
| 103 | int (*cmp) __P((const void *, const void *)); | ||
| 104 | { | 93 | { |
| 105 | register int i, sense; | 94 | int i, sense; |
| 106 | int big, iflag; | 95 | int big, iflag; |
| 107 | register u_char *f1, *f2, *t, *b, *tp2, *q, *l1, *l2; | 96 | u_char *f1, *f2, *t, *b, *tp2, *q, *l1, *l2; |
| 108 | u_char *list2, *list1, *p2, *p, *last, **p1; | 97 | u_char *list2, *list1, *p2, *p, *last, **p1; |
| 109 | 98 | ||
| 110 | if (size < PSIZE / 2) { /* Pointers must fit into 2 * size. */ | 99 | if (size < PSIZE / 2) { /* Pointers must fit into 2 * size. */ |
| @@ -148,7 +137,7 @@ mergesort(base, nmemb, size, cmp) | |||
| 148 | sense = 0; | 137 | sense = 0; |
| 149 | } | 138 | } |
| 150 | if (!big) { /* here i = 0 */ | 139 | if (!big) { /* here i = 0 */ |
| 151 | LINEAR: while ((b += size) < t && cmp(q, b) >sense) | 140 | while ((b += size) < t && cmp(q, b) >sense) |
| 152 | if (++i == 6) { | 141 | if (++i == 6) { |
| 153 | big = 1; | 142 | big = 1; |
| 154 | goto EXPONENTIAL; | 143 | goto EXPONENTIAL; |
| @@ -169,7 +158,7 @@ EXPONENTIAL: for (i = size; ; i <<= 1) | |||
| 169 | goto FASTCASE; | 158 | goto FASTCASE; |
| 170 | } else | 159 | } else |
| 171 | b = p; | 160 | b = p; |
| 172 | SLOWCASE: while (t > b+size) { | 161 | while (t > b+size) { |
| 173 | i = (((t - b) / size) >> 1) * size; | 162 | i = (((t - b) / size) >> 1) * size; |
| 174 | if ((*cmp)(q, p = b + i) <= sense) | 163 | if ((*cmp)(q, p = b + i) <= sense) |
| 175 | t = p; | 164 | t = p; |
| @@ -256,13 +245,11 @@ COPY: b = t; | |||
| 256 | * is defined. Otherwise simple pairwise merging is used.) | 245 | * is defined. Otherwise simple pairwise merging is used.) |
| 257 | */ | 246 | */ |
| 258 | void | 247 | void |
| 259 | setup(list1, list2, n, size, cmp) | 248 | setup(u_char *list1, u_char *list2, size_t n, size_t size, |
| 260 | size_t n, size; | 249 | int (*cmp)(const void *, const void *)) |
| 261 | int (*cmp) __P((const void *, const void *)); | ||
| 262 | u_char *list1, *list2; | ||
| 263 | { | 250 | { |
| 264 | int i, length, size2, tmp, sense; | 251 | int i, length, size2, sense; |
| 265 | u_char *f1, *f2, *s, *l2, *last, *p2; | 252 | u_char tmp, *f1, *f2, *s, *l2, *last, *p2; |
| 266 | 253 | ||
| 267 | size2 = size*2; | 254 | size2 = size*2; |
| 268 | if (n <= 5) { | 255 | if (n <= 5) { |
| @@ -330,10 +317,8 @@ setup(list1, list2, n, size, cmp) | |||
| 330 | * last 4 elements. | 317 | * last 4 elements. |
| 331 | */ | 318 | */ |
| 332 | static void | 319 | static void |
| 333 | insertionsort(a, n, size, cmp) | 320 | insertionsort(u_char *a, size_t n, size_t size, |
| 334 | u_char *a; | 321 | int (*cmp)(const void *, const void *)) |
| 335 | size_t n, size; | ||
| 336 | int (*cmp) __P((const void *, const void *)); | ||
| 337 | { | 322 | { |
| 338 | u_char *ai, *s, *t, *u, tmp; | 323 | u_char *ai, *s, *t, *u, tmp; |
| 339 | int i; | 324 | int i; |
diff --git a/src/lib/libc/stdlib/mrand48.c b/src/lib/libc/stdlib/mrand48.c index 43356e66b3..977264aba5 100644 --- a/src/lib/libc/stdlib/mrand48.c +++ b/src/lib/libc/stdlib/mrand48.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: mrand48.c,v 1.3 2005/08/08 08:05:37 espie Exp $ */ | ||
| 1 | /* | 2 | /* |
| 2 | * Copyright (c) 1993 Martin Birgmeier | 3 | * Copyright (c) 1993 Martin Birgmeier |
| 3 | * All rights reserved. | 4 | * All rights reserved. |
diff --git a/src/lib/libc/stdlib/multibyte.c b/src/lib/libc/stdlib/multibyte.c deleted file mode 100644 index fe1cd5781b..0000000000 --- a/src/lib/libc/stdlib/multibyte.c +++ /dev/null | |||
| @@ -1,131 +0,0 @@ | |||
| 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) | ||
| 35 | /*static char *sccsid = "from: @(#)multibyte.c 5.1 (Berkeley) 2/18/91";*/ | ||
| 36 | static char *rcsid = "$Id: multibyte.c,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $"; | ||
| 37 | #endif /* LIBC_SCCS and not lint */ | ||
| 38 | |||
| 39 | #include <stdlib.h> | ||
| 40 | |||
| 41 | /* | ||
| 42 | * Stub multibyte character functions. | ||
| 43 | * This cheezy implementation is fixed to the native single-byte | ||
| 44 | * character set. | ||
| 45 | */ | ||
| 46 | |||
| 47 | int | ||
| 48 | mblen(s, n) | ||
| 49 | const char *s; | ||
| 50 | size_t n; | ||
| 51 | { | ||
| 52 | if (s == NULL || *s == '\0') | ||
| 53 | return 0; | ||
| 54 | if (n == 0) | ||
| 55 | return -1; | ||
| 56 | return 1; | ||
| 57 | } | ||
| 58 | |||
| 59 | /*ARGSUSED*/ | ||
| 60 | int | ||
| 61 | mbtowc(pwc, s, n) | ||
| 62 | wchar_t *pwc; | ||
| 63 | const char *s; | ||
| 64 | size_t n; | ||
| 65 | { | ||
| 66 | if (s == NULL) | ||
| 67 | return 0; | ||
| 68 | if (n == 0) | ||
| 69 | return -1; | ||
| 70 | if (pwc) | ||
| 71 | *pwc = (wchar_t) *s; | ||
| 72 | return (*s != '\0'); | ||
| 73 | } | ||
| 74 | |||
| 75 | /*ARGSUSED*/ | ||
| 76 | int | ||
| 77 | #ifdef __STDC__ | ||
| 78 | wctomb(char *s, wchar_t wchar) | ||
| 79 | #else | ||
| 80 | wctomb(s, wchar) | ||
| 81 | char *s; | ||
| 82 | wchar_t wchar; | ||
| 83 | #endif | ||
| 84 | { | ||
| 85 | if (s == NULL) | ||
| 86 | return 0; | ||
| 87 | |||
| 88 | *s = (char) wchar; | ||
| 89 | return 1; | ||
| 90 | } | ||
| 91 | |||
| 92 | /*ARGSUSED*/ | ||
| 93 | size_t | ||
| 94 | mbstowcs(pwcs, s, n) | ||
| 95 | wchar_t *pwcs; | ||
| 96 | const char *s; | ||
| 97 | size_t n; | ||
| 98 | { | ||
| 99 | int count = 0; | ||
| 100 | |||
| 101 | if (n != 0) { | ||
| 102 | do { | ||
| 103 | if ((*pwcs++ = (wchar_t) *s++) == 0) | ||
| 104 | break; | ||
| 105 | count++; | ||
| 106 | } while (--n != 0); | ||
| 107 | } | ||
| 108 | |||
| 109 | return count; | ||
| 110 | } | ||
| 111 | |||
| 112 | /*ARGSUSED*/ | ||
| 113 | size_t | ||
| 114 | wcstombs(s, pwcs, n) | ||
| 115 | char *s; | ||
| 116 | const wchar_t *pwcs; | ||
| 117 | size_t n; | ||
| 118 | { | ||
| 119 | int count = 0; | ||
| 120 | |||
| 121 | if (n != 0) { | ||
| 122 | do { | ||
| 123 | if ((*s++ = (char) *pwcs++) == 0) | ||
| 124 | break; | ||
| 125 | count++; | ||
| 126 | } while (--n != 0); | ||
| 127 | } | ||
| 128 | |||
| 129 | return count; | ||
| 130 | } | ||
| 131 | |||
diff --git a/src/lib/libc/stdlib/nrand48.c b/src/lib/libc/stdlib/nrand48.c index 63f839cb05..f1f548c3af 100644 --- a/src/lib/libc/stdlib/nrand48.c +++ b/src/lib/libc/stdlib/nrand48.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: nrand48.c,v 1.3 2005/08/08 08:05:37 espie Exp $ */ | ||
| 1 | /* | 2 | /* |
| 2 | * Copyright (c) 1993 Martin Birgmeier | 3 | * Copyright (c) 1993 Martin Birgmeier |
| 3 | * All rights reserved. | 4 | * All rights reserved. |
diff --git a/src/lib/libc/stdlib/posix_memalign.3 b/src/lib/libc/stdlib/posix_memalign.3 new file mode 100644 index 0000000000..05ec1b9d14 --- /dev/null +++ b/src/lib/libc/stdlib/posix_memalign.3 | |||
| @@ -0,0 +1,92 @@ | |||
| 1 | .\" $OpenBSD: posix_memalign.3,v 1.3 2012/06/18 17:03:52 matthew Exp $ | ||
| 2 | .\" Copyright (C) 2006 Jason Evans <jasone@FreeBSD.org>. | ||
| 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(s), this list of conditions and the following disclaimer as | ||
| 10 | .\" the first lines of this file unmodified other than the possible | ||
| 11 | .\" addition of one or more copyright notices. | ||
| 12 | .\" 2. Redistributions in binary form must reproduce the above copyright | ||
| 13 | .\" notice(s), this list of conditions and the following disclaimer in | ||
| 14 | .\" the documentation and/or other materials provided with the | ||
| 15 | .\" distribution. | ||
| 16 | .\" | ||
| 17 | .\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY | ||
| 18 | .\" EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 19 | .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
| 20 | .\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE | ||
| 21 | .\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
| 22 | .\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
| 23 | .\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
| 24 | .\" BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||
| 25 | .\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE | ||
| 26 | .\" OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, | ||
| 27 | .\" EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 28 | .\" | ||
| 29 | .\" $FreeBSD: src/lib/libc/stdlib/posix_memalign.3,v 1.3 2007/03/28 04:32:51 jasone Exp $ | ||
| 30 | .\" | ||
| 31 | .Dd $Mdocdate: June 18 2012 $ | ||
| 32 | .Dt POSIX_MEMALIGN 3 | ||
| 33 | .Os | ||
| 34 | .Sh NAME | ||
| 35 | .Nm posix_memalign | ||
| 36 | .Nd aligned memory allocation | ||
| 37 | .Sh SYNOPSIS | ||
| 38 | .In stdlib.h | ||
| 39 | .Ft int | ||
| 40 | .Fn posix_memalign "void **ptr" "size_t alignment" "size_t size" | ||
| 41 | .Sh DESCRIPTION | ||
| 42 | The | ||
| 43 | .Fn posix_memalign | ||
| 44 | function allocates | ||
| 45 | .Fa size | ||
| 46 | bytes of memory such that the allocation's base address is a multiple of | ||
| 47 | .Fa alignment , | ||
| 48 | and returns the allocation in the value pointed to by | ||
| 49 | .Fa ptr . | ||
| 50 | .Pp | ||
| 51 | The requested | ||
| 52 | .Fa alignment | ||
| 53 | must be a power of 2 at least as large as | ||
| 54 | .Fn sizeof "void *" . | ||
| 55 | .Pp | ||
| 56 | Memory that is allocated via | ||
| 57 | .Fn posix_memalign | ||
| 58 | can be used as an argument in subsequent calls to | ||
| 59 | .Xr realloc 3 | ||
| 60 | and | ||
| 61 | .Xr free 3 . | ||
| 62 | .Sh RETURN VALUES | ||
| 63 | The | ||
| 64 | .Fn posix_memalign | ||
| 65 | function returns the value 0 if successful; otherwise it returns an error value. | ||
| 66 | .Sh ERRORS | ||
| 67 | The | ||
| 68 | .Fn posix_memalign | ||
| 69 | function will fail if: | ||
| 70 | .Bl -tag -width Er | ||
| 71 | .It Bq Er EINVAL | ||
| 72 | The | ||
| 73 | .Fa alignment | ||
| 74 | parameter is not a power of 2 at least as large as | ||
| 75 | .Fn sizeof "void *" . | ||
| 76 | .It Bq Er ENOMEM | ||
| 77 | Memory allocation error. | ||
| 78 | .El | ||
| 79 | .Sh SEE ALSO | ||
| 80 | .Xr free 3 , | ||
| 81 | .Xr malloc 3 , | ||
| 82 | .Xr realloc 3 | ||
| 83 | .Sh STANDARDS | ||
| 84 | The | ||
| 85 | .Fn posix_memalign | ||
| 86 | function conforms to | ||
| 87 | .St -p1003.1-2001 . | ||
| 88 | .Sh HISTORY | ||
| 89 | The | ||
| 90 | .Fn posix_memalign | ||
| 91 | function first appeared in | ||
| 92 | .Ox 4.8 . | ||
diff --git a/src/lib/libc/stdlib/posix_openpt.3 b/src/lib/libc/stdlib/posix_openpt.3 new file mode 100644 index 0000000000..376772bb07 --- /dev/null +++ b/src/lib/libc/stdlib/posix_openpt.3 | |||
| @@ -0,0 +1,102 @@ | |||
| 1 | .\" $OpenBSD: posix_openpt.3,v 1.3 2012/12/05 06:40:59 jmc Exp $ | ||
| 2 | .\" | ||
| 3 | .\" Copyright (c) 2012 Todd C. Miller <Todd.Miller@courtesan.com> | ||
| 4 | .\" | ||
| 5 | .\" Permission to use, copy, modify, and distribute this software for any | ||
| 6 | .\" purpose with or without fee is hereby granted, provided that the above | ||
| 7 | .\" copyright notice and this permission notice appear in all copies. | ||
| 8 | .\" | ||
| 9 | .\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 10 | .\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 11 | .\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 12 | .\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 13 | .\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 14 | .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 15 | .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 16 | .\" | ||
| 17 | .Dd $Mdocdate: December 5 2012 $ | ||
| 18 | .Dt POSIX_OPENPT 3 | ||
| 19 | .Os | ||
| 20 | .Sh NAME | ||
| 21 | .Nm posix_openpt | ||
| 22 | .Nd open a pseudo-terminal device | ||
| 23 | .Sh SYNOPSIS | ||
| 24 | .In stdlib.h | ||
| 25 | .In fcntl.h | ||
| 26 | .Ft int | ||
| 27 | .Fn posix_openpt "int oflag" | ||
| 28 | .Sh DESCRIPTION | ||
| 29 | The | ||
| 30 | .Fn posix_openpt | ||
| 31 | function finds the next available pseudo-terminal and returns an open | ||
| 32 | file descriptor for its master device. | ||
| 33 | The path name of the slave device may be determined via the | ||
| 34 | .Fn ptsname | ||
| 35 | function. | ||
| 36 | Note that the | ||
| 37 | .Fn unlockpt | ||
| 38 | and | ||
| 39 | .Fn grantpt | ||
| 40 | functions should be called before opening the slave device. | ||
| 41 | .Pp | ||
| 42 | The | ||
| 43 | .Ar oflag | ||
| 44 | argument is formed by bitwise-inclusive | ||
| 45 | .Tn OR Ns 'ing | ||
| 46 | the following values defined in | ||
| 47 | .In fcntl.h : | ||
| 48 | .Bl -tag -width O_NOCTTY -offset indent | ||
| 49 | .It Dv O_RDWR | ||
| 50 | Open for reading and writing. | ||
| 51 | .It Dv O_NOCTTY | ||
| 52 | Prevent the device from being made the controlling terminal for the session. | ||
| 53 | This flag has no effect on | ||
| 54 | .Ox | ||
| 55 | and is included for compatibility with other systems. | ||
| 56 | .El | ||
| 57 | .Pp | ||
| 58 | The | ||
| 59 | .Dv O_RDWR | ||
| 60 | flag must be specified in | ||
| 61 | .Fa oflag . | ||
| 62 | If | ||
| 63 | .Fa oflag | ||
| 64 | contains values other than those listed above, | ||
| 65 | .Fn posix_openpt | ||
| 66 | will return an error. | ||
| 67 | .Sh RETURN VALUES | ||
| 68 | If successful, | ||
| 69 | .Fn posix_openpt | ||
| 70 | returns a non-negative integer, the file descriptor for the | ||
| 71 | pseudo-terminal master device. | ||
| 72 | Otherwise, a value of \-1 is returned and | ||
| 73 | .Va errno | ||
| 74 | is set to indicate the error. | ||
| 75 | .Sh ERRORS | ||
| 76 | The | ||
| 77 | .Fn posix_openpt | ||
| 78 | function will fail if: | ||
| 79 | .Bl -tag -width Er | ||
| 80 | .It Bq Er EMFILE | ||
| 81 | The per-process descriptor table is full. | ||
| 82 | .It Bq Er ENFILE | ||
| 83 | The system file table is full. | ||
| 84 | .It Bq Er EINVAL | ||
| 85 | The value of | ||
| 86 | .Fa oflag | ||
| 87 | is not valid. | ||
| 88 | .El | ||
| 89 | .Sh SEE ALSO | ||
| 90 | .Xr ptsname 3 , | ||
| 91 | .Xr pty 4 , | ||
| 92 | .Xr tty 4 | ||
| 93 | .Sh STANDARDS | ||
| 94 | The | ||
| 95 | .Fn posix_openpt | ||
| 96 | function conforms to | ||
| 97 | .St -p1003.1-2001 . | ||
| 98 | .Sh HISTORY | ||
| 99 | The | ||
| 100 | .Fn posix_openpt | ||
| 101 | function appeared in | ||
| 102 | .Ox 5.3 . | ||
diff --git a/src/lib/libc/stdlib/posix_pty.c b/src/lib/libc/stdlib/posix_pty.c new file mode 100644 index 0000000000..a2025ddbb6 --- /dev/null +++ b/src/lib/libc/stdlib/posix_pty.c | |||
| @@ -0,0 +1,119 @@ | |||
| 1 | /* $OpenBSD: posix_pty.c,v 1.1 2012/12/03 20:08:33 millert Exp $ */ | ||
| 2 | |||
| 3 | /* | ||
| 4 | * Copyright (c) 2012 Todd C. Miller <Todd.Miller@courtesan.com> | ||
| 5 | * | ||
| 6 | * Permission to use, copy, modify, and distribute this software for any | ||
| 7 | * purpose with or without fee is hereby granted, provided that the above | ||
| 8 | * copyright notice and this permission notice appear in all copies. | ||
| 9 | * | ||
| 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <sys/types.h> | ||
| 20 | #include <sys/ioctl.h> | ||
| 21 | #include <sys/stat.h> | ||
| 22 | #include <sys/tty.h> | ||
| 23 | #include <errno.h> | ||
| 24 | #include <fcntl.h> | ||
| 25 | #include <paths.h> | ||
| 26 | #include <stddef.h> | ||
| 27 | #include <stdlib.h> | ||
| 28 | #include <string.h> | ||
| 29 | #include <unistd.h> | ||
| 30 | |||
| 31 | int | ||
| 32 | posix_openpt(int oflag) | ||
| 33 | { | ||
| 34 | struct ptmget ptm; | ||
| 35 | int fd, mfd = -1; | ||
| 36 | |||
| 37 | /* User must specify O_RDWR in oflag. */ | ||
| 38 | if (!(oflag & O_RDWR)) { | ||
| 39 | errno = EINVAL; | ||
| 40 | return -1; | ||
| 41 | } | ||
| 42 | |||
| 43 | /* Get pty master and slave (this API only uses the master). */ | ||
| 44 | fd = open(PATH_PTMDEV, O_RDWR); | ||
| 45 | if (fd != -1) { | ||
| 46 | if (ioctl(fd, PTMGET, &ptm) != -1) { | ||
| 47 | close(ptm.sfd); | ||
| 48 | mfd = ptm.cfd; | ||
| 49 | } | ||
| 50 | close(fd); | ||
| 51 | } | ||
| 52 | |||
| 53 | return mfd; | ||
| 54 | } | ||
| 55 | |||
| 56 | /* | ||
| 57 | * Look up the name of the specified pty master fd. | ||
| 58 | * Note that the name returned does *not* include the /dev/ prefix. | ||
| 59 | * Returns the name on success and NULL on error, setting errno. | ||
| 60 | */ | ||
| 61 | static const char * | ||
| 62 | ptmname(int mfd) | ||
| 63 | { | ||
| 64 | struct stat sb; | ||
| 65 | const char *name; | ||
| 66 | |||
| 67 | /* Make sure it is a pty master. */ | ||
| 68 | if (fstat(mfd, &sb) != 0) | ||
| 69 | return NULL; | ||
| 70 | if (!S_ISCHR(sb.st_mode)) { | ||
| 71 | errno = EINVAL; | ||
| 72 | return NULL; | ||
| 73 | } | ||
| 74 | name = devname(sb.st_rdev, S_IFCHR); | ||
| 75 | if (strncmp(name, "pty", 3) != 0) { | ||
| 76 | errno = EINVAL; | ||
| 77 | return NULL; | ||
| 78 | } | ||
| 79 | return name; | ||
| 80 | } | ||
| 81 | |||
| 82 | /* | ||
| 83 | * The PTMGET ioctl handles the mode and owner for us. | ||
| 84 | */ | ||
| 85 | int | ||
| 86 | grantpt(int mfd) | ||
| 87 | { | ||
| 88 | return ptmname(mfd) ? 0 : -1; | ||
| 89 | } | ||
| 90 | |||
| 91 | /* | ||
| 92 | * The PTMGET ioctl unlocks the pty master and slave for us. | ||
| 93 | */ | ||
| 94 | int | ||
| 95 | unlockpt(int mfd) | ||
| 96 | { | ||
| 97 | return ptmname(mfd) ? 0 : -1; | ||
| 98 | } | ||
| 99 | |||
| 100 | /* | ||
| 101 | * Look up the path of the slave pty that corresponds to the master fd. | ||
| 102 | * Returns the path if successful or NULL on error. | ||
| 103 | */ | ||
| 104 | char * | ||
| 105 | ptsname(int mfd) | ||
| 106 | { | ||
| 107 | const char *master; | ||
| 108 | static char slave[sizeof(((struct ptmget *)NULL)->sn)]; | ||
| 109 | |||
| 110 | if ((master = ptmname(mfd)) == NULL) | ||
| 111 | return NULL; | ||
| 112 | |||
| 113 | /* Add /dev/ prefix and convert "pty" to "tty". */ | ||
| 114 | strlcpy(slave, _PATH_DEV, sizeof(slave)); | ||
| 115 | strlcat(slave, master, sizeof(slave)); | ||
| 116 | slave[sizeof(_PATH_DEV) - 1] = 't'; | ||
| 117 | |||
| 118 | return slave; | ||
| 119 | } | ||
diff --git a/src/lib/libc/stdlib/ptsname.3 b/src/lib/libc/stdlib/ptsname.3 new file mode 100644 index 0000000000..98705528f5 --- /dev/null +++ b/src/lib/libc/stdlib/ptsname.3 | |||
| @@ -0,0 +1,160 @@ | |||
| 1 | .\" $OpenBSD: ptsname.3,v 1.2 2012/12/04 18:42:16 millert Exp $ | ||
| 2 | .\" | ||
| 3 | .\" Copyright (c) 2002 The FreeBSD Project, Inc. | ||
| 4 | .\" All rights reserved. | ||
| 5 | .\" | ||
| 6 | .\" This software includes code contributed to the FreeBSD Project | ||
| 7 | .\" by Ryan Younce of North Carolina State University. | ||
| 8 | .\" | ||
| 9 | .\" Redistribution and use in source and binary forms, with or without | ||
| 10 | .\" modification, are permitted provided that the following conditions | ||
| 11 | .\" are met: | ||
| 12 | .\" 1. Redistributions of source code must retain the above copyright | ||
| 13 | .\" notice, this list of conditions and the following disclaimer. | ||
| 14 | .\" 2. Redistributions in binary form must reproduce the above copyright | ||
| 15 | .\" notice, this list of conditions and the following disclaimer in the | ||
| 16 | .\" documentation and/or other materials provided with the distribution. | ||
| 17 | .\" 3. Neither the name of the FreeBSD Project nor the names of its | ||
| 18 | .\" contributors may be used to endorse or promote products derived from | ||
| 19 | .\" this software without specific prior written permission. | ||
| 20 | .\" | ||
| 21 | .\" THIS SOFTWARE IS PROVIDED BY THE FREEBSD PROJECT AND CONTRIBUTORS | ||
| 22 | .\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 23 | .\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A | ||
| 24 | .\" PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FREEBSD PROJECT | ||
| 25 | .\" OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
| 26 | .\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED | ||
| 27 | .\" TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
| 28 | .\" PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
| 29 | .\" LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
| 30 | .\" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
| 31 | .\" SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 32 | .\" | ||
| 33 | .\" $FreeBSD: head/lib/libc/stdlib/ptsname.3 240412 2012-09-12 17:54:09Z emaste $ | ||
| 34 | .\" | ||
| 35 | .Dd $Mdocdate: December 4 2012 $ | ||
| 36 | .Dt PTSNAME 3 | ||
| 37 | .Os | ||
| 38 | .Sh NAME | ||
| 39 | .Nm grantpt , | ||
| 40 | .Nm ptsname , | ||
| 41 | .Nm unlockpt | ||
| 42 | .Nd pseudo-terminal access functions | ||
| 43 | .Sh SYNOPSIS | ||
| 44 | .In stdlib.h | ||
| 45 | .Ft int | ||
| 46 | .Fn grantpt "int fildes" | ||
| 47 | .Ft "char *" | ||
| 48 | .Fn ptsname "int fildes" | ||
| 49 | .Ft int | ||
| 50 | .Fn unlockpt "int fildes" | ||
| 51 | .Sh DESCRIPTION | ||
| 52 | The | ||
| 53 | .Fn grantpt , | ||
| 54 | .Fn ptsname , | ||
| 55 | and | ||
| 56 | .Fn unlockpt | ||
| 57 | functions allow access to pseudo-terminal devices. | ||
| 58 | These three functions accept a file descriptor that references the | ||
| 59 | master half of a pseudo-terminal pair. | ||
| 60 | This file descriptor is created with | ||
| 61 | .Xr posix_openpt 3 . | ||
| 62 | .Pp | ||
| 63 | The | ||
| 64 | .Fn grantpt | ||
| 65 | function is used to establish ownership and permissions | ||
| 66 | of the slave device counterpart to the master device | ||
| 67 | specified with | ||
| 68 | .Fa fildes . | ||
| 69 | The slave device's ownership is set to the real user ID | ||
| 70 | of the calling process, and the permissions are set to | ||
| 71 | user readable-writable and group writable. | ||
| 72 | The group owner of the slave device is also set to the | ||
| 73 | group | ||
| 74 | .Dq Li tty . | ||
| 75 | .Pp | ||
| 76 | The | ||
| 77 | .Fn ptsname | ||
| 78 | function returns the full path name of the slave device | ||
| 79 | counterpart to the master device specified with | ||
| 80 | .Fa fildes . | ||
| 81 | This value can be used | ||
| 82 | to subsequently open the appropriate slave after | ||
| 83 | .Xr posix_openpt 3 | ||
| 84 | and | ||
| 85 | .Fn grantpt | ||
| 86 | have been called. | ||
| 87 | .Pp | ||
| 88 | The | ||
| 89 | .Fn unlockpt | ||
| 90 | function clears the lock held on the pseudo-terminal pair | ||
| 91 | for the master device specified with | ||
| 92 | .Fa fildes . | ||
| 93 | .Sh RETURN VALUES | ||
| 94 | .Rv -std grantpt unlockpt | ||
| 95 | .Pp | ||
| 96 | The | ||
| 97 | .Fn ptsname | ||
| 98 | function returns a pointer to the name | ||
| 99 | of the slave device on success; otherwise a | ||
| 100 | .Dv NULL | ||
| 101 | pointer is returned. | ||
| 102 | .Sh ERRORS | ||
| 103 | The | ||
| 104 | .Fn grantpt , | ||
| 105 | .Fn ptsname | ||
| 106 | and | ||
| 107 | .Fn unlockpt | ||
| 108 | functions may fail and set | ||
| 109 | .Va errno | ||
| 110 | to: | ||
| 111 | .Bl -tag -width Er | ||
| 112 | .It Bq Er EBADF | ||
| 113 | .Fa fildes | ||
| 114 | is not a valid open file descriptor. | ||
| 115 | .It Bq Er EINVAL | ||
| 116 | .Fa fildes | ||
| 117 | is not a master pseudo-terminal device. | ||
| 118 | .El | ||
| 119 | .Pp | ||
| 120 | In addition, the | ||
| 121 | .Fn grantpt | ||
| 122 | function may set | ||
| 123 | .Va errno | ||
| 124 | to: | ||
| 125 | .Bl -tag -width Er | ||
| 126 | .It Bq Er EACCES | ||
| 127 | The slave pseudo-terminal device could not be accessed. | ||
| 128 | .El | ||
| 129 | .Sh SEE ALSO | ||
| 130 | .Xr posix_openpt 3 , | ||
| 131 | .Xr pty 4 , | ||
| 132 | .Xr tty 4 | ||
| 133 | .Sh STANDARDS | ||
| 134 | The | ||
| 135 | .Fn ptsname | ||
| 136 | function conforms to | ||
| 137 | .St -p1003.1-2008 . | ||
| 138 | .Pp | ||
| 139 | This implementation of | ||
| 140 | .Fn grantpt | ||
| 141 | and | ||
| 142 | .Fn unlockpt | ||
| 143 | does not conform to | ||
| 144 | .St -p1003.1-2008 , | ||
| 145 | because it depends on | ||
| 146 | .Xr posix_openpt 3 | ||
| 147 | to create the pseudo-terminal device with proper permissions in place. | ||
| 148 | It only validates whether | ||
| 149 | .Fa fildes | ||
| 150 | is a valid pseudo-terminal master device. | ||
| 151 | Future revisions of the specification will likely allow this behaviour, | ||
| 152 | as stated by the Austin Group. | ||
| 153 | .Sh HISTORY | ||
| 154 | The | ||
| 155 | .Fn grantpt , | ||
| 156 | .Fn ptsname | ||
| 157 | and | ||
| 158 | .Fn unlockpt | ||
| 159 | functions appeared in | ||
| 160 | .Ox 5.3 . | ||
diff --git a/src/lib/libc/stdlib/qabs.3 b/src/lib/libc/stdlib/qabs.3 index cb1e052191..6703072e72 100644 --- a/src/lib/libc/stdlib/qabs.3 +++ b/src/lib/libc/stdlib/qabs.3 | |||
| @@ -13,11 +13,7 @@ | |||
| 13 | .\" 2. Redistributions in binary form must reproduce the above copyright | 13 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 14 | .\" notice, this list of conditions and the following disclaimer in the | 14 | .\" notice, this list of conditions and the following disclaimer in the |
| 15 | .\" documentation and/or other materials provided with the distribution. | 15 | .\" documentation and/or other materials provided with the distribution. |
| 16 | .\" 3. All advertising materials mentioning features or use of this software | 16 | .\" 3. Neither the name of the University nor the names of its contributors |
| 17 | .\" must display the following acknowledgement: | ||
| 18 | .\" This product includes software developed by the University of | ||
| 19 | .\" California, Berkeley and its contributors. | ||
| 20 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 21 | .\" may be used to endorse or promote products derived from this software | 17 | .\" may be used to endorse or promote products derived from this software |
| 22 | .\" without specific prior written permission. | 18 | .\" without specific prior written permission. |
| 23 | .\" | 19 | .\" |
| @@ -33,30 +29,28 @@ | |||
| 33 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 29 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 34 | .\" SUCH DAMAGE. | 30 | .\" SUCH DAMAGE. |
| 35 | .\" | 31 | .\" |
| 36 | .\" from: @(#)labs.3 5.3 (Berkeley) 6/29/91 | 32 | .\" $OpenBSD: qabs.3,v 1.13 2013/06/05 03:39:23 tedu Exp $ |
| 37 | .\" $Id: qabs.3,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $ | ||
| 38 | .\" | 33 | .\" |
| 39 | .Dd June 29, 1991 | 34 | .Dd $Mdocdate: June 5 2013 $ |
| 40 | .Dt QABS 3 | 35 | .Dt QABS 3 |
| 41 | .Os | 36 | .Os |
| 42 | .Sh NAME | 37 | .Sh NAME |
| 43 | .Nm qabs | 38 | .Nm qabs |
| 44 | .Nd return the absolute value of a quad integer | 39 | .Nd return the absolute value of a quad integer |
| 45 | .Sh SYNOPSIS | 40 | .Sh SYNOPSIS |
| 46 | .Fd #include <stdlib.h> | 41 | .In stdlib.h |
| 47 | .Ft quad_t | 42 | .Ft quad_t |
| 48 | .Fn qabs "quad_t j" | 43 | .Fn qabs "quad_t j" |
| 49 | .Sh DESCRIPTION | 44 | .Sh DESCRIPTION |
| 50 | The | 45 | The |
| 51 | .Fn qabs | 46 | .Fn qabs |
| 52 | function | 47 | function returns the absolute value of the quad integer |
| 53 | returns the absolute value of the quad integer | 48 | .Fa j . |
| 54 | .Ar j . | ||
| 55 | .Sh SEE ALSO | 49 | .Sh SEE ALSO |
| 56 | .Xr abs 3 , | 50 | .Xr abs 3 , |
| 57 | .Xr labs 3 , | ||
| 58 | .Xr floor 3 , | ||
| 59 | .Xr cabs 3 , | 51 | .Xr cabs 3 , |
| 60 | .Xr math 3 | 52 | .Xr floor 3 , |
| 53 | .Xr imaxabs 3 , | ||
| 54 | .Xr labs 3 | ||
| 61 | .Sh BUGS | 55 | .Sh BUGS |
| 62 | The absolute value of the most negative integer remains negative. | 56 | The absolute value of the most negative integer remains negative. |
diff --git a/src/lib/libc/stdlib/qabs.c b/src/lib/libc/stdlib/qabs.c index 9c51a8baa9..656b93c822 100644 --- a/src/lib/libc/stdlib/qabs.c +++ b/src/lib/libc/stdlib/qabs.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: qabs.c,v 1.5 2005/08/08 08:05:37 espie Exp $ */ | ||
| 1 | /*- | 2 | /*- |
| 2 | * Copyright (c) 1990 The Regents of the University of California. | 3 | * Copyright (c) 1990 The Regents of the University of California. |
| 3 | * All rights reserved. | 4 | * All rights reserved. |
| @@ -10,11 +11,7 @@ | |||
| 10 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the |
| 12 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. Neither the name of the University nor the names of its contributors |
| 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 | 15 | * may be used to endorse or promote products derived from this software |
| 19 | * without specific prior written permission. | 16 | * without specific prior written permission. |
| 20 | * | 17 | * |
| @@ -31,16 +28,10 @@ | |||
| 31 | * SUCH DAMAGE. | 28 | * SUCH DAMAGE. |
| 32 | */ | 29 | */ |
| 33 | 30 | ||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 35 | /*static char *sccsid = "from: @(#)labs.c 5.2 (Berkeley) 5/17/90";*/ | ||
| 36 | static char *rcsid = "$Id: qabs.c,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $"; | ||
| 37 | #endif /* LIBC_SCCS and not lint */ | ||
| 38 | |||
| 39 | #include <stdlib.h> | 31 | #include <stdlib.h> |
| 40 | 32 | ||
| 41 | quad_t | 33 | quad_t |
| 42 | qabs(j) | 34 | qabs(quad_t j) |
| 43 | quad_t j; | ||
| 44 | { | 35 | { |
| 45 | return(j < 0 ? -j : j); | 36 | return(j < 0 ? -j : j); |
| 46 | } | 37 | } |
diff --git a/src/lib/libc/stdlib/qdiv.3 b/src/lib/libc/stdlib/qdiv.3 index 0efcfc96ef..5f5275493e 100644 --- a/src/lib/libc/stdlib/qdiv.3 +++ b/src/lib/libc/stdlib/qdiv.3 | |||
| @@ -13,11 +13,7 @@ | |||
| 13 | .\" 2. Redistributions in binary form must reproduce the above copyright | 13 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 14 | .\" notice, this list of conditions and the following disclaimer in the | 14 | .\" notice, this list of conditions and the following disclaimer in the |
| 15 | .\" documentation and/or other materials provided with the distribution. | 15 | .\" documentation and/or other materials provided with the distribution. |
| 16 | .\" 3. All advertising materials mentioning features or use of this software | 16 | .\" 3. Neither the name of the University nor the names of its contributors |
| 17 | .\" must display the following acknowledgement: | ||
| 18 | .\" This product includes software developed by the University of | ||
| 19 | .\" California, Berkeley and its contributors. | ||
| 20 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 21 | .\" may be used to endorse or promote products derived from this software | 17 | .\" may be used to endorse or promote products derived from this software |
| 22 | .\" without specific prior written permission. | 18 | .\" without specific prior written permission. |
| 23 | .\" | 19 | .\" |
| @@ -33,34 +29,33 @@ | |||
| 33 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 29 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 34 | .\" SUCH DAMAGE. | 30 | .\" SUCH DAMAGE. |
| 35 | .\" | 31 | .\" |
| 36 | .\" from: @(#)qdiv.3 5.3 (Berkeley) 6/29/91 | 32 | .\" $OpenBSD: qdiv.3,v 1.10 2013/06/05 03:39:23 tedu Exp $ |
| 37 | .\" $Id: qdiv.3,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $ | ||
| 38 | .\" | 33 | .\" |
| 39 | .Dd June 29, 1991 | 34 | .Dd $Mdocdate: June 5 2013 $ |
| 40 | .Dt QDIV 3 | 35 | .Dt QDIV 3 |
| 41 | .Os | 36 | .Os |
| 42 | .Sh NAME | 37 | .Sh NAME |
| 43 | .Nm qdiv | 38 | .Nm qdiv |
| 44 | .Nd return quotient and remainder from division | 39 | .Nd return quotient and remainder from division |
| 45 | .Sh SYNOPSIS | 40 | .Sh SYNOPSIS |
| 46 | .Fd #include <stdlib.h> | 41 | .In stdlib.h |
| 47 | .Ft qdiv_t | 42 | .Ft qdiv_t |
| 48 | .Fn qdiv "quad_t num" "quad_t denom" | 43 | .Fn qdiv "quad_t num" "quad_t denom" |
| 49 | .Sh DESCRIPTION | 44 | .Sh DESCRIPTION |
| 50 | The | 45 | The |
| 51 | .Fn qdiv | 46 | .Fn qdiv |
| 52 | function | 47 | function computes the value |
| 53 | computes the value | 48 | .Fa num Ns / Ns Fa denom |
| 54 | .Ar num/denom | ||
| 55 | and returns the quotient and remainder in a structure named | 49 | and returns the quotient and remainder in a structure named |
| 56 | .Ar qdiv_t | 50 | .Li qdiv_t |
| 57 | that contains two | 51 | that contains two |
| 58 | .Em quad integer | 52 | .Li quad integer |
| 59 | members named | 53 | members named |
| 60 | .Ar quot | 54 | .Fa quot |
| 61 | and | 55 | and |
| 62 | .Ar rem . | 56 | .Fa rem . |
| 63 | .Sh SEE ALSO | 57 | .Sh SEE ALSO |
| 64 | .Xr div 3 , | 58 | .Xr div 3 , |
| 59 | .Xr imaxdiv 3 , | ||
| 65 | .Xr ldiv 3 , | 60 | .Xr ldiv 3 , |
| 66 | .Xr math 3 | 61 | .Xr lldiv 3 |
diff --git a/src/lib/libc/stdlib/qdiv.c b/src/lib/libc/stdlib/qdiv.c index 8f8e3f89c4..f3db0915ed 100644 --- a/src/lib/libc/stdlib/qdiv.c +++ b/src/lib/libc/stdlib/qdiv.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: qdiv.c,v 1.5 2005/08/08 08:05:37 espie Exp $ */ | ||
| 1 | /* | 2 | /* |
| 2 | * Copyright (c) 1990 Regents of the University of California. | 3 | * Copyright (c) 1990 Regents of the University of California. |
| 3 | * All rights reserved. | 4 | * All rights reserved. |
| @@ -13,11 +14,7 @@ | |||
| 13 | * 2. Redistributions in binary form must reproduce the above copyright | 14 | * 2. Redistributions in binary form must reproduce the above copyright |
| 14 | * notice, this list of conditions and the following disclaimer in the | 15 | * notice, this list of conditions and the following disclaimer in the |
| 15 | * documentation and/or other materials provided with the distribution. | 16 | * documentation and/or other materials provided with the distribution. |
| 16 | * 3. All advertising materials mentioning features or use of this software | 17 | * 3. Neither the name of the University nor the names of its contributors |
| 17 | * must display the following acknowledgement: | ||
| 18 | * This product includes software developed by the University of | ||
| 19 | * California, Berkeley and its contributors. | ||
| 20 | * 4. Neither the name of the University nor the names of its contributors | ||
| 21 | * may be used to endorse or promote products derived from this software | 18 | * may be used to endorse or promote products derived from this software |
| 22 | * without specific prior written permission. | 19 | * without specific prior written permission. |
| 23 | * | 20 | * |
| @@ -34,16 +31,10 @@ | |||
| 34 | * SUCH DAMAGE. | 31 | * SUCH DAMAGE. |
| 35 | */ | 32 | */ |
| 36 | 33 | ||
| 37 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 38 | /*static char *sccsid = "from: @(#)ldiv.c 5.2 (Berkeley) 4/16/91";*/ | ||
| 39 | static char *rcsid = "$Id: qdiv.c,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $"; | ||
| 40 | #endif /* LIBC_SCCS and not lint */ | ||
| 41 | |||
| 42 | #include <stdlib.h> /* qdiv_t */ | 34 | #include <stdlib.h> /* qdiv_t */ |
| 43 | 35 | ||
| 44 | qdiv_t | 36 | qdiv_t |
| 45 | qdiv(num, denom) | 37 | qdiv(quad_t num, quad_t denom) |
| 46 | quad_t num, denom; | ||
| 47 | { | 38 | { |
| 48 | qdiv_t r; | 39 | qdiv_t r; |
| 49 | 40 | ||
diff --git a/src/lib/libc/stdlib/qsort.3 b/src/lib/libc/stdlib/qsort.3 index eb122cde12..4481a96ee4 100644 --- a/src/lib/libc/stdlib/qsort.3 +++ b/src/lib/libc/stdlib/qsort.3 | |||
| @@ -13,11 +13,7 @@ | |||
| 13 | .\" 2. Redistributions in binary form must reproduce the above copyright | 13 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 14 | .\" notice, this list of conditions and the following disclaimer in the | 14 | .\" notice, this list of conditions and the following disclaimer in the |
| 15 | .\" documentation and/or other materials provided with the distribution. | 15 | .\" documentation and/or other materials provided with the distribution. |
| 16 | .\" 3. All advertising materials mentioning features or use of this software | 16 | .\" 3. Neither the name of the University nor the names of its contributors |
| 17 | .\" must display the following acknowledgement: | ||
| 18 | .\" This product includes software developed by the University of | ||
| 19 | .\" California, Berkeley and its contributors. | ||
| 20 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 21 | .\" may be used to endorse or promote products derived from this software | 17 | .\" may be used to endorse or promote products derived from this software |
| 22 | .\" without specific prior written permission. | 18 | .\" without specific prior written permission. |
| 23 | .\" | 19 | .\" |
| @@ -33,17 +29,18 @@ | |||
| 33 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 29 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 34 | .\" SUCH DAMAGE. | 30 | .\" SUCH DAMAGE. |
| 35 | .\" | 31 | .\" |
| 36 | .\" from: @(#)qsort.3 8.1 (Berkeley) 6/4/93 | 32 | .\" $OpenBSD: qsort.3,v 1.17 2013/07/17 05:42:11 schwarze Exp $ |
| 37 | .\" $Id: qsort.3,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $ | ||
| 38 | .\" | 33 | .\" |
| 39 | .Dd June 4, 1993 | 34 | .Dd $Mdocdate: July 17 2013 $ |
| 40 | .Dt QSORT 3 | 35 | .Dt QSORT 3 |
| 41 | .Os | 36 | .Os |
| 42 | .Sh NAME | 37 | .Sh NAME |
| 43 | .Nm qsort, heapsort, mergesort | 38 | .Nm qsort , |
| 39 | .Nm heapsort , | ||
| 40 | .Nm mergesort | ||
| 44 | .Nd sort functions | 41 | .Nd sort functions |
| 45 | .Sh SYNOPSIS | 42 | .Sh SYNOPSIS |
| 46 | .Fd #include <stdlib.h> | 43 | .In stdlib.h |
| 47 | .Ft void | 44 | .Ft void |
| 48 | .Fn qsort "void *base" "size_t nmemb" "size_t size" "int (*compar)(const void *, const void *)" | 45 | .Fn qsort "void *base" "size_t nmemb" "size_t size" "int (*compar)(const void *, const void *)" |
| 49 | .Ft int | 46 | .Ft int |
| @@ -72,7 +69,7 @@ objects, the initial member of which is pointed to by | |||
| 72 | .Fa base . | 69 | .Fa base . |
| 73 | The size of each object is specified by | 70 | The size of each object is specified by |
| 74 | .Fa size . | 71 | .Fa size . |
| 75 | .Fn Mergesort | 72 | .Fn mergesort |
| 76 | behaves similarly, but | 73 | behaves similarly, but |
| 77 | .Em requires | 74 | .Em requires |
| 78 | that | 75 | that |
| @@ -106,51 +103,49 @@ is stable. | |||
| 106 | .Pp | 103 | .Pp |
| 107 | The | 104 | The |
| 108 | .Fn qsort | 105 | .Fn qsort |
| 109 | function is an implementation of C.A.R. Hoare's ``quicksort'' algorithm, | 106 | function is an implementation of C.A.R. Hoare's |
| 107 | .Dq quicksort | ||
| 108 | algorithm, | ||
| 110 | a variant of partition-exchange sorting; in particular, see D.E. Knuth's | 109 | a variant of partition-exchange sorting; in particular, see D.E. Knuth's |
| 111 | Algorithm Q. | 110 | Algorithm Q. |
| 112 | .Fn Qsort | 111 | .Fn qsort |
| 113 | takes O N lg N average time. | 112 | takes O N lg N average time. |
| 114 | This implementation uses median selection to avoid its | 113 | This implementation uses median selection to avoid its |
| 115 | O N**2 worst-case behavior. | 114 | O N**2 worst-case behavior. |
| 116 | .Pp | 115 | .Pp |
| 117 | The | 116 | The |
| 118 | .Fn heapsort | 117 | .Fn heapsort |
| 119 | function is an implementation of J.W.J. William's ``heapsort'' algorithm, | 118 | function is an implementation of J.W.J. William's |
| 119 | .Dq heapsort | ||
| 120 | algorithm, | ||
| 120 | a variant of selection sorting; in particular, see D.E. Knuth's Algorithm H. | 121 | a variant of selection sorting; in particular, see D.E. Knuth's Algorithm H. |
| 121 | .Fn Heapsort | 122 | .Fn heapsort |
| 122 | takes O N lg N worst-case time. | 123 | takes O N lg N worst-case time. |
| 123 | Its | 124 | This implementation of |
| 124 | .Em only | 125 | .Fn heapsort |
| 125 | advantage over | 126 | is implemented without recursive function calls. |
| 126 | .Fn qsort | ||
| 127 | is that it uses almost no additional memory; while | ||
| 128 | .Fn qsort | ||
| 129 | does not allocate memory, it is implemented using recursion. | ||
| 130 | .Pp | 127 | .Pp |
| 131 | The function | 128 | The function |
| 132 | .Fn mergesort | 129 | .Fn mergesort |
| 133 | requires additional memory of size | 130 | requires additional memory of size |
| 134 | .Fa nmemb * | 131 | .Fa nmemb * |
| 135 | .Fa size | 132 | .Fa size |
| 136 | bytes; it should be used only when space is not at a premium. | 133 | bytes; it should be used only when space is not at a premium. |
| 137 | .Fn Mergesort | 134 | .Fn mergesort |
| 138 | is optimized for data with pre-existing order; its worst case | 135 | is optimized for data with pre-existing order; its worst case |
| 139 | time is O N lg N; its best case is O N. | 136 | time is O N lg N; its best case is O N. |
| 140 | .Pp | 137 | .Pp |
| 141 | Normally, | 138 | Normally, |
| 142 | .Fn qsort | 139 | .Fn qsort |
| 143 | is faster than | 140 | is faster than |
| 144 | .Fn mergesort | 141 | .Fn mergesort , |
| 145 | is faster than | 142 | which is faster than |
| 146 | .Fn heapsort . | 143 | .Fn heapsort . |
| 147 | Memory availability and pre-existing order in the data can make this | 144 | Memory availability and pre-existing order in the data can make this untrue. |
| 148 | untrue. | ||
| 149 | .Sh RETURN VALUES | 145 | .Sh RETURN VALUES |
| 150 | The | 146 | The |
| 151 | .Fn qsort | 147 | .Fn qsort |
| 152 | function | 148 | function returns no value. |
| 153 | returns no value. | ||
| 154 | .Pp | 149 | .Pp |
| 155 | Upon successful completion, | 150 | Upon successful completion, |
| 156 | .Fn heapsort | 151 | .Fn heapsort |
| @@ -163,30 +158,25 @@ is set to indicate the error. | |||
| 163 | .Sh ERRORS | 158 | .Sh ERRORS |
| 164 | The | 159 | The |
| 165 | .Fn heapsort | 160 | .Fn heapsort |
| 166 | function succeeds unless: | 161 | and |
| 162 | .Fn mergesort | ||
| 163 | functions succeed unless: | ||
| 167 | .Bl -tag -width Er | 164 | .Bl -tag -width Er |
| 168 | .It Bq Er EINVAL | 165 | .It Bq Er EINVAL |
| 169 | The | 166 | The |
| 170 | .Fa size | 167 | .Fa size |
| 171 | argument is zero, or, | 168 | argument is zero, or the |
| 172 | the | ||
| 173 | .Fa size | 169 | .Fa size |
| 174 | argument to | 170 | argument to |
| 175 | .Fn mergesort | 171 | .Fn mergesort |
| 176 | is less than | 172 | is less than |
| 177 | .Dq "sizeof(void *) / 2" . | 173 | .Dq "sizeof(void *) / 2" . |
| 178 | .It Bq Er ENOMEM | 174 | .It Bq Er ENOMEM |
| 179 | .Fn Heapsort | 175 | .Fn heapsort |
| 180 | or | 176 | or |
| 181 | .Fn mergesort | 177 | .Fn mergesort |
| 182 | were unable to allocate memory. | 178 | were unable to allocate memory. |
| 183 | .El | 179 | .El |
| 184 | .Sh COMPATIBILITY | ||
| 185 | Previous versions of | ||
| 186 | .Fn qsort | ||
| 187 | did not permit the comparison routine itself to call | ||
| 188 | .Fn qsort 3 . | ||
| 189 | This is no longer true. | ||
| 190 | .Sh SEE ALSO | 180 | .Sh SEE ALSO |
| 191 | .Xr sort 1 , | 181 | .Xr sort 1 , |
| 192 | .Xr radixsort 3 | 182 | .Xr radixsort 3 |
| @@ -204,7 +194,7 @@ This is no longer true. | |||
| 204 | .%T "Heapsort" | 194 | .%T "Heapsort" |
| 205 | .%J "Communications of the ACM" | 195 | .%J "Communications of the ACM" |
| 206 | .%V 7:1 | 196 | .%V 7:1 |
| 207 | .%P pp. 347-348 | 197 | .%P pp. 347\-348 |
| 208 | .Re | 198 | .Re |
| 209 | .Rs | 199 | .Rs |
| 210 | .%A Knuth, D.E. | 200 | .%A Knuth, D.E. |
| @@ -212,23 +202,37 @@ This is no longer true. | |||
| 212 | .%B "The Art of Computer Programming" | 202 | .%B "The Art of Computer Programming" |
| 213 | .%V Vol. 3 | 203 | .%V Vol. 3 |
| 214 | .%T "Sorting and Searching" | 204 | .%T "Sorting and Searching" |
| 215 | .%P pp. 114-123, 145-149 | 205 | .%P pp. 114\-123, 145\-149 |
| 216 | .Re | 206 | .Re |
| 217 | .Rs | 207 | .Rs |
| 218 | .%A Mcilroy, P.M. | 208 | .%A McIlroy, P.M. |
| 219 | .%T "Optimistic Sorting and Information Theoretic Complexity" | 209 | .%T "Optimistic Sorting and Information Theoretic Complexity" |
| 220 | .%J "Fourth Annual ACM-SIAM Symposium on Discrete Algorithms" | 210 | .%J "Fourth Annual ACM-SIAM Symposium on Discrete Algorithms" |
| 221 | .%V January 1992 | 211 | .%P pp. 467\-464 |
| 212 | .%D January 1993 | ||
| 222 | .Re | 213 | .Re |
| 223 | .Rs | 214 | .Rs |
| 224 | .%A Bentley, J.L. | 215 | .%A Bentley, J.L. |
| 216 | .%A McIlroy, M.D. | ||
| 225 | .%T "Engineering a Sort Function" | 217 | .%T "Engineering a Sort Function" |
| 226 | .%J "bentley@research.att.com" | 218 | .%J "Software \- Practice and Experience" |
| 227 | .%V January 1992 | 219 | .%V Vol. 23(11) |
| 220 | .%P pp. 1249\-1265 | ||
| 221 | .%D November 1993 | ||
| 228 | .Re | 222 | .Re |
| 229 | .Sh STANDARDS | 223 | .Sh STANDARDS |
| 224 | Previous versions of | ||
| 225 | .Fn qsort | ||
| 226 | did not permit the comparison routine itself to call | ||
| 227 | .Fn qsort . | ||
| 228 | This is no longer true. | ||
| 229 | .Pp | ||
| 230 | The | 230 | The |
| 231 | .Fn qsort | 231 | .Fn qsort |
| 232 | function | 232 | function conforms to |
| 233 | conforms to | ||
| 234 | .St -ansiC . | 233 | .St -ansiC . |
| 234 | .Sh HISTORY | ||
| 235 | A | ||
| 236 | .Fn qsort | ||
| 237 | function first appeared in | ||
| 238 | .At v3 . | ||
diff --git a/src/lib/libc/stdlib/qsort.c b/src/lib/libc/stdlib/qsort.c index c06bd54054..f28449fb5b 100644 --- a/src/lib/libc/stdlib/qsort.c +++ b/src/lib/libc/stdlib/qsort.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: qsort.c,v 1.11 2010/02/08 11:04:07 otto Exp $ */ | ||
| 1 | /*- | 2 | /*- |
| 2 | * Copyright (c) 1992, 1993 | 3 | * Copyright (c) 1992, 1993 |
| 3 | * The Regents of the University of California. All rights reserved. | 4 | * The Regents of the University of California. All rights reserved. |
| @@ -10,11 +11,7 @@ | |||
| 10 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the |
| 12 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. Neither the name of the University nor the names of its contributors |
| 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 | 15 | * may be used to endorse or promote products derived from this software |
| 19 | * without specific prior written permission. | 16 | * without specific prior written permission. |
| 20 | * | 17 | * |
| @@ -31,16 +28,11 @@ | |||
| 31 | * SUCH DAMAGE. | 28 | * SUCH DAMAGE. |
| 32 | */ | 29 | */ |
| 33 | 30 | ||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 35 | /*static char sccsid[] = "from: @(#)qsort.c 8.1 (Berkeley) 6/4/93";*/ | ||
| 36 | static char *rcsid = "$Id: qsort.c,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $"; | ||
| 37 | #endif /* LIBC_SCCS and not lint */ | ||
| 38 | |||
| 39 | #include <sys/types.h> | 31 | #include <sys/types.h> |
| 40 | #include <stdlib.h> | 32 | #include <stdlib.h> |
| 41 | 33 | ||
| 42 | static inline char *med3 __P((char *, char *, char *, int (*)())); | 34 | static __inline char *med3(char *, char *, char *, int (*)(const void *, const void *)); |
| 43 | static inline void swapfunc __P((char *, char *, int, int)); | 35 | static __inline void swapfunc(char *, char *, size_t, int); |
| 44 | 36 | ||
| 45 | #define min(a, b) (a) < (b) ? a : b | 37 | #define min(a, b) (a) < (b) ? a : b |
| 46 | 38 | ||
| @@ -48,11 +40,11 @@ static inline void swapfunc __P((char *, char *, int, int)); | |||
| 48 | * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function". | 40 | * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function". |
| 49 | */ | 41 | */ |
| 50 | #define swapcode(TYPE, parmi, parmj, n) { \ | 42 | #define swapcode(TYPE, parmi, parmj, n) { \ |
| 51 | long i = (n) / sizeof (TYPE); \ | 43 | size_t i = (n) / sizeof (TYPE); \ |
| 52 | register TYPE *pi = (TYPE *) (parmi); \ | 44 | TYPE *pi = (TYPE *) (parmi); \ |
| 53 | register TYPE *pj = (TYPE *) (parmj); \ | 45 | TYPE *pj = (TYPE *) (parmj); \ |
| 54 | do { \ | 46 | do { \ |
| 55 | register TYPE t = *pi; \ | 47 | TYPE t = *pi; \ |
| 56 | *pi++ = *pj; \ | 48 | *pi++ = *pj; \ |
| 57 | *pj++ = t; \ | 49 | *pj++ = t; \ |
| 58 | } while (--i > 0); \ | 50 | } while (--i > 0); \ |
| @@ -61,12 +53,10 @@ static inline void swapfunc __P((char *, char *, int, int)); | |||
| 61 | #define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \ | 53 | #define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \ |
| 62 | es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1; | 54 | es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1; |
| 63 | 55 | ||
| 64 | static inline void | 56 | static __inline void |
| 65 | swapfunc(a, b, n, swaptype) | 57 | swapfunc(char *a, char *b, size_t n, int swaptype) |
| 66 | char *a, *b; | ||
| 67 | int n, swaptype; | ||
| 68 | { | 58 | { |
| 69 | if(swaptype <= 1) | 59 | if (swaptype <= 1) |
| 70 | swapcode(long, a, b, n) | 60 | swapcode(long, a, b, n) |
| 71 | else | 61 | else |
| 72 | swapcode(char, a, b, n) | 62 | swapcode(char, a, b, n) |
| @@ -82,10 +72,8 @@ swapfunc(a, b, n, swaptype) | |||
| 82 | 72 | ||
| 83 | #define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype) | 73 | #define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype) |
| 84 | 74 | ||
| 85 | static inline char * | 75 | static __inline char * |
| 86 | med3(a, b, c, cmp) | 76 | med3(char *a, char *b, char *c, int (*cmp)(const void *, const void *)) |
| 87 | char *a, *b, *c; | ||
| 88 | int (*cmp)(); | ||
| 89 | { | 77 | { |
| 90 | return cmp(a, b) < 0 ? | 78 | return cmp(a, b) < 0 ? |
| 91 | (cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a )) | 79 | (cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a )) |
| @@ -93,27 +81,26 @@ med3(a, b, c, cmp) | |||
| 93 | } | 81 | } |
| 94 | 82 | ||
| 95 | void | 83 | void |
| 96 | qsort(a, n, es, cmp) | 84 | qsort(void *aa, size_t n, size_t es, int (*cmp)(const void *, const void *)) |
| 97 | void *a; | ||
| 98 | size_t n, es; | ||
| 99 | int (*cmp)(); | ||
| 100 | { | 85 | { |
| 101 | char *pa, *pb, *pc, *pd, *pl, *pm, *pn; | 86 | char *pa, *pb, *pc, *pd, *pl, *pm, *pn; |
| 102 | int d, r, swaptype, swap_cnt; | 87 | int cmp_result, swaptype, swap_cnt; |
| 88 | size_t d, r; | ||
| 89 | char *a = aa; | ||
| 103 | 90 | ||
| 104 | loop: SWAPINIT(a, es); | 91 | loop: SWAPINIT(a, es); |
| 105 | swap_cnt = 0; | 92 | swap_cnt = 0; |
| 106 | if (n < 7) { | 93 | if (n < 7) { |
| 107 | for (pm = a + es; pm < (char *) a + n * es; pm += es) | 94 | for (pm = (char *)a + es; pm < (char *) a + n * es; pm += es) |
| 108 | for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0; | 95 | for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0; |
| 109 | pl -= es) | 96 | pl -= es) |
| 110 | swap(pl, pl - es); | 97 | swap(pl, pl - es); |
| 111 | return; | 98 | return; |
| 112 | } | 99 | } |
| 113 | pm = a + (n / 2) * es; | 100 | pm = (char *)a + (n / 2) * es; |
| 114 | if (n > 7) { | 101 | if (n > 7) { |
| 115 | pl = a; | 102 | pl = (char *)a; |
| 116 | pn = a + (n - 1) * es; | 103 | pn = (char *)a + (n - 1) * es; |
| 117 | if (n > 40) { | 104 | if (n > 40) { |
| 118 | d = (n / 8) * es; | 105 | d = (n / 8) * es; |
| 119 | pl = med3(pl, pl + d, pl + 2 * d, cmp); | 106 | pl = med3(pl, pl + d, pl + 2 * d, cmp); |
| @@ -123,20 +110,20 @@ loop: SWAPINIT(a, es); | |||
| 123 | pm = med3(pl, pm, pn, cmp); | 110 | pm = med3(pl, pm, pn, cmp); |
| 124 | } | 111 | } |
| 125 | swap(a, pm); | 112 | swap(a, pm); |
| 126 | pa = pb = a + es; | 113 | pa = pb = (char *)a + es; |
| 127 | 114 | ||
| 128 | pc = pd = a + (n - 1) * es; | 115 | pc = pd = (char *)a + (n - 1) * es; |
| 129 | for (;;) { | 116 | for (;;) { |
| 130 | while (pb <= pc && (r = cmp(pb, a)) <= 0) { | 117 | while (pb <= pc && (cmp_result = cmp(pb, a)) <= 0) { |
| 131 | if (r == 0) { | 118 | if (cmp_result == 0) { |
| 132 | swap_cnt = 1; | 119 | swap_cnt = 1; |
| 133 | swap(pa, pb); | 120 | swap(pa, pb); |
| 134 | pa += es; | 121 | pa += es; |
| 135 | } | 122 | } |
| 136 | pb += es; | 123 | pb += es; |
| 137 | } | 124 | } |
| 138 | while (pb <= pc && (r = cmp(pc, a)) >= 0) { | 125 | while (pb <= pc && (cmp_result = cmp(pc, a)) >= 0) { |
| 139 | if (r == 0) { | 126 | if (cmp_result == 0) { |
| 140 | swap_cnt = 1; | 127 | swap_cnt = 1; |
| 141 | swap(pc, pd); | 128 | swap(pc, pd); |
| 142 | pd -= es; | 129 | pd -= es; |
| @@ -151,14 +138,14 @@ loop: SWAPINIT(a, es); | |||
| 151 | pc -= es; | 138 | pc -= es; |
| 152 | } | 139 | } |
| 153 | if (swap_cnt == 0) { /* Switch to insertion sort */ | 140 | if (swap_cnt == 0) { /* Switch to insertion sort */ |
| 154 | for (pm = a + es; pm < (char *) a + n * es; pm += es) | 141 | for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es) |
| 155 | for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0; | 142 | for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0; |
| 156 | pl -= es) | 143 | pl -= es) |
| 157 | swap(pl, pl - es); | 144 | swap(pl, pl - es); |
| 158 | return; | 145 | return; |
| 159 | } | 146 | } |
| 160 | 147 | ||
| 161 | pn = a + n * es; | 148 | pn = (char *)a + n * es; |
| 162 | r = min(pa - (char *)a, pb - pa); | 149 | r = min(pa - (char *)a, pb - pa); |
| 163 | vecswap(a, pb - r, r); | 150 | vecswap(a, pb - r, r); |
| 164 | r = min(pd - pc, pn - pd - es); | 151 | r = min(pd - pc, pn - pd - es); |
diff --git a/src/lib/libc/stdlib/radixsort.3 b/src/lib/libc/stdlib/radixsort.3 index a2af9f17a4..e62f760270 100644 --- a/src/lib/libc/stdlib/radixsort.3 +++ b/src/lib/libc/stdlib/radixsort.3 | |||
| @@ -9,11 +9,7 @@ | |||
| 9 | .\" 2. Redistributions in binary form must reproduce the above copyright | 9 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 10 | .\" notice, this list of conditions and the following disclaimer in the | 10 | .\" notice, this list of conditions and the following disclaimer in the |
| 11 | .\" documentation and/or other materials provided with the distribution. | 11 | .\" documentation and/or other materials provided with the distribution. |
| 12 | .\" 3. All advertising materials mentioning features or use of this software | 12 | .\" 3. Neither the name of the University nor the names of its contributors |
| 13 | .\" must display the following acknowledgement: | ||
| 14 | .\" This product includes software developed by the University of | ||
| 15 | .\" California, Berkeley and its contributors. | ||
| 16 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 17 | .\" may be used to endorse or promote products derived from this software | 13 | .\" may be used to endorse or promote products derived from this software |
| 18 | .\" without specific prior written permission. | 14 | .\" without specific prior written permission. |
| 19 | .\" | 15 | .\" |
| @@ -29,32 +25,33 @@ | |||
| 29 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 25 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 30 | .\" SUCH DAMAGE. | 26 | .\" SUCH DAMAGE. |
| 31 | .\" | 27 | .\" |
| 32 | .\" from: @(#)radixsort.3 8.2 (Berkeley) 1/27/94 | 28 | .\" $OpenBSD: radixsort.3,v 1.12 2013/06/05 03:39:23 tedu Exp $ |
| 33 | .\" $Id: radixsort.3,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $ | ||
| 34 | .\" | 29 | .\" |
| 35 | .Dd January 27, 1994 | 30 | .Dd $Mdocdate: June 5 2013 $ |
| 36 | .Dt RADIXSORT 3 | 31 | .Dt RADIXSORT 3 |
| 37 | .Os | 32 | .Os |
| 38 | .Sh NAME | 33 | .Sh NAME |
| 39 | .Nm radixsort | 34 | .Nm radixsort , |
| 35 | .Nm sradixsort | ||
| 40 | .Nd radix sort | 36 | .Nd radix sort |
| 41 | .Sh SYNOPSIS | 37 | .Sh SYNOPSIS |
| 42 | .Fd #include <limits.h> | 38 | .In limits.h |
| 43 | .Fd #include <stdlib.h> | 39 | .In stdlib.h |
| 44 | .Ft int | 40 | .Ft int |
| 45 | .Fn radixsort "u_char **base" "int nmemb" "u_char *table" "u_int endbyte" | 41 | .Fn radixsort "const u_char **base" "int nmemb" "const u_char *table" "u_int endbyte" |
| 46 | .Ft int | 42 | .Ft int |
| 47 | .Fn sradixsort "u_char **base" "int nmemb" "u_char *table" "u_int endbyte" | 43 | .Fn sradixsort "const u_char **base" "int nmemb" "const u_char *table" "u_int endbyte" |
| 48 | .Sh DESCRIPTION | 44 | .Sh DESCRIPTION |
| 49 | The | 45 | The |
| 50 | .Fn radixsort | 46 | .Fn radixsort |
| 51 | and | 47 | and |
| 52 | .Fn sradixsort | 48 | .Fn sradixsort |
| 53 | functions | 49 | functions are implementations of radix sort. |
| 54 | are implementations of radix sort. | ||
| 55 | .Pp | 50 | .Pp |
| 56 | These functions sort an array of pointers to byte strings, the initial | 51 | These functions sort an array of |
| 57 | member of which is referenced by | 52 | .Fa nmemb |
| 53 | pointers to byte strings. | ||
| 54 | The initial member is referenced by | ||
| 58 | .Fa base . | 55 | .Fa base . |
| 59 | The byte strings may contain any values; the end of each string | 56 | The byte strings may contain any values; the end of each string |
| 60 | is denoted by the user-specified value | 57 | is denoted by the user-specified value |
| @@ -63,26 +60,24 @@ is denoted by the user-specified value | |||
| 63 | Applications may specify a sort order by providing the | 60 | Applications may specify a sort order by providing the |
| 64 | .Fa table | 61 | .Fa table |
| 65 | argument. | 62 | argument. |
| 66 | If | 63 | If non-null, |
| 67 | .Pf non- Dv NULL , | ||
| 68 | .Fa table | 64 | .Fa table |
| 69 | must reference an array of | 65 | must reference an array of |
| 70 | .Dv UCHAR_MAX | 66 | .Dv UCHAR_MAX |
| 71 | + 1 bytes which contains the sort | 67 | + 1 bytes which contains the sort weight of each possible byte value. |
| 72 | weight of each possible byte value. | ||
| 73 | The end-of-string byte must have a sort weight of 0 or 255 | 68 | The end-of-string byte must have a sort weight of 0 or 255 |
| 74 | (for sorting in reverse order). | 69 | (for sorting in reverse order). |
| 75 | More than one byte may have the same sort weight. | 70 | More than one byte may have the same sort weight. |
| 76 | The | 71 | The |
| 77 | .Fa table | 72 | .Fa table |
| 78 | argument | 73 | argument is useful for applications which wish to sort different characters |
| 79 | is useful for applications which wish to sort different characters | 74 | equally; for example, providing a table with the same weights |
| 80 | equally, for example, providing a table with the same weights | 75 | for A\-Z as for a\-z will result in a case-insensitive sort. |
| 81 | for A-Z as for a-z will result in a case-insensitive sort. | ||
| 82 | If | 76 | If |
| 83 | .Fa table | 77 | .Fa table |
| 84 | is NULL, the contents of the array are sorted in ascending order | 78 | is |
| 85 | according to the | 79 | .Dv NULL , |
| 80 | the contents of the array are sorted in ascending order according to the | ||
| 86 | .Tn ASCII | 81 | .Tn ASCII |
| 87 | order of the byte strings they reference and | 82 | order of the byte strings they reference and |
| 88 | .Fa endbyte | 83 | .Fa endbyte |
| @@ -90,7 +85,7 @@ has a sorting weight of 0. | |||
| 90 | .Pp | 85 | .Pp |
| 91 | The | 86 | The |
| 92 | .Fn sradixsort | 87 | .Fn sradixsort |
| 93 | function is stable, that is, if two elements compare as equal, their | 88 | function is stable; that is, if two elements compare as equal, their |
| 94 | order in the sorted array is unchanged. | 89 | order in the sorted array is unchanged. |
| 95 | The | 90 | The |
| 96 | .Fn sradixsort | 91 | .Fn sradixsort |
| @@ -107,7 +102,7 @@ particular, see D.E. Knuth's Algorithm R and section 5.2.5, exercise 10. | |||
| 107 | They take linear time relative to the number of bytes in the strings. | 102 | They take linear time relative to the number of bytes in the strings. |
| 108 | .Sh RETURN VALUES | 103 | .Sh RETURN VALUES |
| 109 | Upon successful completion 0 is returned. | 104 | Upon successful completion 0 is returned. |
| 110 | Otherwise, \-1 is returned and the global variable | 105 | Otherwise, \-1 is returned and the global variable |
| 111 | .Va errno | 106 | .Va errno |
| 112 | is set to indicate the error. | 107 | is set to indicate the error. |
| 113 | .Sh ERRORS | 108 | .Sh ERRORS |
| @@ -122,15 +117,13 @@ is not 0 or 255. | |||
| 122 | .Pp | 117 | .Pp |
| 123 | Additionally, the | 118 | Additionally, the |
| 124 | .Fn sradixsort | 119 | .Fn sradixsort |
| 125 | function | 120 | function may fail and set |
| 126 | may fail and set | ||
| 127 | .Va errno | 121 | .Va errno |
| 128 | for any of the errors specified for the library routine | 122 | for any of the errors specified for the library routine |
| 129 | .Xr malloc 3 . | 123 | .Xr malloc 3 . |
| 130 | .Sh SEE ALSO | 124 | .Sh SEE ALSO |
| 131 | .Xr sort 1 , | 125 | .Xr sort 1 , |
| 132 | .Xr qsort 3 | 126 | .Xr qsort 3 |
| 133 | .Pp | ||
| 134 | .Rs | 127 | .Rs |
| 135 | .%A Knuth, D.E. | 128 | .%A Knuth, D.E. |
| 136 | .%D 1968 | 129 | .%D 1968 |
| @@ -158,4 +151,5 @@ for any of the errors specified for the library routine | |||
| 158 | .Sh HISTORY | 151 | .Sh HISTORY |
| 159 | The | 152 | The |
| 160 | .Fn radixsort | 153 | .Fn radixsort |
| 161 | function first appeared in 4.4BSD. | 154 | function first appeared in |
| 155 | .Bx 4.4 . | ||
diff --git a/src/lib/libc/stdlib/radixsort.c b/src/lib/libc/stdlib/radixsort.c index dd51013c94..49d03b52d5 100644 --- a/src/lib/libc/stdlib/radixsort.c +++ b/src/lib/libc/stdlib/radixsort.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: radixsort.c,v 1.9 2007/09/02 15:19:17 deraadt Exp $ */ | ||
| 1 | /*- | 2 | /*- |
| 2 | * Copyright (c) 1990, 1993 | 3 | * Copyright (c) 1990, 1993 |
| 3 | * The Regents of the University of California. All rights reserved. | 4 | * The Regents of the University of California. All rights reserved. |
| @@ -13,11 +14,7 @@ | |||
| 13 | * 2. Redistributions in binary form must reproduce the above copyright | 14 | * 2. Redistributions in binary form must reproduce the above copyright |
| 14 | * notice, this list of conditions and the following disclaimer in the | 15 | * notice, this list of conditions and the following disclaimer in the |
| 15 | * documentation and/or other materials provided with the distribution. | 16 | * documentation and/or other materials provided with the distribution. |
| 16 | * 3. All advertising materials mentioning features or use of this software | 17 | * 3. Neither the name of the University nor the names of its contributors |
| 17 | * must display the following acknowledgement: | ||
| 18 | * This product includes software developed by the University of | ||
| 19 | * California, Berkeley and its contributors. | ||
| 20 | * 4. Neither the name of the University nor the names of its contributors | ||
| 21 | * may be used to endorse or promote products derived from this software | 18 | * may be used to endorse or promote products derived from this software |
| 22 | * without specific prior written permission. | 19 | * without specific prior written permission. |
| 23 | * | 20 | * |
| @@ -34,11 +31,6 @@ | |||
| 34 | * SUCH DAMAGE. | 31 | * SUCH DAMAGE. |
| 35 | */ | 32 | */ |
| 36 | 33 | ||
| 37 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 38 | /*static char sccsid[] = "from: @(#)radixsort.c 8.1 (Berkeley) 6/4/93";*/ | ||
| 39 | static char *rcsid = "$Id: radixsort.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $"; | ||
| 40 | #endif /* LIBC_SCCS and not lint */ | ||
| 41 | |||
| 42 | /* | 34 | /* |
| 43 | * Radixsort routines. | 35 | * Radixsort routines. |
| 44 | * | 36 | * |
| @@ -61,11 +53,11 @@ typedef struct { | |||
| 61 | int sn, si; | 53 | int sn, si; |
| 62 | } stack; | 54 | } stack; |
| 63 | 55 | ||
| 64 | static inline void simplesort | 56 | static __inline void simplesort |
| 65 | __P((const u_char **, int, int, const u_char *, u_int)); | 57 | (const u_char **, int, int, const u_char *, u_int); |
| 66 | static void r_sort_a __P((const u_char **, int, int, const u_char *, u_int)); | 58 | static void r_sort_a(const u_char **, int, int, const u_char *, u_int); |
| 67 | static void r_sort_b __P((const u_char **, | 59 | static void r_sort_b(const u_char **, |
| 68 | const u_char **, int, int, const u_char *, u_int)); | 60 | const u_char **, int, int, const u_char *, u_int); |
| 69 | 61 | ||
| 70 | #define THRESHOLD 20 /* Divert to simplesort(). */ | 62 | #define THRESHOLD 20 /* Divert to simplesort(). */ |
| 71 | #define SIZE 512 /* Default stack size. */ | 63 | #define SIZE 512 /* Default stack size. */ |
| @@ -90,10 +82,7 @@ static void r_sort_b __P((const u_char **, | |||
| 90 | } | 82 | } |
| 91 | 83 | ||
| 92 | int | 84 | int |
| 93 | radixsort(a, n, tab, endch) | 85 | radixsort(const u_char **a, int n, const u_char *tab, u_int endch) |
| 94 | const u_char **a, *tab; | ||
| 95 | int n; | ||
| 96 | u_int endch; | ||
| 97 | { | 86 | { |
| 98 | const u_char *tr; | 87 | const u_char *tr; |
| 99 | int c; | 88 | int c; |
| @@ -105,10 +94,7 @@ radixsort(a, n, tab, endch) | |||
| 105 | } | 94 | } |
| 106 | 95 | ||
| 107 | int | 96 | int |
| 108 | sradixsort(a, n, tab, endch) | 97 | sradixsort(const u_char **a, int n, const u_char *tab, u_int endch) |
| 109 | const u_char **a, *tab; | ||
| 110 | int n; | ||
| 111 | u_int endch; | ||
| 112 | { | 98 | { |
| 113 | const u_char *tr, **ta; | 99 | const u_char *tr, **ta; |
| 114 | int c; | 100 | int c; |
| @@ -118,7 +104,7 @@ sradixsort(a, n, tab, endch) | |||
| 118 | if (n < THRESHOLD) | 104 | if (n < THRESHOLD) |
| 119 | simplesort(a, n, 0, tr, endch); | 105 | simplesort(a, n, 0, tr, endch); |
| 120 | else { | 106 | else { |
| 121 | if ((ta = malloc(n * sizeof(a))) == NULL) | 107 | if ((ta = calloc(n, sizeof(a))) == NULL) |
| 122 | return (-1); | 108 | return (-1); |
| 123 | r_sort_b(a, ta, n, 0, tr, endch); | 109 | r_sort_b(a, ta, n, 0, tr, endch); |
| 124 | free(ta); | 110 | free(ta); |
| @@ -133,15 +119,11 @@ sradixsort(a, n, tab, endch) | |||
| 133 | 119 | ||
| 134 | /* Unstable, in-place sort. */ | 120 | /* Unstable, in-place sort. */ |
| 135 | void | 121 | void |
| 136 | r_sort_a(a, n, i, tr, endch) | 122 | r_sort_a(const u_char **a, int n, int i, const u_char *tr, u_int endch) |
| 137 | const u_char **a; | ||
| 138 | int n, i; | ||
| 139 | const u_char *tr; | ||
| 140 | u_int endch; | ||
| 141 | { | 123 | { |
| 142 | static int count[256], nc, bmin; | 124 | static int count[256], nc, bmin; |
| 143 | register int c; | 125 | int c; |
| 144 | register const u_char **ak, *r; | 126 | const u_char **ak, *r; |
| 145 | stack s[SIZE], *sp, *sp0, *sp1, temp; | 127 | stack s[SIZE], *sp, *sp0, *sp1, temp; |
| 146 | int *cp, bigc; | 128 | int *cp, bigc; |
| 147 | const u_char **an, *t, **aj, **top[256]; | 129 | const u_char **an, *t, **aj, **top[256]; |
| @@ -224,15 +206,12 @@ r_sort_a(a, n, i, tr, endch) | |||
| 224 | 206 | ||
| 225 | /* Stable sort, requiring additional memory. */ | 207 | /* Stable sort, requiring additional memory. */ |
| 226 | void | 208 | void |
| 227 | r_sort_b(a, ta, n, i, tr, endch) | 209 | r_sort_b(const u_char **a, const u_char **ta, int n, int i, const u_char *tr, |
| 228 | const u_char **a, **ta; | 210 | u_int endch) |
| 229 | int n, i; | ||
| 230 | const u_char *tr; | ||
| 231 | u_int endch; | ||
| 232 | { | 211 | { |
| 233 | static int count[256], nc, bmin; | 212 | static int count[256], nc, bmin; |
| 234 | register int c; | 213 | int c; |
| 235 | register const u_char **ak, **ai; | 214 | const u_char **ak, **ai; |
| 236 | stack s[512], *sp, *sp0, *sp1, temp; | 215 | stack s[512], *sp, *sp0, *sp1, temp; |
| 237 | const u_char **top[256]; | 216 | const u_char **top[256]; |
| 238 | int *cp, bigc; | 217 | int *cp, bigc; |
| @@ -295,14 +274,11 @@ r_sort_b(a, ta, n, i, tr, endch) | |||
| 295 | } | 274 | } |
| 296 | } | 275 | } |
| 297 | 276 | ||
| 298 | static inline void | 277 | static __inline void |
| 299 | simplesort(a, n, b, tr, endch) /* insertion sort */ | 278 | simplesort(const u_char **a, int n, int b, const u_char *tr, u_int endch) |
| 300 | register const u_char **a; | 279 | /* insertion sort */ |
| 301 | int n, b; | ||
| 302 | register const u_char *tr; | ||
| 303 | u_int endch; | ||
| 304 | { | 280 | { |
| 305 | register u_char ch; | 281 | u_char ch; |
| 306 | const u_char **ak, **ai, *s, *t; | 282 | const u_char **ak, **ai, *s, *t; |
| 307 | 283 | ||
| 308 | for (ak = a+1; --n >= 1; ak++) | 284 | for (ak = a+1; --n >= 1; ak++) |
diff --git a/src/lib/libc/stdlib/rand.3 b/src/lib/libc/stdlib/rand.3 index a0e7740e66..75395976f8 100644 --- a/src/lib/libc/stdlib/rand.3 +++ b/src/lib/libc/stdlib/rand.3 | |||
| @@ -13,11 +13,7 @@ | |||
| 13 | .\" 2. Redistributions in binary form must reproduce the above copyright | 13 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 14 | .\" notice, this list of conditions and the following disclaimer in the | 14 | .\" notice, this list of conditions and the following disclaimer in the |
| 15 | .\" documentation and/or other materials provided with the distribution. | 15 | .\" documentation and/or other materials provided with the distribution. |
| 16 | .\" 3. All advertising materials mentioning features or use of this software | 16 | .\" 3. Neither the name of the University nor the names of its contributors |
| 17 | .\" must display the following acknowledgement: | ||
| 18 | .\" This product includes software developed by the University of | ||
| 19 | .\" California, Berkeley and its contributors. | ||
| 20 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 21 | .\" may be used to endorse or promote products derived from this software | 17 | .\" may be used to endorse or promote products derived from this software |
| 22 | .\" without specific prior written permission. | 18 | .\" without specific prior written permission. |
| 23 | .\" | 19 | .\" |
| @@ -33,25 +29,28 @@ | |||
| 33 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 29 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 34 | .\" SUCH DAMAGE. | 30 | .\" SUCH DAMAGE. |
| 35 | .\" | 31 | .\" |
| 36 | .\" from: @(#)rand.3 6.7 (Berkeley) 6/29/91 | 32 | .\" $OpenBSD: rand.3,v 1.15 2014/04/07 17:57:56 schwarze Exp $ |
| 37 | .\" $Id: rand.3,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $ | ||
| 38 | .\" | 33 | .\" |
| 39 | .Dd June 29, 1991 | 34 | .Dd $Mdocdate: April 7 2014 $ |
| 40 | .Dt RAND 3 | 35 | .Dt RAND 3 |
| 41 | .Os | 36 | .Os |
| 42 | .Sh NAME | 37 | .Sh NAME |
| 43 | .Nm rand , | 38 | .Nm rand , |
| 39 | .Nm rand_r , | ||
| 44 | .Nm srand | 40 | .Nm srand |
| 45 | .Nd bad random number generator | 41 | .Nd bad random number generator |
| 46 | .Sh SYNOPSIS | 42 | .Sh SYNOPSIS |
| 47 | .Fd #include <stdlib.h> | 43 | .In stdlib.h |
| 48 | .Ft void | 44 | .Ft void |
| 49 | .Fn srand "unsigned seed" | 45 | .Fn srand "unsigned int seed" |
| 50 | .Ft int | 46 | .Ft int |
| 51 | .Fn rand void | 47 | .Fn rand void |
| 48 | .Ft int | ||
| 49 | .Fn rand_r "unsigned int *seed" | ||
| 52 | .Sh DESCRIPTION | 50 | .Sh DESCRIPTION |
| 53 | .Bf -symbolic | 51 | .Bf -symbolic |
| 54 | These interfaces are obsoleted by random(3). | 52 | These interfaces are obsoleted by |
| 53 | .Xr random 3 . | ||
| 55 | .Ef | 54 | .Ef |
| 56 | .Pp | 55 | .Pp |
| 57 | The | 56 | The |
| @@ -60,7 +59,7 @@ function computes a sequence of pseudo-random integers in the range | |||
| 60 | of 0 to | 59 | of 0 to |
| 61 | .Dv RAND_MAX | 60 | .Dv RAND_MAX |
| 62 | (as defined by the header file | 61 | (as defined by the header file |
| 63 | .Aq Pa stdlib.h ) . | 62 | .In stdlib.h ) . |
| 64 | .Pp | 63 | .Pp |
| 65 | The | 64 | The |
| 66 | .Fn srand | 65 | .Fn srand |
| @@ -73,13 +72,34 @@ with the same seed value. | |||
| 73 | .Pp | 72 | .Pp |
| 74 | If no seed value is provided, the functions are automatically | 73 | If no seed value is provided, the functions are automatically |
| 75 | seeded with a value of 1. | 74 | seeded with a value of 1. |
| 75 | .Pp | ||
| 76 | The | ||
| 77 | .Fn rand_r | ||
| 78 | is a thread-safe version of | ||
| 79 | .Fn rand . | ||
| 80 | Storage for the seed must be provided through the | ||
| 81 | .Fa seed | ||
| 82 | argument, and needs to have been initialized by the caller. | ||
| 76 | .Sh SEE ALSO | 83 | .Sh SEE ALSO |
| 84 | .Xr arc4random 3 , | ||
| 85 | .Xr rand48 3 , | ||
| 77 | .Xr random 3 | 86 | .Xr random 3 |
| 78 | .Sh STANDARDS | 87 | .Sh STANDARDS |
| 79 | The | 88 | The |
| 80 | .Fn rand | 89 | .Fn rand |
| 81 | and | 90 | and |
| 82 | .Fn srand | 91 | .Fn srand |
| 83 | functions | 92 | functions conform to |
| 84 | conform to | ||
| 85 | .St -ansiC . | 93 | .St -ansiC . |
| 94 | .Pp | ||
| 95 | The | ||
| 96 | .Fn rand_r | ||
| 97 | function conforms to | ||
| 98 | .St -p1003.1-2008 . | ||
| 99 | .Sh HISTORY | ||
| 100 | The functions | ||
| 101 | .Fn rand | ||
| 102 | and | ||
| 103 | .Fn srand | ||
| 104 | first appeared in | ||
| 105 | .At v3 . | ||
diff --git a/src/lib/libc/stdlib/rand.c b/src/lib/libc/stdlib/rand.c index 361d473448..6860dd4f71 100644 --- a/src/lib/libc/stdlib/rand.c +++ b/src/lib/libc/stdlib/rand.c | |||
| @@ -10,11 +10,7 @@ | |||
| 10 | * 2. Redistributions in binary form must reproduce the above copyright | 10 | * 2. Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in the | 11 | * notice, this list of conditions and the following disclaimer in the |
| 12 | * documentation and/or other materials provided with the distribution. | 12 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. All advertising materials mentioning features or use of this software | 13 | * 3. Neither the name of the University nor the names of its contributors |
| 14 | * must display the following acknowledgement: | ||
| 15 | * This product includes software developed by the University of | ||
| 16 | * California, Berkeley and its contributors. | ||
| 17 | * 4. Neither the name of the University nor the names of its contributors | ||
| 18 | * may be used to endorse or promote products derived from this software | 14 | * may be used to endorse or promote products derived from this software |
| 19 | * without specific prior written permission. | 15 | * without specific prior written permission. |
| 20 | * | 16 | * |
| @@ -31,25 +27,41 @@ | |||
| 31 | * SUCH DAMAGE. | 27 | * SUCH DAMAGE. |
| 32 | */ | 28 | */ |
| 33 | 29 | ||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 35 | /*static char *sccsid = "from: @(#)rand.c 5.6 (Berkeley) 6/24/91";*/ | ||
| 36 | static char *rcsid = "$Id: rand.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $"; | ||
| 37 | #endif /* LIBC_SCCS and not lint */ | ||
| 38 | |||
| 39 | #include <sys/types.h> | 30 | #include <sys/types.h> |
| 40 | #include <stdlib.h> | 31 | #include <stdlib.h> |
| 41 | 32 | ||
| 42 | static u_long next = 1; | 33 | static u_int next = 1; |
| 34 | |||
| 35 | int | ||
| 36 | rand_r(u_int *seed) | ||
| 37 | { | ||
| 38 | *seed = *seed * 1103515245 + 12345; | ||
| 39 | return (*seed % ((u_int)RAND_MAX + 1)); | ||
| 40 | } | ||
| 41 | |||
| 42 | #if defined(APIWARN) | ||
| 43 | __warn_references(rand_r, | ||
| 44 | "warning: rand_r() isn't random; consider using arc4random()"); | ||
| 45 | #endif | ||
| 43 | 46 | ||
| 44 | int | 47 | int |
| 45 | rand() | 48 | rand(void) |
| 46 | { | 49 | { |
| 47 | return ((next = next * 1103515245 + 12345) % ((u_int)RAND_MAX + 1)); | 50 | return (rand_r(&next)); |
| 48 | } | 51 | } |
| 49 | 52 | ||
| 53 | #if defined(APIWARN) | ||
| 54 | __warn_references(rand, | ||
| 55 | "warning: rand() isn't random; consider using arc4random()"); | ||
| 56 | #endif | ||
| 57 | |||
| 50 | void | 58 | void |
| 51 | srand(seed) | 59 | srand(u_int seed) |
| 52 | u_int seed; | ||
| 53 | { | 60 | { |
| 54 | next = seed; | 61 | next = seed; |
| 55 | } | 62 | } |
| 63 | |||
| 64 | #if defined(APIWARN) | ||
| 65 | __warn_references(srand, | ||
| 66 | "warning: srand() seed choices are invariably poor"); | ||
| 67 | #endif | ||
diff --git a/src/lib/libc/stdlib/rand48.3 b/src/lib/libc/stdlib/rand48.3 index 5a772c9a8c..8b7c572fb4 100644 --- a/src/lib/libc/stdlib/rand48.3 +++ b/src/lib/libc/stdlib/rand48.3 | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | \" Copyright (c) 1993 Martin Birgmeier | 1 | .\" Copyright (c) 1993 Martin Birgmeier |
| 2 | .\" All rights reserved. | 2 | .\" All rights reserved. |
| 3 | .\" | 3 | .\" |
| 4 | .\" You may redistribute unmodified or modified versions of this source | 4 | .\" You may redistribute unmodified or modified versions of this source |
| @@ -9,9 +9,9 @@ | |||
| 9 | .\" of any kind. I shall in no event be liable for anything that happens | 9 | .\" of any kind. I shall in no event be liable for anything that happens |
| 10 | .\" to anyone/anything when using this software. | 10 | .\" to anyone/anything when using this software. |
| 11 | .\" | 11 | .\" |
| 12 | .\" $Id: rand48.3,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $ | 12 | .\" $OpenBSD: rand48.3,v 1.14 2014/01/21 23:25:03 deraadt Exp $ |
| 13 | .\" | 13 | .\" |
| 14 | .Dd October 8, 1993 | 14 | .Dd $Mdocdate: January 21 2014 $ |
| 15 | .Dt RAND48 3 | 15 | .Dt RAND48 3 |
| 16 | .Os | 16 | .Os |
| 17 | .Sh NAME | 17 | .Sh NAME |
| @@ -24,10 +24,10 @@ | |||
| 24 | .Nm srand48 , | 24 | .Nm srand48 , |
| 25 | .Nm seed48 , | 25 | .Nm seed48 , |
| 26 | .Nm lcong48 | 26 | .Nm lcong48 |
| 27 | .Nd pseudo random number generators and initialization routines | 27 | .Nd pseudo-random number generators and initialization routines |
| 28 | .Sh SYNOPSIS | 28 | .Sh SYNOPSIS |
| 29 | .Fd #include <stdlib.h> | 29 | .In stdlib.h |
| 30 | .Ft double | 30 | .Ft double |
| 31 | .Fn drand48 void | 31 | .Fn drand48 void |
| 32 | .Ft double | 32 | .Ft double |
| 33 | .Fn erand48 "unsigned short xseed[3]" | 33 | .Fn erand48 "unsigned short xseed[3]" |
| @@ -49,12 +49,13 @@ | |||
| 49 | The | 49 | The |
| 50 | .Fn rand48 | 50 | .Fn rand48 |
| 51 | family of functions generates pseudo-random numbers using a linear | 51 | family of functions generates pseudo-random numbers using a linear |
| 52 | congruential algorithm working on integers 48 bits in size. The | 52 | congruential algorithm working on integers 48 bits in size. |
| 53 | particular formula employed is | 53 | The particular formula employed is |
| 54 | r(n+1) = (a * r(n) + c) mod m | 54 | r(n+1) = (a * r(n) + c) mod m |
| 55 | where the default values are | 55 | where the default values are |
| 56 | for the multiplicand a = 0xfdeece66d = 25214903917 and | 56 | for the multiplicand a = 0xfdeece66d = 25214903917 and |
| 57 | the addend c = 0xb = 11. The modulus is always fixed at m = 2 ** 48. | 57 | the addend c = 0xb = 11. |
| 58 | The modulus is always fixed at m = 2 ** 48. | ||
| 58 | r(n) is called the seed of the random number generator. | 59 | r(n) is called the seed of the random number generator. |
| 59 | .Pp | 60 | .Pp |
| 60 | For all the six generator routines described next, the first | 61 | For all the six generator routines described next, the first |
| @@ -63,15 +64,17 @@ computational step is to perform a single iteration of the algorithm. | |||
| 63 | .Fn drand48 | 64 | .Fn drand48 |
| 64 | and | 65 | and |
| 65 | .Fn erand48 | 66 | .Fn erand48 |
| 66 | return values of type double. The full 48 bits of r(n+1) are | 67 | return values of type double. |
| 68 | The full 48 bits of r(n+1) are | ||
| 67 | loaded into the mantissa of the returned value, with the exponent set | 69 | loaded into the mantissa of the returned value, with the exponent set |
| 68 | such that the values produced lie in the interval [0.0, 1.0). | 70 | such that the values produced lie in the interval [0.0, 1.0]. |
| 69 | .Pp | 71 | .Pp |
| 70 | .Fn lrand48 | 72 | .Fn lrand48 |
| 71 | and | 73 | and |
| 72 | .Fn nrand48 | 74 | .Fn nrand48 |
| 73 | return values of type long in the range | 75 | return values of type long in the range |
| 74 | [0, 2**31-1]. The high-order (31) bits of | 76 | [0, 2**31-1]. |
| 77 | The high-order (31) bits of | ||
| 75 | r(n+1) are loaded into the lower bits of the returned value, with | 78 | r(n+1) are loaded into the lower bits of the returned value, with |
| 76 | the topmost (sign) bit set to zero. | 79 | the topmost (sign) bit set to zero. |
| 77 | .Pp | 80 | .Pp |
| @@ -79,14 +82,15 @@ the topmost (sign) bit set to zero. | |||
| 79 | and | 82 | and |
| 80 | .Fn jrand48 | 83 | .Fn jrand48 |
| 81 | return values of type long in the range | 84 | return values of type long in the range |
| 82 | [-2**31, 2**31-1]. The high-order (32) bits of | 85 | [-2**31, 2**31-1]. |
| 83 | r(n+1) are loaded into the returned value. | 86 | The high-order (32) bits of r(n+1) are loaded into the returned value. |
| 84 | .Pp | 87 | .Pp |
| 85 | .Fn drand48 , | 88 | .Fn drand48 , |
| 86 | .Fn lrand48 , | 89 | .Fn lrand48 , |
| 87 | and | 90 | and |
| 88 | .Fn mrand48 | 91 | .Fn mrand48 |
| 89 | use an internal buffer to store r(n). For these functions | 92 | use an internal buffer to store r(n). |
| 93 | For these functions | ||
| 90 | the initial value of r(0) = 0x1234abcd330e = 20017429951246. | 94 | the initial value of r(0) = 0x1234abcd330e = 20017429951246. |
| 91 | .Pp | 95 | .Pp |
| 92 | On the other hand, | 96 | On the other hand, |
| @@ -118,12 +122,12 @@ also initializes the internal buffer r(n) of | |||
| 118 | and | 122 | and |
| 119 | .Fn mrand48 , | 123 | .Fn mrand48 , |
| 120 | but here all 48 bits of the seed can be specified in an array of 3 shorts, | 124 | but here all 48 bits of the seed can be specified in an array of 3 shorts, |
| 121 | where the zeroth member specifies the lowest bits. Again, | 125 | where the zeroth member specifies the lowest bits. |
| 122 | the constant multiplicand and addend of the algorithm are | 126 | Again, the constant multiplicand and addend of the algorithm are |
| 123 | reset to the default values given above. | 127 | reset to the default values given above. |
| 124 | .Fn seed48 | 128 | .Fn seed48 |
| 125 | returns a pointer to an array of 3 shorts which contains the old seed. | 129 | returns a pointer to an array of 3 shorts which contains the old seed. |
| 126 | This array is statically allocated, thus its contents are lost after | 130 | This array is statically allocated, so its contents are lost after |
| 127 | each new call to | 131 | each new call to |
| 128 | .Fn seed48 . | 132 | .Fn seed48 . |
| 129 | .Pp | 133 | .Pp |
| @@ -152,9 +156,24 @@ always also set the multiplicand and addend for any of the six | |||
| 152 | generator calls. | 156 | generator calls. |
| 153 | .Pp | 157 | .Pp |
| 154 | For a more powerful random number generator, see | 158 | For a more powerful random number generator, see |
| 155 | .Xr random 3 | 159 | .Xr arc4random 3 . |
| 156 | .Sh AUTHOR | ||
| 157 | Martin Birgmeier | ||
| 158 | .Sh SEE ALSO | 160 | .Sh SEE ALSO |
| 161 | .Xr arc4random 3 , | ||
| 159 | .Xr rand 3 , | 162 | .Xr rand 3 , |
| 160 | .Xr random 3 . | 163 | .Xr random 3 |
| 164 | .Sh STANDARDS | ||
| 165 | The | ||
| 166 | .Fn drand48 , | ||
| 167 | .Fn erand48 , | ||
| 168 | .Fn jrand48 , | ||
| 169 | .Fn lcong48 , | ||
| 170 | .Fn lrand48 , | ||
| 171 | .Fn mrand48 , | ||
| 172 | .Fn nrand48 , | ||
| 173 | .Fn seed48 , | ||
| 174 | and | ||
| 175 | .Fn srand48 | ||
| 176 | functions conform to | ||
| 177 | .St -p1003.1-2008 . | ||
| 178 | .Sh AUTHORS | ||
| 179 | Martin Birgmeier | ||
diff --git a/src/lib/libc/stdlib/rand48.h b/src/lib/libc/stdlib/rand48.h index 12496d1c8c..afa49f65f3 100644 --- a/src/lib/libc/stdlib/rand48.h +++ b/src/lib/libc/stdlib/rand48.h | |||
| @@ -9,6 +9,8 @@ | |||
| 9 | * This software is provided ``as is'', and comes with no warranties | 9 | * This software is provided ``as is'', and comes with no warranties |
| 10 | * of any kind. I shall in no event be liable for anything that happens | 10 | * of any kind. I shall in no event be liable for anything that happens |
| 11 | * to anyone/anything when using this software. | 11 | * to anyone/anything when using this software. |
| 12 | * | ||
| 13 | * $OpenBSD: rand48.h,v 1.3 2002/02/16 21:27:24 millert Exp $ | ||
| 12 | */ | 14 | */ |
| 13 | 15 | ||
| 14 | #ifndef _RAND48_H_ | 16 | #ifndef _RAND48_H_ |
| @@ -17,7 +19,7 @@ | |||
| 17 | #include <math.h> | 19 | #include <math.h> |
| 18 | #include <stdlib.h> | 20 | #include <stdlib.h> |
| 19 | 21 | ||
| 20 | void __dorand48 __P((unsigned short[3])); | 22 | void __dorand48(unsigned short[3]); |
| 21 | 23 | ||
| 22 | #define RAND48_SEED_0 (0x330e) | 24 | #define RAND48_SEED_0 (0x330e) |
| 23 | #define RAND48_SEED_1 (0xabcd) | 25 | #define RAND48_SEED_1 (0xabcd) |
diff --git a/src/lib/libc/stdlib/random.3 b/src/lib/libc/stdlib/random.3 index 38c15a9803..fdb78848d8 100644 --- a/src/lib/libc/stdlib/random.3 +++ b/src/lib/libc/stdlib/random.3 | |||
| @@ -9,11 +9,7 @@ | |||
| 9 | .\" 2. Redistributions in binary form must reproduce the above copyright | 9 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 10 | .\" notice, this list of conditions and the following disclaimer in the | 10 | .\" notice, this list of conditions and the following disclaimer in the |
| 11 | .\" documentation and/or other materials provided with the distribution. | 11 | .\" documentation and/or other materials provided with the distribution. |
| 12 | .\" 3. All advertising materials mentioning features or use of this software | 12 | .\" 3. Neither the name of the University nor the names of its contributors |
| 13 | .\" must display the following acknowledgement: | ||
| 14 | .\" This product includes software developed by the University of | ||
| 15 | .\" California, Berkeley and its contributors. | ||
| 16 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 17 | .\" may be used to endorse or promote products derived from this software | 13 | .\" may be used to endorse or promote products derived from this software |
| 18 | .\" without specific prior written permission. | 14 | .\" without specific prior written permission. |
| 19 | .\" | 15 | .\" |
| @@ -29,97 +25,105 @@ | |||
| 29 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 25 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 30 | .\" SUCH DAMAGE. | 26 | .\" SUCH DAMAGE. |
| 31 | .\" | 27 | .\" |
| 32 | .\" from: @(#)random.3 6.5 (Berkeley) 4/19/91 | 28 | .\" $OpenBSD: random.3,v 1.21 2013/06/05 03:39:23 tedu Exp $ |
| 33 | .\" $Id: random.3,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $ | ||
| 34 | .\" | 29 | .\" |
| 35 | .Dd April 19, 1991 | 30 | .Dd $Mdocdate: June 5 2013 $ |
| 36 | .Dt RANDOM 3 | 31 | .Dt RANDOM 3 |
| 37 | .Os BSD 4.2 | 32 | .Os |
| 38 | .Sh NAME | 33 | .Sh NAME |
| 39 | .Nm random , | 34 | .Nm random , |
| 40 | .Nm srandom , | 35 | .Nm srandom , |
| 36 | .Nm srandomdev , | ||
| 41 | .Nm initstate , | 37 | .Nm initstate , |
| 42 | .Nm setstate | 38 | .Nm setstate |
| 43 | .Nd better random number generator; routines for changing generators | 39 | .Nd better random number generator; routines for changing generators |
| 44 | .Sh SYNOPSIS | 40 | .Sh SYNOPSIS |
| 45 | .Fd #include <stdlib.h> | 41 | .In stdlib.h |
| 46 | .Ft long | 42 | .Ft long |
| 47 | .Fn random void | 43 | .Fn random void |
| 48 | .Ft void | 44 | .Ft void |
| 49 | .Fn srandom "unsigned seed" | 45 | .Fn srandom "unsigned int seed" |
| 46 | .Ft void | ||
| 47 | .Fn srandomdev void | ||
| 50 | .Ft char * | 48 | .Ft char * |
| 51 | .Fn initstate "unsigned seed" "char *state" "int n" | 49 | .Fn initstate "unsigned int seed" "char *state" "size_t n" |
| 52 | .Ft char * | 50 | .Ft char * |
| 53 | .Fn setstate "char *state" | 51 | .Fn setstate "char *state" |
| 54 | .Sh DESCRIPTION | 52 | .Sh DESCRIPTION |
| 55 | The | 53 | The |
| 56 | .Fn random | 54 | .Fn random |
| 57 | function | 55 | function uses a non-linear additive feedback random number generator employing |
| 58 | uses a non-linear additive feedback random number generator employing a | 56 | a default table of size 31 long integers to return successive pseudo-random |
| 59 | default table of size 31 long integers to return successive pseudo-random | 57 | numbers in the range from 0 to (2**31)\-1. |
| 60 | numbers in the range from 0 to | ||
| 61 | .if t 2\u\s731\s10\d\(mi1. | ||
| 62 | .if n (2**31)\(mi1. | ||
| 63 | The period of this random number generator is very large, approximately | 58 | The period of this random number generator is very large, approximately |
| 64 | .if t 16\(mu(2\u\s731\s10\d\(mi1). | 59 | 16*((2**31)\-1). |
| 65 | .if n 16*((2**31)\(mi1). | ||
| 66 | .Pp | 60 | .Pp |
| 67 | The | 61 | The |
| 68 | .Fn random Ns / Fn srandom | 62 | .Fn random |
| 69 | have (almost) the same calling sequence and initialization properties as | 63 | and |
| 70 | .Xr rand 3 Ns / Xr srand 3 . | 64 | .Fn srandom |
| 65 | functions have (almost) the same calling sequence and initialization | ||
| 66 | properties as | ||
| 67 | .Xr rand 3 Ns / Ns Xr srand 3 . | ||
| 71 | The difference is that | 68 | The difference is that |
| 72 | .Xr rand | 69 | .Xr rand |
| 73 | produces a much less random sequence \(em in fact, the low dozen bits | 70 | produces a much less random sequence \(em in fact, the low dozen bits |
| 74 | generated by rand go through a cyclic pattern. All the bits generated by | 71 | generated by rand go through a cyclic pattern. |
| 72 | All the bits generated by | ||
| 75 | .Fn random | 73 | .Fn random |
| 76 | are usable. For example, | 74 | are usable. |
| 75 | For example, | ||
| 77 | .Sq Li random()&01 | 76 | .Sq Li random()&01 |
| 78 | will produce a random binary | 77 | will produce a random binary |
| 79 | value. | 78 | value. |
| 80 | .Pp | 79 | .Pp |
| 81 | Unlike | 80 | Like |
| 82 | .Xr srand , | ||
| 83 | .Fn srandom | ||
| 84 | does not return the old seed; the reason for this is that the amount of | ||
| 85 | state information used is much more than a single word. (Two other | ||
| 86 | routines are provided to deal with restarting/changing random | ||
| 87 | number generators). Like | ||
| 88 | .Xr rand 3 , | 81 | .Xr rand 3 , |
| 89 | however, | ||
| 90 | .Fn random | 82 | .Fn random |
| 91 | will by default produce a sequence of numbers that can be duplicated | 83 | will by default produce a sequence of numbers that can be duplicated |
| 92 | by calling | 84 | by calling |
| 93 | .Fn srandom | 85 | .Fn srandom |
| 94 | with | 86 | with |
| 95 | .Ql 1 | 87 | .Ql 1 |
| 96 | as the seed. | 88 | as the seed. |
| 97 | .Pp | 89 | .Pp |
| 98 | The | 90 | The |
| 91 | .Fn srandomdev | ||
| 92 | routine initializes a state array using | ||
| 93 | random numbers obtained from the kernel, | ||
| 94 | suitable for cryptographic use. | ||
| 95 | Note that this particular seeding procedure can generate | ||
| 96 | states which are impossible to reproduce by calling | ||
| 97 | .Fn srandom | ||
| 98 | with any value, since the succeeding terms in the | ||
| 99 | state buffer are no longer derived from the LC algorithm applied to | ||
| 100 | a fixed seed. | ||
| 101 | .Pp | ||
| 102 | The | ||
| 99 | .Fn initstate | 103 | .Fn initstate |
| 100 | routine allows a state array, passed in as an argument, to be initialized | 104 | routine allows a state array, passed in as an argument, to be initialized |
| 101 | for future use. The size of the state array (in bytes) is used by | 105 | for future use. |
| 106 | The size of the state array (in bytes) is used by | ||
| 102 | .Fn initstate | 107 | .Fn initstate |
| 103 | to decide how sophisticated a random number generator it should use \(em the | 108 | to decide how sophisticated a random number generator it should use \(em the |
| 104 | more state, the better the random numbers will be. | 109 | more state, the better the random numbers will be. |
| 105 | (Current "optimal" values for the amount of state information are | 110 | (Current "optimal" values for the amount of state information are |
| 106 | 8, 32, 64, 128, and 256 bytes; other amounts will be rounded down to | 111 | 8, 32, 64, 128, and 256 bytes; other amounts will be rounded down to |
| 107 | the nearest known amount. Using less than 8 bytes will cause an error.) | 112 | the nearest known amount. |
| 113 | Using less than 8 bytes will cause an error.) | ||
| 108 | The seed for the initialization (which specifies a starting point for | 114 | The seed for the initialization (which specifies a starting point for |
| 109 | the random number sequence, and provides for restarting at the same | 115 | the random number sequence, and provides for restarting at the same |
| 110 | point) is also an argument. | 116 | point) is also an argument. |
| 111 | The | 117 | The |
| 112 | .Fn initstate | 118 | .Fn initstate |
| 113 | function | 119 | function returns a pointer to the previous state information array. |
| 114 | returns a pointer to the previous state information array. | ||
| 115 | .Pp | 120 | .Pp |
| 116 | Once a state has been initialized, the | 121 | Once a state has been initialized, the |
| 117 | .Fn setstate | 122 | .Fn setstate |
| 118 | routine provides for rapid switching between states. | 123 | routine provides for rapid switching between states. |
| 119 | The | 124 | The |
| 120 | .Fn setstate | 125 | .Fn setstate |
| 121 | function | 126 | function returns a pointer to the previous state array; its |
| 122 | returns a pointer to the previous state array; its | ||
| 123 | argument state array is used for further random number generation | 127 | argument state array is used for further random number generation |
| 124 | until the next call to | 128 | until the next call to |
| 125 | .Fn initstate | 129 | .Fn initstate |
| @@ -143,12 +147,8 @@ is that the size of the state array does not have to be remembered after | |||
| 143 | it is initialized. | 147 | it is initialized. |
| 144 | .Pp | 148 | .Pp |
| 145 | With 256 bytes of state information, the period of the random number | 149 | With 256 bytes of state information, the period of the random number |
| 146 | generator is greater than | 150 | generator is greater than 2**69 |
| 147 | .if t 2\u\s769\s10\d, | ||
| 148 | .if n 2**69 | ||
| 149 | which should be sufficient for most purposes. | 151 | which should be sufficient for most purposes. |
| 150 | .Sh AUTHOR | ||
| 151 | Earl T. Cohen | ||
| 152 | .Sh DIAGNOSTICS | 152 | .Sh DIAGNOSTICS |
| 153 | If | 153 | If |
| 154 | .Fn initstate | 154 | .Fn initstate |
| @@ -157,11 +157,29 @@ is called with less than 8 bytes of state information, or if | |||
| 157 | detects that the state information has been garbled, error | 157 | detects that the state information has been garbled, error |
| 158 | messages are printed on the standard error output. | 158 | messages are printed on the standard error output. |
| 159 | .Sh SEE ALSO | 159 | .Sh SEE ALSO |
| 160 | .Xr rand 3 | 160 | .Xr arc4random 3 , |
| 161 | .Xr drand48 3 , | ||
| 162 | .Xr rand 3 , | ||
| 163 | .Xr random 4 | ||
| 164 | .Sh STANDARDS | ||
| 165 | The | ||
| 166 | .Fn random , | ||
| 167 | .Fn srandom , | ||
| 168 | .Fn initstate , | ||
| 169 | and | ||
| 170 | .Fn setstate | ||
| 171 | functions conform to | ||
| 172 | .St -xpg4.2 . | ||
| 173 | .Pp | ||
| 174 | The | ||
| 175 | .Fn srandomdev | ||
| 176 | function is an extension. | ||
| 161 | .Sh HISTORY | 177 | .Sh HISTORY |
| 162 | These | 178 | These |
| 163 | functions appeared in | 179 | functions appeared in |
| 164 | .Bx 4.2 . | 180 | .Bx 4.2 . |
| 181 | .Sh AUTHORS | ||
| 182 | .An Earl T. Cohen | ||
| 165 | .Sh BUGS | 183 | .Sh BUGS |
| 166 | About 2/3 the speed of | 184 | About 2/3 the speed of |
| 167 | .Xr rand 3 . | 185 | .Xr rand 3 . |
diff --git a/src/lib/libc/stdlib/random.c b/src/lib/libc/stdlib/random.c index 469b6d976a..00edf2dca1 100644 --- a/src/lib/libc/stdlib/random.c +++ b/src/lib/libc/stdlib/random.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: random.c,v 1.19 2013/08/01 19:42:08 kettenis Exp $ */ | ||
| 1 | /* | 2 | /* |
| 2 | * Copyright (c) 1983 Regents of the University of California. | 3 | * Copyright (c) 1983 Regents of the University of California. |
| 3 | * All rights reserved. | 4 | * All rights reserved. |
| @@ -10,11 +11,7 @@ | |||
| 10 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the |
| 12 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. Neither the name of the University nor the names of its contributors |
| 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 | 15 | * may be used to endorse or promote products derived from this software |
| 19 | * without specific prior written permission. | 16 | * without specific prior written permission. |
| 20 | * | 17 | * |
| @@ -31,13 +28,15 @@ | |||
| 31 | * SUCH DAMAGE. | 28 | * SUCH DAMAGE. |
| 32 | */ | 29 | */ |
| 33 | 30 | ||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | 31 | #include <sys/param.h> |
| 35 | /*static char *sccsid = "from: @(#)random.c 5.9 (Berkeley) 2/23/91";*/ | 32 | #include <sys/sysctl.h> |
| 36 | static char *rcsid = "$Id: random.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $"; | 33 | #include <sys/time.h> |
| 37 | #endif /* LIBC_SCCS and not lint */ | 34 | #include <fcntl.h> |
| 38 | |||
| 39 | #include <stdio.h> | 35 | #include <stdio.h> |
| 40 | #include <stdlib.h> | 36 | #include <stdlib.h> |
| 37 | #include <unistd.h> | ||
| 38 | |||
| 39 | #include "thread_private.h" | ||
| 41 | 40 | ||
| 42 | /* | 41 | /* |
| 43 | * random.c: | 42 | * random.c: |
| @@ -55,10 +54,10 @@ static char *rcsid = "$Id: random.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $" | |||
| 55 | * congruential generator. If the amount of state information is less than | 54 | * congruential generator. If the amount of state information is less than |
| 56 | * 32 bytes, a simple linear congruential R.N.G. is used. | 55 | * 32 bytes, a simple linear congruential R.N.G. is used. |
| 57 | * | 56 | * |
| 58 | * Internally, the state information is treated as an array of longs; the | 57 | * Internally, the state information is treated as an array of int32_t; the |
| 59 | * zeroeth element of the array is the type of R.N.G. being used (small | 58 | * zeroeth element of the array is the type of R.N.G. being used (small |
| 60 | * integer); the remainder of the array is the state information for the | 59 | * integer); the remainder of the array is the state information for the |
| 61 | * R.N.G. Thus, 32 bytes of state information will give 7 longs worth of | 60 | * R.N.G. Thus, 32 bytes of state information will give 7 int32_ts worth of |
| 62 | * state information, which will allow a degree seven polynomial. (Note: | 61 | * state information, which will allow a degree seven polynomial. (Note: |
| 63 | * the zeroeth word of state information also has some other information | 62 | * the zeroeth word of state information also has some other information |
| 64 | * stored in it -- see setstate() for details). | 63 | * stored in it -- see setstate() for details). |
| @@ -134,14 +133,14 @@ static int seps [MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 }; | |||
| 134 | * MAX_TYPES * (rptr - state) + TYPE_3 == TYPE_3. | 133 | * MAX_TYPES * (rptr - state) + TYPE_3 == TYPE_3. |
| 135 | */ | 134 | */ |
| 136 | 135 | ||
| 137 | static long randtbl[DEG_3 + 1] = { | 136 | static int32_t randtbl[DEG_3 + 1] = { |
| 138 | TYPE_3, | 137 | TYPE_3, |
| 139 | 0x9a319039, 0x32d9c024, 0x9b663182, 0x5da1f342, 0xde3b81e0, 0xdf0a6fb5, | 138 | 0x991539b1, 0x16a5bce3, 0x6774a4cd, 0x3e01511e, 0x4e508aaa, 0x61048c05, |
| 140 | 0xf103bc02, 0x48f340fb, 0x7449e56b, 0xbeb1dbb0, 0xab5c5918, 0x946554fd, | 139 | 0xf5500617, 0x846b7115, 0x6a19892c, 0x896a97af, 0xdb48f936, 0x14898454, |
| 141 | 0x8c2e680f, 0xeb3d799f, 0xb11ee0b7, 0x2d436b86, 0xda672e2a, 0x1588ca88, | 140 | 0x37ffd106, 0xb58bff9c, 0x59e17104, 0xcf918a49, 0x09378c83, 0x52c7a471, |
| 142 | 0xe369735d, 0x904f35f7, 0xd7158fd6, 0x6fa6f051, 0x616e6b96, 0xac94efdc, | 141 | 0x8d293ea9, 0x1f4fc301, 0xc3db71be, 0x39b44e1c, 0xf8a44ef9, 0x4c8b80b1, |
| 143 | 0x36413f93, 0xc622c298, 0xf5a42ab8, 0x8a88d77b, 0xf5ad9d0e, 0x8999220b, | 142 | 0x19edc328, 0x87bf4bdd, 0xc9b240e5, 0xe9ee4b1b, 0x4382aee7, 0x535b6b41, |
| 144 | 0x27fb47b9, | 143 | 0xf3bec5da, |
| 145 | }; | 144 | }; |
| 146 | 145 | ||
| 147 | /* | 146 | /* |
| @@ -158,8 +157,8 @@ static long randtbl[DEG_3 + 1] = { | |||
| 158 | * in the initialization of randtbl) because the state table pointer is set | 157 | * in the initialization of randtbl) because the state table pointer is set |
| 159 | * to point to randtbl[1] (as explained below). | 158 | * to point to randtbl[1] (as explained below). |
| 160 | */ | 159 | */ |
| 161 | static long *fptr = &randtbl[SEP_3 + 1]; | 160 | static int32_t *fptr = &randtbl[SEP_3 + 1]; |
| 162 | static long *rptr = &randtbl[1]; | 161 | static int32_t *rptr = &randtbl[1]; |
| 163 | 162 | ||
| 164 | /* | 163 | /* |
| 165 | * The following things are the pointer to the state information table, the | 164 | * The following things are the pointer to the state information table, the |
| @@ -171,11 +170,17 @@ static long *rptr = &randtbl[1]; | |||
| 171 | * this is more efficient than indexing every time to find the address of | 170 | * this is more efficient than indexing every time to find the address of |
| 172 | * the last element to see if the front and rear pointers have wrapped. | 171 | * the last element to see if the front and rear pointers have wrapped. |
| 173 | */ | 172 | */ |
| 174 | static long *state = &randtbl[1]; | 173 | static int32_t *state = &randtbl[1]; |
| 174 | static int32_t *end_ptr = &randtbl[DEG_3 + 1]; | ||
| 175 | static int rand_type = TYPE_3; | 175 | static int rand_type = TYPE_3; |
| 176 | static int rand_deg = DEG_3; | 176 | static int rand_deg = DEG_3; |
| 177 | static int rand_sep = SEP_3; | 177 | static int rand_sep = SEP_3; |
| 178 | static long *end_ptr = &randtbl[DEG_3 + 1]; | 178 | |
| 179 | _THREAD_PRIVATE_MUTEX(random); | ||
| 180 | static long random_l(void); | ||
| 181 | |||
| 182 | #define LOCK() _THREAD_PRIVATE_MUTEX_LOCK(random) | ||
| 183 | #define UNLOCK() _THREAD_PRIVATE_MUTEX_UNLOCK(random) | ||
| 179 | 184 | ||
| 180 | /* | 185 | /* |
| 181 | * srandom: | 186 | * srandom: |
| @@ -189,26 +194,89 @@ static long *end_ptr = &randtbl[DEG_3 + 1]; | |||
| 189 | * introduced by the L.C.R.N.G. Note that the initialization of randtbl[] | 194 | * introduced by the L.C.R.N.G. Note that the initialization of randtbl[] |
| 190 | * for default usage relies on values produced by this routine. | 195 | * for default usage relies on values produced by this routine. |
| 191 | */ | 196 | */ |
| 192 | void | 197 | static void |
| 193 | srandom(x) | 198 | srandom_l(unsigned int x) |
| 194 | u_int x; | ||
| 195 | { | 199 | { |
| 196 | register int i, j; | 200 | int i; |
| 201 | int32_t test; | ||
| 202 | div_t val; | ||
| 197 | 203 | ||
| 198 | if (rand_type == TYPE_0) | 204 | if (rand_type == TYPE_0) |
| 199 | state[0] = x; | 205 | state[0] = x; |
| 200 | else { | 206 | else { |
| 201 | j = 1; | 207 | /* A seed of 0 would result in state[] always being zero. */ |
| 202 | state[0] = x; | 208 | state[0] = x ? x : 1; |
| 203 | for (i = 1; i < rand_deg; i++) | 209 | for (i = 1; i < rand_deg; i++) { |
| 204 | state[i] = 1103515245 * state[i - 1] + 12345; | 210 | /* |
| 211 | * Implement the following, without overflowing 31 bits: | ||
| 212 | * | ||
| 213 | * state[i] = (16807 * state[i - 1]) % 2147483647; | ||
| 214 | * | ||
| 215 | * 2^31-1 (prime) = 2147483647 = 127773*16807+2836 | ||
| 216 | */ | ||
| 217 | val = div(state[i-1], 127773); | ||
| 218 | test = 16807 * val.rem - 2836 * val.quot; | ||
| 219 | state[i] = test + (test < 0 ? 2147483647 : 0); | ||
| 220 | } | ||
| 205 | fptr = &state[rand_sep]; | 221 | fptr = &state[rand_sep]; |
| 206 | rptr = &state[0]; | 222 | rptr = &state[0]; |
| 207 | for (i = 0; i < 10 * rand_deg; i++) | 223 | for (i = 0; i < 10 * rand_deg; i++) |
| 208 | (void)random(); | 224 | (void)random_l(); |
| 209 | } | 225 | } |
| 210 | } | 226 | } |
| 211 | 227 | ||
| 228 | void | ||
| 229 | srandom(unsigned int x) | ||
| 230 | { | ||
| 231 | LOCK(); | ||
| 232 | srandom_l(x); | ||
| 233 | UNLOCK(); | ||
| 234 | } | ||
| 235 | |||
| 236 | #if defined(APIWARN) | ||
| 237 | __warn_references(srandom, | ||
| 238 | "warning: srandom() seed choices are invariably poor"); | ||
| 239 | #endif | ||
| 240 | |||
| 241 | /* | ||
| 242 | * srandomdev: | ||
| 243 | * | ||
| 244 | * Many programs choose the seed value in a totally predictable manner. | ||
| 245 | * This often causes problems. We seed the generator using random | ||
| 246 | * data from the kernel. | ||
| 247 | * Note that this particular seeding procedure can generate states | ||
| 248 | * which are impossible to reproduce by calling srandom() with any | ||
| 249 | * value, since the succeeding terms in the state buffer are no longer | ||
| 250 | * derived from the LC algorithm applied to a fixed seed. | ||
| 251 | */ | ||
| 252 | void | ||
| 253 | srandomdev(void) | ||
| 254 | { | ||
| 255 | int mib[2]; | ||
| 256 | size_t len; | ||
| 257 | |||
| 258 | LOCK(); | ||
| 259 | if (rand_type == TYPE_0) | ||
| 260 | len = sizeof(state[0]); | ||
| 261 | else | ||
| 262 | len = rand_deg * sizeof(state[0]); | ||
| 263 | |||
| 264 | mib[0] = CTL_KERN; | ||
| 265 | mib[1] = KERN_ARND; | ||
| 266 | sysctl(mib, 2, state, &len, NULL, 0); | ||
| 267 | |||
| 268 | if (rand_type != TYPE_0) { | ||
| 269 | fptr = &state[rand_sep]; | ||
| 270 | rptr = &state[0]; | ||
| 271 | } | ||
| 272 | UNLOCK(); | ||
| 273 | } | ||
| 274 | |||
| 275 | #if defined(APIWARN) | ||
| 276 | __warn_references(srandomdev, | ||
| 277 | "warning: srandomdev() usage; consider switching to arc4random()"); | ||
| 278 | #endif | ||
| 279 | |||
| 212 | /* | 280 | /* |
| 213 | * initstate: | 281 | * initstate: |
| 214 | * | 282 | * |
| @@ -229,21 +297,18 @@ srandom(x) | |||
| 229 | * Returns a pointer to the old state. | 297 | * Returns a pointer to the old state. |
| 230 | */ | 298 | */ |
| 231 | char * | 299 | char * |
| 232 | initstate(seed, arg_state, n) | 300 | initstate(u_int seed, char *arg_state, size_t n) |
| 233 | u_int seed; /* seed for R.N.G. */ | ||
| 234 | char *arg_state; /* pointer to state array */ | ||
| 235 | int n; /* # bytes of state info */ | ||
| 236 | { | 301 | { |
| 237 | register char *ostate = (char *)(&state[-1]); | 302 | char *ostate = (char *)(&state[-1]); |
| 238 | 303 | ||
| 304 | LOCK(); | ||
| 239 | if (rand_type == TYPE_0) | 305 | if (rand_type == TYPE_0) |
| 240 | state[-1] = rand_type; | 306 | state[-1] = rand_type; |
| 241 | else | 307 | else |
| 242 | state[-1] = MAX_TYPES * (rptr - state) + rand_type; | 308 | state[-1] = MAX_TYPES * (rptr - state) + rand_type; |
| 243 | if (n < BREAK_0) { | 309 | if (n < BREAK_0) { |
| 244 | (void)fprintf(stderr, | 310 | UNLOCK(); |
| 245 | "random: not enough state (%d bytes); ignored.\n", n); | 311 | return(NULL); |
| 246 | return(0); | ||
| 247 | } | 312 | } |
| 248 | if (n < BREAK_1) { | 313 | if (n < BREAK_1) { |
| 249 | rand_type = TYPE_0; | 314 | rand_type = TYPE_0; |
| @@ -266,13 +331,14 @@ initstate(seed, arg_state, n) | |||
| 266 | rand_deg = DEG_4; | 331 | rand_deg = DEG_4; |
| 267 | rand_sep = SEP_4; | 332 | rand_sep = SEP_4; |
| 268 | } | 333 | } |
| 269 | state = &(((long *)arg_state)[1]); /* first location */ | 334 | state = &(((int32_t *)arg_state)[1]); /* first location */ |
| 270 | end_ptr = &state[rand_deg]; /* must set end_ptr before srandom */ | 335 | end_ptr = &state[rand_deg]; /* must set end_ptr before srandom */ |
| 271 | srandom(seed); | 336 | srandom_l(seed); |
| 272 | if (rand_type == TYPE_0) | 337 | if (rand_type == TYPE_0) |
| 273 | state[-1] = rand_type; | 338 | state[-1] = rand_type; |
| 274 | else | 339 | else |
| 275 | state[-1] = MAX_TYPES*(rptr - state) + rand_type; | 340 | state[-1] = MAX_TYPES*(rptr - state) + rand_type; |
| 341 | UNLOCK(); | ||
| 276 | return(ostate); | 342 | return(ostate); |
| 277 | } | 343 | } |
| 278 | 344 | ||
| @@ -292,14 +358,14 @@ initstate(seed, arg_state, n) | |||
| 292 | * Returns a pointer to the old state information. | 358 | * Returns a pointer to the old state information. |
| 293 | */ | 359 | */ |
| 294 | char * | 360 | char * |
| 295 | setstate(arg_state) | 361 | setstate(char *arg_state) |
| 296 | char *arg_state; | ||
| 297 | { | 362 | { |
| 298 | register long *new_state = (long *)arg_state; | 363 | int32_t *new_state = (int32_t *)arg_state; |
| 299 | register int type = new_state[0] % MAX_TYPES; | 364 | int32_t type = new_state[0] % MAX_TYPES; |
| 300 | register int rear = new_state[0] / MAX_TYPES; | 365 | int32_t rear = new_state[0] / MAX_TYPES; |
| 301 | char *ostate = (char *)(&state[-1]); | 366 | char *ostate = (char *)(&state[-1]); |
| 302 | 367 | ||
| 368 | LOCK(); | ||
| 303 | if (rand_type == TYPE_0) | 369 | if (rand_type == TYPE_0) |
| 304 | state[-1] = rand_type; | 370 | state[-1] = rand_type; |
| 305 | else | 371 | else |
| @@ -315,8 +381,8 @@ setstate(arg_state) | |||
| 315 | rand_sep = seps[type]; | 381 | rand_sep = seps[type]; |
| 316 | break; | 382 | break; |
| 317 | default: | 383 | default: |
| 318 | (void)fprintf(stderr, | 384 | UNLOCK(); |
| 319 | "random: state info corrupted; not changed.\n"); | 385 | return(NULL); |
| 320 | } | 386 | } |
| 321 | state = &new_state[1]; | 387 | state = &new_state[1]; |
| 322 | if (rand_type != TYPE_0) { | 388 | if (rand_type != TYPE_0) { |
| @@ -324,6 +390,7 @@ setstate(arg_state) | |||
| 324 | fptr = &state[(rear + rand_sep) % rand_deg]; | 390 | fptr = &state[(rear + rand_sep) % rand_deg]; |
| 325 | } | 391 | } |
| 326 | end_ptr = &state[rand_deg]; /* set end_ptr too */ | 392 | end_ptr = &state[rand_deg]; /* set end_ptr too */ |
| 393 | UNLOCK(); | ||
| 327 | return(ostate); | 394 | return(ostate); |
| 328 | } | 395 | } |
| 329 | 396 | ||
| @@ -344,10 +411,10 @@ setstate(arg_state) | |||
| 344 | * | 411 | * |
| 345 | * Returns a 31-bit random number. | 412 | * Returns a 31-bit random number. |
| 346 | */ | 413 | */ |
| 347 | long | 414 | static long |
| 348 | random() | 415 | random_l(void) |
| 349 | { | 416 | { |
| 350 | long i; | 417 | int32_t i; |
| 351 | 418 | ||
| 352 | if (rand_type == TYPE_0) | 419 | if (rand_type == TYPE_0) |
| 353 | i = state[0] = (state[0] * 1103515245 + 12345) & 0x7fffffff; | 420 | i = state[0] = (state[0] * 1103515245 + 12345) & 0x7fffffff; |
| @@ -360,5 +427,20 @@ random() | |||
| 360 | } else if (++rptr >= end_ptr) | 427 | } else if (++rptr >= end_ptr) |
| 361 | rptr = state; | 428 | rptr = state; |
| 362 | } | 429 | } |
| 363 | return(i); | 430 | return((long)i); |
| 431 | } | ||
| 432 | |||
| 433 | long | ||
| 434 | random(void) | ||
| 435 | { | ||
| 436 | long r; | ||
| 437 | LOCK(); | ||
| 438 | r = random_l(); | ||
| 439 | UNLOCK(); | ||
| 440 | return r; | ||
| 364 | } | 441 | } |
| 442 | |||
| 443 | #if defined(APIWARN) | ||
| 444 | __warn_references(random, | ||
| 445 | "warning: random() isn't random; consider using arc4random()"); | ||
| 446 | #endif | ||
diff --git a/src/lib/libc/stdlib/realloc.3 b/src/lib/libc/stdlib/realloc.3 deleted file mode 100644 index 66f09b2081..0000000000 --- a/src/lib/libc/stdlib/realloc.3 +++ /dev/null | |||
| @@ -1,100 +0,0 @@ | |||
| 1 | .\" Copyright (c) 1991 The Regents of the University of California. | ||
| 2 | .\" All rights reserved. | ||
| 3 | .\" | ||
| 4 | .\" Redistribution and use in source and binary forms, with or without | ||
| 5 | .\" modification, are permitted provided that the following conditions | ||
| 6 | .\" are met: | ||
| 7 | .\" 1. Redistributions of source code must retain the above copyright | ||
| 8 | .\" notice, this list of conditions and the following disclaimer. | ||
| 9 | .\" 2. Redistributions in binary form must reproduce the above copyright | ||
| 10 | .\" notice, this list of conditions and the following disclaimer in the | ||
| 11 | .\" documentation and/or other materials provided with the distribution. | ||
| 12 | .\" 3. All advertising materials mentioning features or use of this software | ||
| 13 | .\" must display the following acknowledgement: | ||
| 14 | .\" This product includes software developed by the University of | ||
| 15 | .\" California, Berkeley and its contributors. | ||
| 16 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 17 | .\" may be used to endorse or promote products derived from this software | ||
| 18 | .\" without specific prior written permission. | ||
| 19 | .\" | ||
| 20 | .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
| 21 | .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 22 | .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 23 | .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
| 24 | .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 25 | .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 26 | .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 27 | .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 28 | .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 29 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 30 | .\" SUCH DAMAGE. | ||
| 31 | .\" | ||
| 32 | .\" from: @(#)realloc.3 5.1 (Berkeley) 5/2/91 | ||
| 33 | .\" $Id: realloc.3,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $ | ||
| 34 | .\" | ||
| 35 | .Dd May 2, 1991 | ||
| 36 | .Dt REALLOC 3 | ||
| 37 | .Os | ||
| 38 | .Sh NAME | ||
| 39 | .Nm realloc | ||
| 40 | .Nd reallocation of memory function | ||
| 41 | .Sh SYNOPSIS | ||
| 42 | .Fd #include <stdlib.h> | ||
| 43 | .Ft void * | ||
| 44 | .Fn realloc "void *ptr" "size_t size" | ||
| 45 | .Sh DESCRIPTION | ||
| 46 | The | ||
| 47 | .Fn realloc | ||
| 48 | function changes the size of the object pointed to by | ||
| 49 | .Fa ptr | ||
| 50 | to the size specified by | ||
| 51 | .Fa size . | ||
| 52 | The contents of the object are unchanged up to the lesser | ||
| 53 | of the new and old sizes. | ||
| 54 | If the new size is larger, the value of the newly allocated portion | ||
| 55 | of the object is indeterminate. | ||
| 56 | If | ||
| 57 | .Fa ptr | ||
| 58 | is a null pointer, the | ||
| 59 | .Fn realloc | ||
| 60 | function behaves like the | ||
| 61 | .Xr malloc 3 | ||
| 62 | function for the specified size. | ||
| 63 | Otherwise, if | ||
| 64 | .Fa ptr | ||
| 65 | does not match a pointer earlier returned by the | ||
| 66 | .Xr calloc 3 , | ||
| 67 | .Xr malloc 3 , | ||
| 68 | or | ||
| 69 | .Fn realloc | ||
| 70 | function, or if the space has been deallocated | ||
| 71 | by a call to the | ||
| 72 | .Xr free | ||
| 73 | or | ||
| 74 | .Fn realloc | ||
| 75 | function, unpredictable and usually detrimental | ||
| 76 | behavior will occur. | ||
| 77 | If the space cannot be allocated, the object | ||
| 78 | pointed to by | ||
| 79 | .Fa ptr | ||
| 80 | is unchanged. | ||
| 81 | If | ||
| 82 | .Fa size | ||
| 83 | is zero and | ||
| 84 | .Fa ptr | ||
| 85 | is not a null pointer, the object it points to is freed. | ||
| 86 | .Pp | ||
| 87 | The | ||
| 88 | .Fn realloc | ||
| 89 | function returns either a null pointer or a pointer | ||
| 90 | to the possibly moved allocated space. | ||
| 91 | .Sh SEE ALSO | ||
| 92 | .Xr alloca 3 , | ||
| 93 | .Xr calloc 3 , | ||
| 94 | .Xr free 3 , | ||
| 95 | .Xr malloc 3 , | ||
| 96 | .Sh STANDARDS | ||
| 97 | The | ||
| 98 | .Fn realloc | ||
| 99 | function conforms to | ||
| 100 | .St -ansiC . | ||
diff --git a/src/lib/libc/stdlib/realpath.3 b/src/lib/libc/stdlib/realpath.3 index 9d8b1ff2ce..5966b38058 100644 --- a/src/lib/libc/stdlib/realpath.3 +++ b/src/lib/libc/stdlib/realpath.3 | |||
| @@ -12,11 +12,7 @@ | |||
| 12 | .\" 2. Redistributions in binary form must reproduce the above copyright | 12 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 13 | .\" notice, this list of conditions and the following disclaimer in the | 13 | .\" notice, this list of conditions and the following disclaimer in the |
| 14 | .\" documentation and/or other materials provided with the distribution. | 14 | .\" documentation and/or other materials provided with the distribution. |
| 15 | .\" 3. All advertising materials mentioning features or use of this software | 15 | .\" 3. Neither the name of the University nor the names of its contributors |
| 16 | .\" must display the following acknowledgement: | ||
| 17 | .\" This product includes software developed by the University of | ||
| 18 | .\" California, Berkeley and its contributors. | ||
| 19 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 20 | .\" may be used to endorse or promote products derived from this software | 16 | .\" may be used to endorse or promote products derived from this software |
| 21 | .\" without specific prior written permission. | 17 | .\" without specific prior written permission. |
| 22 | .\" | 18 | .\" |
| @@ -32,20 +28,19 @@ | |||
| 32 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 28 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 33 | .\" SUCH DAMAGE. | 29 | .\" SUCH DAMAGE. |
| 34 | .\" | 30 | .\" |
| 35 | .\" from: @(#)realpath.3 8.2 (Berkeley) 2/16/94 | 31 | .\" $OpenBSD: realpath.3,v 1.19 2014/01/20 22:40:06 schwarze Exp $ |
| 36 | .\" $Id: realpath.3,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $ | ||
| 37 | .\" | 32 | .\" |
| 38 | .Dd "February 16, 1994" | 33 | .Dd $Mdocdate: January 20 2014 $ |
| 39 | .Dt REALPATH 3 | 34 | .Dt REALPATH 3 |
| 40 | .Os | 35 | .Os |
| 41 | .Sh NAME | 36 | .Sh NAME |
| 42 | .Nm realpath | 37 | .Nm realpath |
| 43 | .Nd returns the canonicalized absolute pathname | 38 | .Nd returns the canonicalized absolute pathname |
| 44 | .Sh SYNOPSIS | 39 | .Sh SYNOPSIS |
| 45 | .Fd #include <sys/param.h> | 40 | .In limits.h |
| 46 | .Fd #include <stdlib.h> | 41 | .In stdlib.h |
| 47 | .Ft "char *" | 42 | .Ft "char *" |
| 48 | .Fn realpath "const char *pathname" "char resolvedname[MAXPATHLEN]" | 43 | .Fn realpath "const char *pathname" "char *resolved" |
| 49 | .Sh DESCRIPTION | 44 | .Sh DESCRIPTION |
| 50 | The | 45 | The |
| 51 | .Fn realpath | 46 | .Fn realpath |
| @@ -57,18 +52,18 @@ and | |||
| 57 | .Pa /../ | 52 | .Pa /../ |
| 58 | in | 53 | in |
| 59 | .Fa pathname , | 54 | .Fa pathname , |
| 60 | and copies the resulting absolute pathname into | 55 | and copies the resulting absolute pathname into the memory referenced by |
| 61 | the memory referenced by | 56 | .Fa resolved . |
| 62 | .Fa resolvedname . | ||
| 63 | The | 57 | The |
| 64 | .Fa resolvedname | 58 | .Fa resolved |
| 65 | argument | 59 | argument |
| 66 | .Em must | 60 | .Em must |
| 67 | refer to a buffer capable of storing at least | 61 | refer to a buffer capable of storing at least |
| 68 | .Dv MAXPATHLEN | 62 | .Dv PATH_MAX |
| 69 | characters. | 63 | characters, or be |
| 64 | .Dv NULL . | ||
| 70 | .Pp | 65 | .Pp |
| 71 | The | 66 | The |
| 72 | .Fn realpath | 67 | .Fn realpath |
| 73 | function will resolve both absolute and relative paths | 68 | function will resolve both absolute and relative paths |
| 74 | and return the absolute pathname corresponding to | 69 | and return the absolute pathname corresponding to |
| @@ -78,33 +73,49 @@ All but the last component of | |||
| 78 | must exist when | 73 | must exist when |
| 79 | .Fn realpath | 74 | .Fn realpath |
| 80 | is called. | 75 | is called. |
| 81 | .Sh "RETURN VALUES" | 76 | .Sh RETURN VALUES |
| 82 | The | 77 | The |
| 83 | .Fn realpath | 78 | .Fn realpath |
| 84 | function returns | 79 | function returns |
| 85 | .Fa resolved_name | 80 | .Fa resolved |
| 86 | on success. | 81 | on success. |
| 82 | If | ||
| 83 | .Fa resolved | ||
| 84 | is | ||
| 85 | .Dv NULL | ||
| 86 | and no error occurred, then | ||
| 87 | .Fn realpath | ||
| 88 | returns a NUL-terminated string in a newly allocated buffer. | ||
| 87 | If an error occurs, | 89 | If an error occurs, |
| 88 | .Fn realpath | 90 | .Fn realpath |
| 89 | returns | 91 | returns |
| 90 | .Dv NULL , | 92 | .Dv NULL |
| 91 | and | 93 | and the contents of |
| 92 | .Fa resolved_name | 94 | .Fa resolved |
| 93 | contains the pathname which caused the problem. | 95 | are undefined. |
| 94 | .Sh ERRORS | 96 | .Sh ERRORS |
| 95 | The function | 97 | The function |
| 96 | .Fn realpath | 98 | .Fn realpath |
| 97 | may fail and set the external variable | 99 | may fail and set the external variable |
| 98 | .Va errno | 100 | .Va errno |
| 99 | for any of the errors specified for the library functions | 101 | for any of the errors specified for the library functions |
| 100 | .Xr chdir 2 , | ||
| 101 | .Xr close 2 , | ||
| 102 | .Xr fchdir 2 , | ||
| 103 | .Xr lstat 2 , | 102 | .Xr lstat 2 , |
| 104 | .Xr open 2 , | 103 | .Xr readlink 2 , |
| 105 | .Xr readlink 2 | ||
| 106 | and | 104 | and |
| 107 | .Xr getcwd 3 . | 105 | .Xr getcwd 3 . |
| 106 | .Sh SEE ALSO | ||
| 107 | .Xr readlink 1 , | ||
| 108 | .Xr getcwd 3 | ||
| 109 | .Sh STANDARDS | ||
| 110 | The | ||
| 111 | .Fn realpath | ||
| 112 | function conforms to | ||
| 113 | .St -p1003.1-2008 . | ||
| 114 | .Sh HISTORY | ||
| 115 | The | ||
| 116 | .Fn realpath | ||
| 117 | function call first appeared in | ||
| 118 | .Bx 4.4 . | ||
| 108 | .Sh CAVEATS | 119 | .Sh CAVEATS |
| 109 | This implementation of | 120 | This implementation of |
| 110 | .Fn realpath | 121 | .Fn realpath |
| @@ -114,13 +125,6 @@ The | |||
| 114 | version always returns absolute pathnames, | 125 | version always returns absolute pathnames, |
| 115 | whereas the Solaris implementation will, | 126 | whereas the Solaris implementation will, |
| 116 | under certain circumstances, return a relative | 127 | under certain circumstances, return a relative |
| 117 | .Fa resolved_path | 128 | .Fa resolved |
| 118 | when given a relative | 129 | when given a relative |
| 119 | .Fa pathname . | 130 | .Fa pathname . |
| 120 | .Sh "SEE ALSO" | ||
| 121 | .Xr getcwd 3 | ||
| 122 | .Sh HISTORY | ||
| 123 | The | ||
| 124 | .Fn realpath | ||
| 125 | function call first appeared in | ||
| 126 | .Bx 4.4 . | ||
diff --git a/src/lib/libc/stdlib/realpath.c b/src/lib/libc/stdlib/realpath.c index e349b7e068..e0f9b123b3 100644 --- a/src/lib/libc/stdlib/realpath.c +++ b/src/lib/libc/stdlib/realpath.c | |||
| @@ -1,9 +1,6 @@ | |||
| 1 | /* $OpenBSD: realpath.c,v 1.16 2013/04/05 12:59:54 kurt Exp $ */ | ||
| 1 | /* | 2 | /* |
| 2 | * Copyright (c) 1994 | 3 | * Copyright (c) 2003 Constantin S. Svintsoff <kostik@iclub.nsu.ru> |
| 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 | * | 4 | * |
| 8 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
| 9 | * modification, are permitted provided that the following conditions | 6 | * modification, are permitted provided that the following conditions |
| @@ -13,18 +10,14 @@ | |||
| 13 | * 2. Redistributions in binary form must reproduce the above copyright | 10 | * 2. Redistributions in binary form must reproduce the above copyright |
| 14 | * notice, this list of conditions and the following disclaimer in the | 11 | * notice, this list of conditions and the following disclaimer in the |
| 15 | * documentation and/or other materials provided with the distribution. | 12 | * documentation and/or other materials provided with the distribution. |
| 16 | * 3. All advertising materials mentioning features or use of this software | 13 | * 3. The names of the authors may not be used to endorse or promote |
| 17 | * must display the following acknowledgement: | 14 | * products derived from this software without specific prior written |
| 18 | * This product includes software developed by the University of | 15 | * permission. |
| 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 | * | 16 | * |
| 24 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND |
| 25 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 26 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 27 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
| 28 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| 29 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
| 30 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| @@ -34,126 +27,188 @@ | |||
| 34 | * SUCH DAMAGE. | 27 | * SUCH DAMAGE. |
| 35 | */ | 28 | */ |
| 36 | 29 | ||
| 37 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 38 | /*static char sccsid[] = "from: @(#)realpath.c 8.1 (Berkeley) 2/16/94";*/ | ||
| 39 | static char *rcsid = "$Id: realpath.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $"; | ||
| 40 | #endif /* LIBC_SCCS and not lint */ | ||
| 41 | |||
| 42 | #include <sys/param.h> | 30 | #include <sys/param.h> |
| 43 | #include <sys/stat.h> | 31 | #include <sys/stat.h> |
| 44 | 32 | ||
| 45 | #include <errno.h> | 33 | #include <errno.h> |
| 46 | #include <fcntl.h> | ||
| 47 | #include <stdlib.h> | 34 | #include <stdlib.h> |
| 48 | #include <string.h> | 35 | #include <string.h> |
| 49 | #include <unistd.h> | 36 | #include <unistd.h> |
| 50 | 37 | ||
| 38 | /* A slightly modified copy of this file exists in libexec/ld.so */ | ||
| 39 | |||
| 51 | /* | 40 | /* |
| 52 | * char *realpath(const char *path, char resolved_path[MAXPATHLEN]); | 41 | * char *realpath(const char *path, char resolved[PATH_MAX]); |
| 53 | * | 42 | * |
| 54 | * Find the real name of path, by removing all ".", ".." and symlink | 43 | * Find the real name of path, by removing all ".", ".." and symlink |
| 55 | * components. Returns (resolved) on success, or (NULL) on failure, | 44 | * components. Returns (resolved) on success, or (NULL) on failure, |
| 56 | * in which case the path which caused trouble is left in (resolved). | 45 | * in which case the path which caused trouble is left in (resolved). |
| 57 | */ | 46 | */ |
| 58 | char * | 47 | char * |
| 59 | realpath(path, resolved) | 48 | realpath(const char *path, char *resolved) |
| 60 | const char *path; | ||
| 61 | char *resolved; | ||
| 62 | { | 49 | { |
| 63 | struct stat sb; | 50 | struct stat sb; |
| 64 | int fd, n, rootd, serrno; | 51 | char *p, *q, *s; |
| 65 | char *p, *q, wbuf[MAXPATHLEN]; | 52 | size_t left_len, resolved_len; |
| 53 | unsigned symlinks; | ||
| 54 | int serrno, slen, mem_allocated; | ||
| 55 | char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX]; | ||
| 66 | 56 | ||
| 67 | /* Save the starting point. */ | 57 | if (path[0] == '\0') { |
| 68 | if ((fd = open(".", O_RDONLY)) < 0) { | 58 | errno = ENOENT; |
| 69 | (void)strcpy(resolved, "."); | ||
| 70 | return (NULL); | 59 | return (NULL); |
| 71 | } | 60 | } |
| 72 | 61 | ||
| 73 | /* | 62 | serrno = errno; |
| 74 | * Find the dirname and basename from the path to be resolved. | 63 | |
| 75 | * Change directory to the dirname component. | 64 | if (resolved == NULL) { |
| 76 | * lstat the basename part. | 65 | resolved = malloc(PATH_MAX); |
| 77 | * if it is a symlink, read in the value and loop. | 66 | if (resolved == NULL) |
| 78 | * if it is a directory, then change to that directory. | 67 | return (NULL); |
| 79 | * get the current directory name and append the basename. | 68 | mem_allocated = 1; |
| 80 | */ | ||
| 81 | (void)strncpy(resolved, path, MAXPATHLEN - 1); | ||
| 82 | resolved[MAXPATHLEN - 1] = '\0'; | ||
| 83 | loop: | ||
| 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 | 69 | } else |
| 99 | p = resolved; | 70 | mem_allocated = 0; |
| 100 | 71 | ||
| 101 | /* Deal with the last component. */ | 72 | symlinks = 0; |
| 102 | if (lstat(p, &sb) == 0) { | 73 | if (path[0] == '/') { |
| 103 | if (S_ISLNK(sb.st_mode)) { | 74 | resolved[0] = '/'; |
| 104 | n = readlink(p, resolved, MAXPATHLEN); | 75 | resolved[1] = '\0'; |
| 105 | if (n < 0) | 76 | if (path[1] == '\0') |
| 106 | goto err1; | 77 | return (resolved); |
| 107 | resolved[n] = '\0'; | 78 | resolved_len = 1; |
| 108 | goto loop; | 79 | left_len = strlcpy(left, path + 1, sizeof(left)); |
| 109 | } | 80 | } else { |
| 110 | if (S_ISDIR(sb.st_mode)) { | 81 | if (getcwd(resolved, PATH_MAX) == NULL) { |
| 111 | if (chdir(p) < 0) | 82 | if (mem_allocated) |
| 112 | goto err1; | 83 | free(resolved); |
| 113 | p = ""; | 84 | else |
| 85 | strlcpy(resolved, ".", PATH_MAX); | ||
| 86 | return (NULL); | ||
| 114 | } | 87 | } |
| 88 | resolved_len = strlen(resolved); | ||
| 89 | left_len = strlcpy(left, path, sizeof(left)); | ||
| 90 | } | ||
| 91 | if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) { | ||
| 92 | errno = ENAMETOOLONG; | ||
| 93 | goto err; | ||
| 115 | } | 94 | } |
| 116 | 95 | ||
| 117 | /* | 96 | /* |
| 118 | * Save the last component name and get the full pathname of | 97 | * Iterate over path components in `left'. |
| 119 | * the current directory. | ||
| 120 | */ | ||
| 121 | (void)strcpy(wbuf, p); | ||
| 122 | if (getcwd(resolved, MAXPATHLEN) == 0) | ||
| 123 | goto err1; | ||
| 124 | |||
| 125 | /* | ||
| 126 | * Join the two strings together, ensuring that the right thing | ||
| 127 | * happens if the last component is empty, or the dirname is root. | ||
| 128 | */ | 98 | */ |
| 129 | if (resolved[0] == '/' && resolved[1] == '\0') | 99 | while (left_len != 0) { |
| 130 | rootd = 1; | 100 | /* |
| 131 | else | 101 | * Extract the next path component and adjust `left' |
| 132 | rootd = 0; | 102 | * and its length. |
| 103 | */ | ||
| 104 | p = strchr(left, '/'); | ||
| 105 | s = p ? p : left + left_len; | ||
| 106 | if (s - left >= sizeof(next_token)) { | ||
| 107 | errno = ENAMETOOLONG; | ||
| 108 | goto err; | ||
| 109 | } | ||
| 110 | memcpy(next_token, left, s - left); | ||
| 111 | next_token[s - left] = '\0'; | ||
| 112 | left_len -= s - left; | ||
| 113 | if (p != NULL) | ||
| 114 | memmove(left, s + 1, left_len + 1); | ||
| 115 | if (resolved[resolved_len - 1] != '/') { | ||
| 116 | if (resolved_len + 1 >= PATH_MAX) { | ||
| 117 | errno = ENAMETOOLONG; | ||
| 118 | goto err; | ||
| 119 | } | ||
| 120 | resolved[resolved_len++] = '/'; | ||
| 121 | resolved[resolved_len] = '\0'; | ||
| 122 | } | ||
| 123 | if (next_token[0] == '\0') | ||
| 124 | continue; | ||
| 125 | else if (strcmp(next_token, ".") == 0) | ||
| 126 | continue; | ||
| 127 | else if (strcmp(next_token, "..") == 0) { | ||
| 128 | /* | ||
| 129 | * Strip the last path component except when we have | ||
| 130 | * single "/" | ||
| 131 | */ | ||
| 132 | if (resolved_len > 1) { | ||
| 133 | resolved[resolved_len - 1] = '\0'; | ||
| 134 | q = strrchr(resolved, '/') + 1; | ||
| 135 | *q = '\0'; | ||
| 136 | resolved_len = q - resolved; | ||
| 137 | } | ||
| 138 | continue; | ||
| 139 | } | ||
| 133 | 140 | ||
| 134 | if (*wbuf) { | 141 | /* |
| 135 | if (strlen(resolved) + strlen(wbuf) + rootd + 1 > MAXPATHLEN) { | 142 | * Append the next path component and lstat() it. If |
| 143 | * lstat() fails we still can return successfully if | ||
| 144 | * there are no more path components left. | ||
| 145 | */ | ||
| 146 | resolved_len = strlcat(resolved, next_token, PATH_MAX); | ||
| 147 | if (resolved_len >= PATH_MAX) { | ||
| 136 | errno = ENAMETOOLONG; | 148 | errno = ENAMETOOLONG; |
| 137 | goto err1; | 149 | goto err; |
| 138 | } | 150 | } |
| 139 | if (rootd == 0) | 151 | if (lstat(resolved, &sb) != 0) { |
| 140 | (void)strcat(resolved, "/"); | 152 | if (errno == ENOENT && p == NULL) { |
| 141 | (void)strcat(resolved, wbuf); | 153 | errno = serrno; |
| 142 | } | 154 | return (resolved); |
| 155 | } | ||
| 156 | goto err; | ||
| 157 | } | ||
| 158 | if (S_ISLNK(sb.st_mode)) { | ||
| 159 | if (symlinks++ > MAXSYMLINKS) { | ||
| 160 | errno = ELOOP; | ||
| 161 | goto err; | ||
| 162 | } | ||
| 163 | slen = readlink(resolved, symlink, sizeof(symlink) - 1); | ||
| 164 | if (slen < 0) | ||
| 165 | goto err; | ||
| 166 | symlink[slen] = '\0'; | ||
| 167 | if (symlink[0] == '/') { | ||
| 168 | resolved[1] = 0; | ||
| 169 | resolved_len = 1; | ||
| 170 | } else if (resolved_len > 1) { | ||
| 171 | /* Strip the last path component. */ | ||
| 172 | resolved[resolved_len - 1] = '\0'; | ||
| 173 | q = strrchr(resolved, '/') + 1; | ||
| 174 | *q = '\0'; | ||
| 175 | resolved_len = q - resolved; | ||
| 176 | } | ||
| 143 | 177 | ||
| 144 | /* Go back to where we came from. */ | 178 | /* |
| 145 | if (fchdir(fd) < 0) { | 179 | * If there are any path components left, then |
| 146 | serrno = errno; | 180 | * append them to symlink. The result is placed |
| 147 | goto err2; | 181 | * in `left'. |
| 182 | */ | ||
| 183 | if (p != NULL) { | ||
| 184 | if (symlink[slen - 1] != '/') { | ||
| 185 | if (slen + 1 >= sizeof(symlink)) { | ||
| 186 | errno = ENAMETOOLONG; | ||
| 187 | goto err; | ||
| 188 | } | ||
| 189 | symlink[slen] = '/'; | ||
| 190 | symlink[slen + 1] = 0; | ||
| 191 | } | ||
| 192 | left_len = strlcat(symlink, left, sizeof(symlink)); | ||
| 193 | if (left_len >= sizeof(left)) { | ||
| 194 | errno = ENAMETOOLONG; | ||
| 195 | goto err; | ||
| 196 | } | ||
| 197 | } | ||
| 198 | left_len = strlcpy(left, symlink, sizeof(left)); | ||
| 199 | } | ||
| 148 | } | 200 | } |
| 149 | 201 | ||
| 150 | /* It's okay if the close fails, what's an fd more or less? */ | 202 | /* |
| 151 | (void)close(fd); | 203 | * Remove trailing slash except when the resolved pathname |
| 204 | * is a single "/". | ||
| 205 | */ | ||
| 206 | if (resolved_len > 1 && resolved[resolved_len - 1] == '/') | ||
| 207 | resolved[resolved_len - 1] = '\0'; | ||
| 152 | return (resolved); | 208 | return (resolved); |
| 153 | 209 | ||
| 154 | err1: serrno = errno; | 210 | err: |
| 155 | (void)fchdir(fd); | 211 | if (mem_allocated) |
| 156 | err2: (void)close(fd); | 212 | free(resolved); |
| 157 | errno = serrno; | ||
| 158 | return (NULL); | 213 | return (NULL); |
| 159 | } | 214 | } |
diff --git a/src/lib/libc/stdlib/remque.c b/src/lib/libc/stdlib/remque.c new file mode 100644 index 0000000000..ae249ae053 --- /dev/null +++ b/src/lib/libc/stdlib/remque.c | |||
| @@ -0,0 +1,44 @@ | |||
| 1 | /* $OpenBSD: remque.c,v 1.2 2005/08/08 08:05:37 espie Exp $ */ | ||
| 2 | |||
| 3 | /* | ||
| 4 | * Copyright (c) 1993 John Brezak | ||
| 5 | * All rights reserved. | ||
| 6 | * | ||
| 7 | * Redistribution and use in source and binary forms, with or without | ||
| 8 | * modification, are permitted provided that the following conditions | ||
| 9 | * are met: | ||
| 10 | * 1. Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 13 | * notice, this list of conditions and the following disclaimer in the | ||
| 14 | * documentation and/or other materials provided with the distribution. | ||
| 15 | * 3. The name of the author may be used to endorse or promote products | ||
| 16 | * derived from this software without specific prior written permission. | ||
| 17 | * | ||
| 18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR | ||
| 19 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
| 20 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
| 21 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, | ||
| 22 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
| 23 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||
| 24 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| 26 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 27 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 28 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 29 | */ | ||
| 30 | |||
| 31 | #include <search.h> | ||
| 32 | |||
| 33 | struct qelem { | ||
| 34 | struct qelem *q_forw; | ||
| 35 | struct qelem *q_back; | ||
| 36 | }; | ||
| 37 | |||
| 38 | void | ||
| 39 | remque(void *element) | ||
| 40 | { | ||
| 41 | struct qelem *e = (struct qelem *) element; | ||
| 42 | e->q_forw->q_back = e->q_back; | ||
| 43 | e->q_back->q_forw = e->q_forw; | ||
| 44 | } | ||
diff --git a/src/lib/libc/stdlib/seed48.c b/src/lib/libc/stdlib/seed48.c index e3d31901dd..583262f2d5 100644 --- a/src/lib/libc/stdlib/seed48.c +++ b/src/lib/libc/stdlib/seed48.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: seed48.c,v 1.3 2005/08/08 08:05:37 espie Exp $ */ | ||
| 1 | /* | 2 | /* |
| 2 | * Copyright (c) 1993 Martin Birgmeier | 3 | * Copyright (c) 1993 Martin Birgmeier |
| 3 | * All rights reserved. | 4 | * All rights reserved. |
diff --git a/src/lib/libc/stdlib/setenv.c b/src/lib/libc/stdlib/setenv.c index a36669888d..9060fdba88 100644 --- a/src/lib/libc/stdlib/setenv.c +++ b/src/lib/libc/stdlib/setenv.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: setenv.c,v 1.14 2012/09/23 16:08:04 jeremy Exp $ */ | ||
| 1 | /* | 2 | /* |
| 2 | * Copyright (c) 1987 Regents of the University of California. | 3 | * Copyright (c) 1987 Regents of the University of California. |
| 3 | * All rights reserved. | 4 | * All rights reserved. |
| @@ -10,11 +11,7 @@ | |||
| 10 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the |
| 12 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. Neither the name of the University nor the names of its contributors |
| 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 | 15 | * may be used to endorse or promote products derived from this software |
| 19 | * without specific prior written permission. | 16 | * without specific prior written permission. |
| 20 | * | 17 | * |
| @@ -31,71 +28,122 @@ | |||
| 31 | * SUCH DAMAGE. | 28 | * SUCH DAMAGE. |
| 32 | */ | 29 | */ |
| 33 | 30 | ||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | 31 | #include <errno.h> |
| 35 | /*static char *sccsid = "from: @(#)setenv.c 5.6 (Berkeley) 6/4/91";*/ | ||
| 36 | static char *rcsid = "$Id: setenv.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $"; | ||
| 37 | #endif /* LIBC_SCCS and not lint */ | ||
| 38 | |||
| 39 | #include <stdlib.h> | 32 | #include <stdlib.h> |
| 40 | #include <string.h> | 33 | #include <string.h> |
| 41 | 34 | ||
| 35 | char *__findenv(const char *name, int len, int *offset); | ||
| 36 | |||
| 37 | extern char **environ; | ||
| 38 | static char **lastenv; /* last value of environ */ | ||
| 39 | |||
| 40 | /* | ||
| 41 | * putenv -- | ||
| 42 | * Add a name=value string directly to the environmental, replacing | ||
| 43 | * any current value. | ||
| 44 | */ | ||
| 45 | int | ||
| 46 | putenv(char *str) | ||
| 47 | { | ||
| 48 | char **P, *cp; | ||
| 49 | size_t cnt; | ||
| 50 | int offset = 0; | ||
| 51 | |||
| 52 | for (cp = str; *cp && *cp != '='; ++cp) | ||
| 53 | ; | ||
| 54 | if (*cp != '=') { | ||
| 55 | errno = EINVAL; | ||
| 56 | return (-1); /* missing `=' in string */ | ||
| 57 | } | ||
| 58 | |||
| 59 | if (__findenv(str, (int)(cp - str), &offset) != NULL) { | ||
| 60 | environ[offset++] = str; | ||
| 61 | /* could be set multiple times */ | ||
| 62 | while (__findenv(str, (int)(cp - str), &offset)) { | ||
| 63 | for (P = &environ[offset];; ++P) | ||
| 64 | if (!(*P = *(P + 1))) | ||
| 65 | break; | ||
| 66 | } | ||
| 67 | return (0); | ||
| 68 | } | ||
| 69 | |||
| 70 | /* create new slot for string */ | ||
| 71 | for (P = environ; *P != NULL; P++) | ||
| 72 | ; | ||
| 73 | cnt = P - environ; | ||
| 74 | P = (char **)realloc(lastenv, sizeof(char *) * (cnt + 2)); | ||
| 75 | if (!P) | ||
| 76 | return (-1); | ||
| 77 | if (lastenv != environ) | ||
| 78 | memcpy(P, environ, cnt * sizeof(char *)); | ||
| 79 | lastenv = environ = P; | ||
| 80 | environ[cnt] = str; | ||
| 81 | environ[cnt + 1] = NULL; | ||
| 82 | return (0); | ||
| 83 | } | ||
| 84 | |||
| 42 | /* | 85 | /* |
| 43 | * setenv -- | 86 | * setenv -- |
| 44 | * Set the value of the environmental variable "name" to be | 87 | * Set the value of the environmental variable "name" to be |
| 45 | * "value". If rewrite is set, replace any current value. | 88 | * "value". If rewrite is set, replace any current value. |
| 46 | */ | 89 | */ |
| 47 | int | 90 | int |
| 48 | setenv(name, value, rewrite) | 91 | setenv(const char *name, const char *value, int rewrite) |
| 49 | register const char *name; | ||
| 50 | register const char *value; | ||
| 51 | int rewrite; | ||
| 52 | { | 92 | { |
| 53 | extern char **environ; | 93 | char *C, **P; |
| 54 | static int alloced; /* if allocated space before */ | 94 | const char *np; |
| 55 | register char *C; | 95 | int l_value, offset = 0; |
| 56 | int l_value, offset; | 96 | |
| 57 | char *__findenv(); | 97 | if (!name || !*name) { |
| 98 | errno = EINVAL; | ||
| 99 | return (-1); | ||
| 100 | } | ||
| 101 | for (np = name; *np && *np != '='; ++np) | ||
| 102 | ; | ||
| 103 | if (*np) { | ||
| 104 | errno = EINVAL; | ||
| 105 | return (-1); /* has `=' in name */ | ||
| 106 | } | ||
| 58 | 107 | ||
| 59 | if (*value == '=') /* no `=' in value */ | ||
| 60 | ++value; | ||
| 61 | l_value = strlen(value); | 108 | l_value = strlen(value); |
| 62 | if ((C = __findenv(name, &offset))) { /* find if already exists */ | 109 | if ((C = __findenv(name, (int)(np - name), &offset)) != NULL) { |
| 110 | int tmpoff = offset + 1; | ||
| 63 | if (!rewrite) | 111 | if (!rewrite) |
| 64 | return (0); | 112 | return (0); |
| 113 | #if 0 /* XXX - existing entry may not be writable */ | ||
| 65 | if (strlen(C) >= l_value) { /* old larger; copy over */ | 114 | if (strlen(C) >= l_value) { /* old larger; copy over */ |
| 66 | while (*C++ = *value++); | 115 | while ((*C++ = *value++)) |
| 116 | ; | ||
| 67 | return (0); | 117 | return (0); |
| 68 | } | 118 | } |
| 119 | #endif | ||
| 120 | /* could be set multiple times */ | ||
| 121 | while (__findenv(name, (int)(np - name), &tmpoff)) { | ||
| 122 | for (P = &environ[tmpoff];; ++P) | ||
| 123 | if (!(*P = *(P + 1))) | ||
| 124 | break; | ||
| 125 | } | ||
| 69 | } else { /* create new slot */ | 126 | } else { /* create new slot */ |
| 70 | register int cnt; | 127 | size_t cnt; |
| 71 | register char **P; | ||
| 72 | 128 | ||
| 73 | for (P = environ, cnt = 0; *P; ++P, ++cnt); | 129 | for (P = environ; *P != NULL; P++) |
| 74 | if (alloced) { /* just increase size */ | 130 | ; |
| 75 | environ = (char **)realloc((char *)environ, | 131 | cnt = P - environ; |
| 76 | (size_t)(sizeof(char *) * (cnt + 2))); | 132 | P = (char **)realloc(lastenv, sizeof(char *) * (cnt + 2)); |
| 77 | if (!environ) | 133 | if (!P) |
| 78 | return (-1); | 134 | return (-1); |
| 79 | } | 135 | if (lastenv != environ) |
| 80 | else { /* get new space */ | 136 | memcpy(P, environ, cnt * sizeof(char *)); |
| 81 | alloced = 1; /* copy old entries into it */ | 137 | lastenv = environ = P; |
| 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; | 138 | offset = cnt; |
| 139 | environ[cnt + 1] = NULL; | ||
| 91 | } | 140 | } |
| 92 | for (C = (char *)name; *C && *C != '='; ++C); /* no `=' in name */ | ||
| 93 | if (!(environ[offset] = /* name + `=' + value */ | 141 | if (!(environ[offset] = /* name + `=' + value */ |
| 94 | malloc((size_t)((int)(C - name) + l_value + 2)))) | 142 | malloc((size_t)((int)(np - name) + l_value + 2)))) |
| 95 | return (-1); | 143 | return (-1); |
| 96 | for (C = environ[offset]; (*C = *name++) && *C != '='; ++C) | 144 | for (C = environ[offset]; (*C = *name++) && *C != '='; ++C) |
| 97 | ; | 145 | ; |
| 98 | for (*C++ = '='; *C++ = *value++; ) | 146 | for (*C++ = '='; (*C++ = *value++); ) |
| 99 | ; | 147 | ; |
| 100 | return (0); | 148 | return (0); |
| 101 | } | 149 | } |
| @@ -104,17 +152,29 @@ setenv(name, value, rewrite) | |||
| 104 | * unsetenv(name) -- | 152 | * unsetenv(name) -- |
| 105 | * Delete environmental variable "name". | 153 | * Delete environmental variable "name". |
| 106 | */ | 154 | */ |
| 107 | void | 155 | int |
| 108 | unsetenv(name) | 156 | unsetenv(const char *name) |
| 109 | const char *name; | ||
| 110 | { | 157 | { |
| 111 | extern char **environ; | 158 | char **P; |
| 112 | register char **P; | 159 | const char *np; |
| 113 | int offset; | 160 | int offset = 0; |
| 114 | char *__findenv(); | ||
| 115 | 161 | ||
| 116 | while (__findenv(name, &offset)) /* if set multiple times */ | 162 | if (!name || !*name) { |
| 163 | errno = EINVAL; | ||
| 164 | return (-1); | ||
| 165 | } | ||
| 166 | for (np = name; *np && *np != '='; ++np) | ||
| 167 | ; | ||
| 168 | if (*np) { | ||
| 169 | errno = EINVAL; | ||
| 170 | return (-1); /* has `=' in name */ | ||
| 171 | } | ||
| 172 | |||
| 173 | /* could be set multiple times */ | ||
| 174 | while (__findenv(name, (int)(np - name), &offset)) { | ||
| 117 | for (P = &environ[offset];; ++P) | 175 | for (P = &environ[offset];; ++P) |
| 118 | if (!(*P = *(P + 1))) | 176 | if (!(*P = *(P + 1))) |
| 119 | break; | 177 | break; |
| 178 | } | ||
| 179 | return (0); | ||
| 120 | } | 180 | } |
diff --git a/src/lib/libc/stdlib/srand48.c b/src/lib/libc/stdlib/srand48.c index daf733f93e..f76b6cca86 100644 --- a/src/lib/libc/stdlib/srand48.c +++ b/src/lib/libc/stdlib/srand48.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: srand48.c,v 1.3 2005/08/08 08:05:37 espie Exp $ */ | ||
| 1 | /* | 2 | /* |
| 2 | * Copyright (c) 1993 Martin Birgmeier | 3 | * Copyright (c) 1993 Martin Birgmeier |
| 3 | * All rights reserved. | 4 | * All rights reserved. |
diff --git a/src/lib/libc/stdlib/strtod.3 b/src/lib/libc/stdlib/strtod.3 index 0b7f973857..6f079b73a9 100644 --- a/src/lib/libc/stdlib/strtod.3 +++ b/src/lib/libc/stdlib/strtod.3 | |||
| @@ -13,11 +13,7 @@ | |||
| 13 | .\" 2. Redistributions in binary form must reproduce the above copyright | 13 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 14 | .\" notice, this list of conditions and the following disclaimer in the | 14 | .\" notice, this list of conditions and the following disclaimer in the |
| 15 | .\" documentation and/or other materials provided with the distribution. | 15 | .\" documentation and/or other materials provided with the distribution. |
| 16 | .\" 3. All advertising materials mentioning features or use of this software | 16 | .\" 3. Neither the name of the University nor the names of its contributors |
| 17 | .\" must display the following acknowledgement: | ||
| 18 | .\" This product includes software developed by the University of | ||
| 19 | .\" California, Berkeley and its contributors. | ||
| 20 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 21 | .\" may be used to endorse or promote products derived from this software | 17 | .\" may be used to endorse or promote products derived from this software |
| 22 | .\" without specific prior written permission. | 18 | .\" without specific prior written permission. |
| 23 | .\" | 19 | .\" |
| @@ -33,44 +29,96 @@ | |||
| 33 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 29 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 34 | .\" SUCH DAMAGE. | 30 | .\" SUCH DAMAGE. |
| 35 | .\" | 31 | .\" |
| 36 | .\" from: @(#)strtod.3 5.3 (Berkeley) 6/29/91 | 32 | .\" $OpenBSD: strtod.3,v 1.19 2014/01/19 10:39:00 schwarze Exp $ |
| 37 | .\" $Id: strtod.3,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $ | ||
| 38 | .\" | 33 | .\" |
| 39 | .Dd June 29, 1991 | 34 | .Dd $Mdocdate: January 19 2014 $ |
| 40 | .Dt STRTOD 3 | 35 | .Dt STRTOD 3 |
| 41 | .Os | 36 | .Os |
| 42 | .Sh NAME | 37 | .Sh NAME |
| 43 | .Nm strtod | 38 | .Nm strtod , |
| 44 | .Nd convert | 39 | .Nm strtof , |
| 45 | .Tn ASCII | 40 | .Nm strtold |
| 46 | string to double | 41 | .Nd convert ASCII string to double, float or long double |
| 47 | .Sh SYNOPSIS | 42 | .Sh SYNOPSIS |
| 48 | .Fd #include <stdlib.h> | 43 | .In stdlib.h |
| 49 | .Ft double | 44 | .Ft double |
| 50 | .Fn strtod "const char *nptr" "char **endptr" | 45 | .Fn strtod "const char *nptr" "char **endptr" |
| 46 | .Pp | ||
| 47 | .Ft float | ||
| 48 | .Fn strtof "const char *nptr" "char **endptr" | ||
| 49 | .Pp | ||
| 50 | .Ft long double | ||
| 51 | .Fn strtold "const char *nptr" "char **endptr" | ||
| 51 | .Sh DESCRIPTION | 52 | .Sh DESCRIPTION |
| 52 | The | 53 | The |
| 53 | .Fn strtod | 54 | .Fn strtod |
| 54 | function converts the initial portion of the string | 55 | function converts the initial portion of the string pointed to by |
| 55 | pointed to by | 56 | .Fa nptr |
| 57 | to | ||
| 58 | .Li double | ||
| 59 | representation. | ||
| 60 | The | ||
| 61 | .Fn strtof | ||
| 62 | function converts the initial portion of the string pointed to by | ||
| 63 | .Fa nptr | ||
| 64 | to | ||
| 65 | .Li float | ||
| 66 | representation. | ||
| 67 | The | ||
| 68 | .Fn strtold | ||
| 69 | function converts the initial portion of the string pointed to by | ||
| 56 | .Fa nptr | 70 | .Fa nptr |
| 57 | to | 71 | to |
| 58 | .Em double | 72 | .Li long double |
| 59 | representation. | 73 | representation. |
| 60 | .Pp | 74 | .Pp |
| 61 | The expected form of the string is an optional plus (``+'') or minus | 75 | The expected form of the string is an optional plus |
| 62 | sign (``-'') followed by a sequence of digits optionally containing | 76 | .Pq Ql + |
| 77 | or minus sign | ||
| 78 | .Pq Ql - | ||
| 79 | followed by a sequence of digits optionally containing | ||
| 63 | a decimal-point character, optionally followed by an exponent. | 80 | a decimal-point character, optionally followed by an exponent. |
| 64 | An exponent consists of an ``E'' or ``e'', followed by an optional plus | 81 | An exponent consists of an |
| 65 | or minus sign, followed by a sequence of digits. | 82 | .Sq E |
| 83 | or | ||
| 84 | .Sq e , | ||
| 85 | followed by an optional plus or minus sign, followed by a sequence of digits. | ||
| 86 | .Pp | ||
| 87 | Alternatively, if the portion of the string following the optional | ||
| 88 | plus or minus sign begins with | ||
| 89 | .Dq INF | ||
| 90 | or | ||
| 91 | .Dq NAN , | ||
| 92 | ignoring case, it is interpreted as an infinity or a quiet \*(Na, | ||
| 93 | respectively. | ||
| 94 | The syntax | ||
| 95 | .Dq NAN Ns Pq Ar s , | ||
| 96 | where | ||
| 97 | .Ar s | ||
| 98 | is an alphanumeric string, produces the same value as the call | ||
| 99 | .Fo nan | ||
| 100 | .Qq Ar s Ns | ||
| 101 | .Fc | ||
| 102 | (respectively, | ||
| 103 | .Fo nanf | ||
| 104 | .Qq Ar s Ns | ||
| 105 | .Fc | ||
| 106 | and | ||
| 107 | .Fo nanl | ||
| 108 | .Qq Ar s Ns | ||
| 109 | .Fc . ) | ||
| 66 | .Pp | 110 | .Pp |
| 67 | Leading white-space characters in the string (as defined by the | 111 | In any of the above cases, leading whitespace characters in the |
| 112 | string (as defined by the | ||
| 68 | .Xr isspace 3 | 113 | .Xr isspace 3 |
| 69 | function) are skipped. | 114 | function) are skipped. |
| 70 | .Sh RETURN VALUES | 115 | .Sh RETURN VALUES |
| 71 | The | 116 | The |
| 72 | .Fn strtod | 117 | .Fn strtod , |
| 73 | function returns the converted value, if any. | 118 | .Fn strtof |
| 119 | and | ||
| 120 | .Fn strtold | ||
| 121 | functions return the converted value, if any. | ||
| 74 | .Pp | 122 | .Pp |
| 75 | If | 123 | If |
| 76 | .Fa endptr | 124 | .Fa endptr |
| @@ -88,18 +136,18 @@ is stored in the location referenced by | |||
| 88 | If the correct value would cause overflow, plus or minus | 136 | If the correct value would cause overflow, plus or minus |
| 89 | .Dv HUGE_VAL | 137 | .Dv HUGE_VAL |
| 90 | is returned (according to the sign of the value), and | 138 | is returned (according to the sign of the value), and |
| 91 | .Dv ERANGE | 139 | .Er ERANGE |
| 92 | is stored in | 140 | is stored in |
| 93 | .Va errno . | 141 | .Va errno . |
| 94 | If the correct value would cause underflow, zero is | 142 | If the correct value would cause underflow, zero is returned and |
| 95 | returned and | 143 | .Er ERANGE |
| 96 | .Dv ERANGE | 144 | is stored in |
| 97 | is stored in | ||
| 98 | .Va errno . | 145 | .Va errno . |
| 99 | .Sh ERRORS | 146 | .Sh ERRORS |
| 100 | .Bl -tag -width Er | 147 | .Bl -tag -width Er |
| 101 | .It Bq Er ERANGE | 148 | .It Bq Er ERANGE |
| 102 | Overflow or underflow occurred. | 149 | Overflow or underflow occurred. |
| 150 | .El | ||
| 103 | .Sh SEE ALSO | 151 | .Sh SEE ALSO |
| 104 | .Xr atof 3 , | 152 | .Xr atof 3 , |
| 105 | .Xr atoi 3 , | 153 | .Xr atoi 3 , |
| @@ -109,6 +157,11 @@ Overflow or underflow occurred. | |||
| 109 | .Sh STANDARDS | 157 | .Sh STANDARDS |
| 110 | The | 158 | The |
| 111 | .Fn strtod | 159 | .Fn strtod |
| 112 | function | 160 | function conforms to |
| 113 | conforms to | 161 | .St -ansiC-89 . |
| 114 | .St -ansiC . | 162 | The |
| 163 | .Fn strtof | ||
| 164 | and | ||
| 165 | .Fn strtold | ||
| 166 | functions conform to | ||
| 167 | .St -ansiC-99 . | ||
diff --git a/src/lib/libc/stdlib/strtod.c b/src/lib/libc/stdlib/strtod.c deleted file mode 100644 index b13fa128f5..0000000000 --- a/src/lib/libc/stdlib/strtod.c +++ /dev/null | |||
| @@ -1,2499 +0,0 @@ | |||
| 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) | ||
| 93 | static char *rcsid = "$Id: strtod.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt 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 | #include <machine/endian.h> | ||
| 99 | #if BYTE_ORDER == BIG_ENDIAN | ||
| 100 | #define IEEE_BIG_ENDIAN | ||
| 101 | #else | ||
| 102 | #define IEEE_LITTLE_ENDIAN | ||
| 103 | #endif | ||
| 104 | #endif | ||
| 105 | |||
| 106 | #ifdef vax | ||
| 107 | #define VAX | ||
| 108 | #endif | ||
| 109 | |||
| 110 | #define Long int32_t | ||
| 111 | #define ULong u_int32_t | ||
| 112 | |||
| 113 | #ifdef DEBUG | ||
| 114 | #include "stdio.h" | ||
| 115 | #define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);} | ||
| 116 | #endif | ||
| 117 | |||
| 118 | #ifdef __cplusplus | ||
| 119 | #include "malloc.h" | ||
| 120 | #include "memory.h" | ||
| 121 | #else | ||
| 122 | #ifndef KR_headers | ||
| 123 | #include "stdlib.h" | ||
| 124 | #include "string.h" | ||
| 125 | #include "locale.h" | ||
| 126 | #else | ||
| 127 | #include "malloc.h" | ||
| 128 | #include "memory.h" | ||
| 129 | #endif | ||
| 130 | #endif | ||
| 131 | |||
| 132 | #ifdef MALLOC | ||
| 133 | #ifdef KR_headers | ||
| 134 | extern char *MALLOC(); | ||
| 135 | #else | ||
| 136 | extern void *MALLOC(size_t); | ||
| 137 | #endif | ||
| 138 | #else | ||
| 139 | #define MALLOC malloc | ||
| 140 | #endif | ||
| 141 | |||
| 142 | #include "ctype.h" | ||
| 143 | #include "errno.h" | ||
| 144 | |||
| 145 | #ifdef Bad_float_h | ||
| 146 | #undef __STDC__ | ||
| 147 | #ifdef IEEE_BIG_ENDIAN | ||
| 148 | #define IEEE_ARITHMETIC | ||
| 149 | #endif | ||
| 150 | #ifdef IEEE_LITTLE_ENDIAN | ||
| 151 | #define IEEE_ARITHMETIC | ||
| 152 | #endif | ||
| 153 | |||
| 154 | #ifdef IEEE_ARITHMETIC | ||
| 155 | #define DBL_DIG 15 | ||
| 156 | #define DBL_MAX_10_EXP 308 | ||
| 157 | #define DBL_MAX_EXP 1024 | ||
| 158 | #define FLT_RADIX 2 | ||
| 159 | #define FLT_ROUNDS 1 | ||
| 160 | #define DBL_MAX 1.7976931348623157e+308 | ||
| 161 | #endif | ||
| 162 | |||
| 163 | #ifdef IBM | ||
| 164 | #define DBL_DIG 16 | ||
| 165 | #define DBL_MAX_10_EXP 75 | ||
| 166 | #define DBL_MAX_EXP 63 | ||
| 167 | #define FLT_RADIX 16 | ||
| 168 | #define FLT_ROUNDS 0 | ||
| 169 | #define DBL_MAX 7.2370055773322621e+75 | ||
| 170 | #endif | ||
| 171 | |||
| 172 | #ifdef VAX | ||
| 173 | #define DBL_DIG 16 | ||
| 174 | #define DBL_MAX_10_EXP 38 | ||
| 175 | #define DBL_MAX_EXP 127 | ||
| 176 | #define FLT_RADIX 2 | ||
| 177 | #define FLT_ROUNDS 1 | ||
| 178 | #define DBL_MAX 1.7014118346046923e+38 | ||
| 179 | #endif | ||
| 180 | |||
| 181 | #ifndef LONG_MAX | ||
| 182 | #define LONG_MAX 2147483647 | ||
| 183 | #endif | ||
| 184 | #else | ||
| 185 | #include "float.h" | ||
| 186 | #endif | ||
| 187 | #ifndef __MATH_H__ | ||
| 188 | #include "math.h" | ||
| 189 | #endif | ||
| 190 | |||
| 191 | #ifdef __cplusplus | ||
| 192 | extern "C" { | ||
| 193 | #endif | ||
| 194 | |||
| 195 | #ifndef CONST | ||
| 196 | #ifdef KR_headers | ||
| 197 | #define CONST /* blank */ | ||
| 198 | #else | ||
| 199 | #define CONST const | ||
| 200 | #endif | ||
| 201 | #endif | ||
| 202 | |||
| 203 | #ifdef Unsigned_Shifts | ||
| 204 | #define Sign_Extend(a,b) if (b < 0) a |= 0xffff0000; | ||
| 205 | #else | ||
| 206 | #define Sign_Extend(a,b) /*no-op*/ | ||
| 207 | #endif | ||
| 208 | |||
| 209 | #if defined(IEEE_LITTLE_ENDIAN) + defined(IEEE_BIG_ENDIAN) + defined(VAX) + \ | ||
| 210 | defined(IBM) != 1 | ||
| 211 | Exactly one of IEEE_LITTLE_ENDIAN IEEE_BIG_ENDIAN, VAX, or | ||
| 212 | IBM should be defined. | ||
| 213 | #endif | ||
| 214 | |||
| 215 | #ifdef IEEE_LITTLE_ENDIAN | ||
| 216 | #define word0(x) ((ULong *)&x)[1] | ||
| 217 | #define word1(x) ((ULong *)&x)[0] | ||
| 218 | #else | ||
| 219 | #define word0(x) ((ULong *)&x)[0] | ||
| 220 | #define word1(x) ((ULong *)&x)[1] | ||
| 221 | #endif | ||
| 222 | |||
| 223 | /* The following definition of Storeinc is appropriate for MIPS processors. | ||
| 224 | * An alternative that might be better on some machines is | ||
| 225 | * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff) | ||
| 226 | */ | ||
| 227 | #if defined(IEEE_LITTLE_ENDIAN) + defined(VAX) | ||
| 228 | #define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \ | ||
| 229 | ((unsigned short *)a)[0] = (unsigned short)c, a++) | ||
| 230 | #else | ||
| 231 | #define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \ | ||
| 232 | ((unsigned short *)a)[1] = (unsigned short)c, a++) | ||
| 233 | #endif | ||
| 234 | |||
| 235 | /* #define P DBL_MANT_DIG */ | ||
| 236 | /* Ten_pmax = floor(P*log(2)/log(5)) */ | ||
| 237 | /* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */ | ||
| 238 | /* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */ | ||
| 239 | /* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */ | ||
| 240 | |||
| 241 | #if defined(IEEE_LITTLE_ENDIAN) + defined(IEEE_BIG_ENDIAN) | ||
| 242 | #define Exp_shift 20 | ||
| 243 | #define Exp_shift1 20 | ||
| 244 | #define Exp_msk1 0x100000 | ||
| 245 | #define Exp_msk11 0x100000 | ||
| 246 | #define Exp_mask 0x7ff00000 | ||
| 247 | #define P 53 | ||
| 248 | #define Bias 1023 | ||
| 249 | #define IEEE_Arith | ||
| 250 | #define Emin (-1022) | ||
| 251 | #define Exp_1 0x3ff00000 | ||
| 252 | #define Exp_11 0x3ff00000 | ||
| 253 | #define Ebits 11 | ||
| 254 | #define Frac_mask 0xfffff | ||
| 255 | #define Frac_mask1 0xfffff | ||
| 256 | #define Ten_pmax 22 | ||
| 257 | #define Bletch 0x10 | ||
| 258 | #define Bndry_mask 0xfffff | ||
| 259 | #define Bndry_mask1 0xfffff | ||
| 260 | #define LSB 1 | ||
| 261 | #define Sign_bit 0x80000000 | ||
| 262 | #define Log2P 1 | ||
| 263 | #define Tiny0 0 | ||
| 264 | #define Tiny1 1 | ||
| 265 | #define Quick_max 14 | ||
| 266 | #define Int_max 14 | ||
| 267 | #define Infinite(x) (word0(x) == 0x7ff00000) /* sufficient test for here */ | ||
| 268 | #else | ||
| 269 | #undef Sudden_Underflow | ||
| 270 | #define Sudden_Underflow | ||
| 271 | #ifdef IBM | ||
| 272 | #define Exp_shift 24 | ||
| 273 | #define Exp_shift1 24 | ||
| 274 | #define Exp_msk1 0x1000000 | ||
| 275 | #define Exp_msk11 0x1000000 | ||
| 276 | #define Exp_mask 0x7f000000 | ||
| 277 | #define P 14 | ||
| 278 | #define Bias 65 | ||
| 279 | #define Exp_1 0x41000000 | ||
| 280 | #define Exp_11 0x41000000 | ||
| 281 | #define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */ | ||
| 282 | #define Frac_mask 0xffffff | ||
| 283 | #define Frac_mask1 0xffffff | ||
| 284 | #define Bletch 4 | ||
| 285 | #define Ten_pmax 22 | ||
| 286 | #define Bndry_mask 0xefffff | ||
| 287 | #define Bndry_mask1 0xffffff | ||
| 288 | #define LSB 1 | ||
| 289 | #define Sign_bit 0x80000000 | ||
| 290 | #define Log2P 4 | ||
| 291 | #define Tiny0 0x100000 | ||
| 292 | #define Tiny1 0 | ||
| 293 | #define Quick_max 14 | ||
| 294 | #define Int_max 15 | ||
| 295 | #else /* VAX */ | ||
| 296 | #define Exp_shift 23 | ||
| 297 | #define Exp_shift1 7 | ||
| 298 | #define Exp_msk1 0x80 | ||
| 299 | #define Exp_msk11 0x800000 | ||
| 300 | #define Exp_mask 0x7f80 | ||
| 301 | #define P 56 | ||
| 302 | #define Bias 129 | ||
| 303 | #define Exp_1 0x40800000 | ||
| 304 | #define Exp_11 0x4080 | ||
| 305 | #define Ebits 8 | ||
| 306 | #define Frac_mask 0x7fffff | ||
| 307 | #define Frac_mask1 0xffff007f | ||
| 308 | #define Ten_pmax 24 | ||
| 309 | #define Bletch 2 | ||
| 310 | #define Bndry_mask 0xffff007f | ||
| 311 | #define Bndry_mask1 0xffff007f | ||
| 312 | #define LSB 0x10000 | ||
| 313 | #define Sign_bit 0x8000 | ||
| 314 | #define Log2P 1 | ||
| 315 | #define Tiny0 0x80 | ||
| 316 | #define Tiny1 0 | ||
| 317 | #define Quick_max 15 | ||
| 318 | #define Int_max 15 | ||
| 319 | #endif | ||
| 320 | #endif | ||
| 321 | |||
| 322 | #ifndef IEEE_Arith | ||
| 323 | #define ROUND_BIASED | ||
| 324 | #endif | ||
| 325 | |||
| 326 | #ifdef RND_PRODQUOT | ||
| 327 | #define rounded_product(a,b) a = rnd_prod(a, b) | ||
| 328 | #define rounded_quotient(a,b) a = rnd_quot(a, b) | ||
| 329 | #ifdef KR_headers | ||
| 330 | extern double rnd_prod(), rnd_quot(); | ||
| 331 | #else | ||
| 332 | extern double rnd_prod(double, double), rnd_quot(double, double); | ||
| 333 | #endif | ||
| 334 | #else | ||
| 335 | #define rounded_product(a,b) a *= b | ||
| 336 | #define rounded_quotient(a,b) a /= b | ||
| 337 | #endif | ||
| 338 | |||
| 339 | #define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1)) | ||
| 340 | #define Big1 0xffffffff | ||
| 341 | |||
| 342 | #ifndef Just_16 | ||
| 343 | /* When Pack_32 is not defined, we store 16 bits per 32-bit Long. | ||
| 344 | * This makes some inner loops simpler and sometimes saves work | ||
| 345 | * during multiplications, but it often seems to make things slightly | ||
| 346 | * slower. Hence the default is now to store 32 bits per Long. | ||
| 347 | */ | ||
| 348 | #ifndef Pack_32 | ||
| 349 | #define Pack_32 | ||
| 350 | #endif | ||
| 351 | #endif | ||
| 352 | |||
| 353 | #define Kmax 15 | ||
| 354 | |||
| 355 | #ifdef __cplusplus | ||
| 356 | extern "C" double strtod(const char *s00, char **se); | ||
| 357 | extern "C" char *__dtoa(double d, int mode, int ndigits, | ||
| 358 | int *decpt, int *sign, char **rve); | ||
| 359 | #endif | ||
| 360 | |||
| 361 | struct | ||
| 362 | Bigint { | ||
| 363 | struct Bigint *next; | ||
| 364 | int k, maxwds, sign, wds; | ||
| 365 | ULong x[1]; | ||
| 366 | }; | ||
| 367 | |||
| 368 | typedef struct Bigint Bigint; | ||
| 369 | |||
| 370 | static Bigint *freelist[Kmax+1]; | ||
| 371 | |||
| 372 | static Bigint * | ||
| 373 | Balloc | ||
| 374 | #ifdef KR_headers | ||
| 375 | (k) int k; | ||
| 376 | #else | ||
| 377 | (int k) | ||
| 378 | #endif | ||
| 379 | { | ||
| 380 | int x; | ||
| 381 | Bigint *rv; | ||
| 382 | |||
| 383 | if (rv = freelist[k]) { | ||
| 384 | freelist[k] = rv->next; | ||
| 385 | } | ||
| 386 | else { | ||
| 387 | x = 1 << k; | ||
| 388 | rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(Long)); | ||
| 389 | rv->k = k; | ||
| 390 | rv->maxwds = x; | ||
| 391 | } | ||
| 392 | rv->sign = rv->wds = 0; | ||
| 393 | return rv; | ||
| 394 | } | ||
| 395 | |||
| 396 | static void | ||
| 397 | Bfree | ||
| 398 | #ifdef KR_headers | ||
| 399 | (v) Bigint *v; | ||
| 400 | #else | ||
| 401 | (Bigint *v) | ||
| 402 | #endif | ||
| 403 | { | ||
| 404 | if (v) { | ||
| 405 | v->next = freelist[v->k]; | ||
| 406 | freelist[v->k] = v; | ||
| 407 | } | ||
| 408 | } | ||
| 409 | |||
| 410 | #define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \ | ||
| 411 | y->wds*sizeof(Long) + 2*sizeof(int)) | ||
| 412 | |||
| 413 | static Bigint * | ||
| 414 | multadd | ||
| 415 | #ifdef KR_headers | ||
| 416 | (b, m, a) Bigint *b; int m, a; | ||
| 417 | #else | ||
| 418 | (Bigint *b, int m, int a) /* multiply by m and add a */ | ||
| 419 | #endif | ||
| 420 | { | ||
| 421 | int i, wds; | ||
| 422 | ULong *x, y; | ||
| 423 | #ifdef Pack_32 | ||
| 424 | ULong xi, z; | ||
| 425 | #endif | ||
| 426 | Bigint *b1; | ||
| 427 | |||
| 428 | wds = b->wds; | ||
| 429 | x = b->x; | ||
| 430 | i = 0; | ||
| 431 | do { | ||
| 432 | #ifdef Pack_32 | ||
| 433 | xi = *x; | ||
| 434 | y = (xi & 0xffff) * m + a; | ||
| 435 | z = (xi >> 16) * m + (y >> 16); | ||
| 436 | a = (int)(z >> 16); | ||
| 437 | *x++ = (z << 16) + (y & 0xffff); | ||
| 438 | #else | ||
| 439 | y = *x * m + a; | ||
| 440 | a = (int)(y >> 16); | ||
| 441 | *x++ = y & 0xffff; | ||
| 442 | #endif | ||
| 443 | } | ||
| 444 | while(++i < wds); | ||
| 445 | if (a) { | ||
| 446 | if (wds >= b->maxwds) { | ||
| 447 | b1 = Balloc(b->k+1); | ||
| 448 | Bcopy(b1, b); | ||
| 449 | Bfree(b); | ||
| 450 | b = b1; | ||
| 451 | } | ||
| 452 | b->x[wds++] = a; | ||
| 453 | b->wds = wds; | ||
| 454 | } | ||
| 455 | return b; | ||
| 456 | } | ||
| 457 | |||
| 458 | static Bigint * | ||
| 459 | s2b | ||
| 460 | #ifdef KR_headers | ||
| 461 | (s, nd0, nd, y9) CONST char *s; int nd0, nd; ULong y9; | ||
| 462 | #else | ||
| 463 | (CONST char *s, int nd0, int nd, ULong y9) | ||
| 464 | #endif | ||
| 465 | { | ||
| 466 | Bigint *b; | ||
| 467 | int i, k; | ||
| 468 | Long x, y; | ||
| 469 | |||
| 470 | x = (nd + 8) / 9; | ||
| 471 | for(k = 0, y = 1; x > y; y <<= 1, k++) ; | ||
| 472 | #ifdef Pack_32 | ||
| 473 | b = Balloc(k); | ||
| 474 | b->x[0] = y9; | ||
| 475 | b->wds = 1; | ||
| 476 | #else | ||
| 477 | b = Balloc(k+1); | ||
| 478 | b->x[0] = y9 & 0xffff; | ||
| 479 | b->wds = (b->x[1] = y9 >> 16) ? 2 : 1; | ||
| 480 | #endif | ||
| 481 | |||
| 482 | i = 9; | ||
| 483 | if (9 < nd0) { | ||
| 484 | s += 9; | ||
| 485 | do b = multadd(b, 10, *s++ - '0'); | ||
| 486 | while(++i < nd0); | ||
| 487 | s++; | ||
| 488 | } | ||
| 489 | else | ||
| 490 | s += 10; | ||
| 491 | for(; i < nd; i++) | ||
| 492 | b = multadd(b, 10, *s++ - '0'); | ||
| 493 | return b; | ||
| 494 | } | ||
| 495 | |||
| 496 | static int | ||
| 497 | hi0bits | ||
| 498 | #ifdef KR_headers | ||
| 499 | (x) register ULong x; | ||
| 500 | #else | ||
| 501 | (register ULong x) | ||
| 502 | #endif | ||
| 503 | { | ||
| 504 | register int k = 0; | ||
| 505 | |||
| 506 | if (!(x & 0xffff0000)) { | ||
| 507 | k = 16; | ||
| 508 | x <<= 16; | ||
| 509 | } | ||
| 510 | if (!(x & 0xff000000)) { | ||
| 511 | k += 8; | ||
| 512 | x <<= 8; | ||
| 513 | } | ||
| 514 | if (!(x & 0xf0000000)) { | ||
| 515 | k += 4; | ||
| 516 | x <<= 4; | ||
| 517 | } | ||
| 518 | if (!(x & 0xc0000000)) { | ||
| 519 | k += 2; | ||
| 520 | x <<= 2; | ||
| 521 | } | ||
| 522 | if (!(x & 0x80000000)) { | ||
| 523 | k++; | ||
| 524 | if (!(x & 0x40000000)) | ||
| 525 | return 32; | ||
| 526 | } | ||
| 527 | return k; | ||
| 528 | } | ||
| 529 | |||
| 530 | static int | ||
| 531 | lo0bits | ||
| 532 | #ifdef KR_headers | ||
| 533 | (y) ULong *y; | ||
| 534 | #else | ||
| 535 | (ULong *y) | ||
| 536 | #endif | ||
| 537 | { | ||
| 538 | register int k; | ||
| 539 | register ULong x = *y; | ||
| 540 | |||
| 541 | if (x & 7) { | ||
| 542 | if (x & 1) | ||
| 543 | return 0; | ||
| 544 | if (x & 2) { | ||
| 545 | *y = x >> 1; | ||
| 546 | return 1; | ||
| 547 | } | ||
| 548 | *y = x >> 2; | ||
| 549 | return 2; | ||
| 550 | } | ||
| 551 | k = 0; | ||
| 552 | if (!(x & 0xffff)) { | ||
| 553 | k = 16; | ||
| 554 | x >>= 16; | ||
| 555 | } | ||
| 556 | if (!(x & 0xff)) { | ||
| 557 | k += 8; | ||
| 558 | x >>= 8; | ||
| 559 | } | ||
| 560 | if (!(x & 0xf)) { | ||
| 561 | k += 4; | ||
| 562 | x >>= 4; | ||
| 563 | } | ||
| 564 | if (!(x & 0x3)) { | ||
| 565 | k += 2; | ||
| 566 | x >>= 2; | ||
| 567 | } | ||
| 568 | if (!(x & 1)) { | ||
| 569 | k++; | ||
| 570 | x >>= 1; | ||
| 571 | if (!x & 1) | ||
| 572 | return 32; | ||
| 573 | } | ||
| 574 | *y = x; | ||
| 575 | return k; | ||
| 576 | } | ||
| 577 | |||
| 578 | static Bigint * | ||
| 579 | i2b | ||
| 580 | #ifdef KR_headers | ||
| 581 | (i) int i; | ||
| 582 | #else | ||
| 583 | (int i) | ||
| 584 | #endif | ||
| 585 | { | ||
| 586 | Bigint *b; | ||
| 587 | |||
| 588 | b = Balloc(1); | ||
| 589 | b->x[0] = i; | ||
| 590 | b->wds = 1; | ||
| 591 | return b; | ||
| 592 | } | ||
| 593 | |||
| 594 | static Bigint * | ||
| 595 | mult | ||
| 596 | #ifdef KR_headers | ||
| 597 | (a, b) Bigint *a, *b; | ||
| 598 | #else | ||
| 599 | (Bigint *a, Bigint *b) | ||
| 600 | #endif | ||
| 601 | { | ||
| 602 | Bigint *c; | ||
| 603 | int k, wa, wb, wc; | ||
| 604 | ULong carry, y, z; | ||
| 605 | ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0; | ||
| 606 | #ifdef Pack_32 | ||
| 607 | ULong z2; | ||
| 608 | #endif | ||
| 609 | |||
| 610 | if (a->wds < b->wds) { | ||
| 611 | c = a; | ||
| 612 | a = b; | ||
| 613 | b = c; | ||
| 614 | } | ||
| 615 | k = a->k; | ||
| 616 | wa = a->wds; | ||
| 617 | wb = b->wds; | ||
| 618 | wc = wa + wb; | ||
| 619 | if (wc > a->maxwds) | ||
| 620 | k++; | ||
| 621 | c = Balloc(k); | ||
| 622 | for(x = c->x, xa = x + wc; x < xa; x++) | ||
| 623 | *x = 0; | ||
| 624 | xa = a->x; | ||
| 625 | xae = xa + wa; | ||
| 626 | xb = b->x; | ||
| 627 | xbe = xb + wb; | ||
| 628 | xc0 = c->x; | ||
| 629 | #ifdef Pack_32 | ||
| 630 | for(; xb < xbe; xb++, xc0++) { | ||
| 631 | if (y = *xb & 0xffff) { | ||
| 632 | x = xa; | ||
| 633 | xc = xc0; | ||
| 634 | carry = 0; | ||
| 635 | do { | ||
| 636 | z = (*x & 0xffff) * y + (*xc & 0xffff) + carry; | ||
| 637 | carry = z >> 16; | ||
| 638 | z2 = (*x++ >> 16) * y + (*xc >> 16) + carry; | ||
| 639 | carry = z2 >> 16; | ||
| 640 | Storeinc(xc, z2, z); | ||
| 641 | } | ||
| 642 | while(x < xae); | ||
| 643 | *xc = carry; | ||
| 644 | } | ||
| 645 | if (y = *xb >> 16) { | ||
| 646 | x = xa; | ||
| 647 | xc = xc0; | ||
| 648 | carry = 0; | ||
| 649 | z2 = *xc; | ||
| 650 | do { | ||
| 651 | z = (*x & 0xffff) * y + (*xc >> 16) + carry; | ||
| 652 | carry = z >> 16; | ||
| 653 | Storeinc(xc, z, z2); | ||
| 654 | z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry; | ||
| 655 | carry = z2 >> 16; | ||
| 656 | } | ||
| 657 | while(x < xae); | ||
| 658 | *xc = z2; | ||
| 659 | } | ||
| 660 | } | ||
| 661 | #else | ||
| 662 | for(; xb < xbe; xc0++) { | ||
| 663 | if (y = *xb++) { | ||
| 664 | x = xa; | ||
| 665 | xc = xc0; | ||
| 666 | carry = 0; | ||
| 667 | do { | ||
| 668 | z = *x++ * y + *xc + carry; | ||
| 669 | carry = z >> 16; | ||
| 670 | *xc++ = z & 0xffff; | ||
| 671 | } | ||
| 672 | while(x < xae); | ||
| 673 | *xc = carry; | ||
| 674 | } | ||
| 675 | } | ||
| 676 | #endif | ||
| 677 | for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ; | ||
| 678 | c->wds = wc; | ||
| 679 | return c; | ||
| 680 | } | ||
| 681 | |||
| 682 | static Bigint *p5s; | ||
| 683 | |||
| 684 | static Bigint * | ||
| 685 | pow5mult | ||
| 686 | #ifdef KR_headers | ||
| 687 | (b, k) Bigint *b; int k; | ||
| 688 | #else | ||
| 689 | (Bigint *b, int k) | ||
| 690 | #endif | ||
| 691 | { | ||
| 692 | Bigint *b1, *p5, *p51; | ||
| 693 | int i; | ||
| 694 | static int p05[3] = { 5, 25, 125 }; | ||
| 695 | |||
| 696 | if (i = k & 3) | ||
| 697 | b = multadd(b, p05[i-1], 0); | ||
| 698 | |||
| 699 | if (!(k >>= 2)) | ||
| 700 | return b; | ||
| 701 | if (!(p5 = p5s)) { | ||
| 702 | /* first time */ | ||
| 703 | p5 = p5s = i2b(625); | ||
| 704 | p5->next = 0; | ||
| 705 | } | ||
| 706 | for(;;) { | ||
| 707 | if (k & 1) { | ||
| 708 | b1 = mult(b, p5); | ||
| 709 | Bfree(b); | ||
| 710 | b = b1; | ||
| 711 | } | ||
| 712 | if (!(k >>= 1)) | ||
| 713 | break; | ||
| 714 | if (!(p51 = p5->next)) { | ||
| 715 | p51 = p5->next = mult(p5,p5); | ||
| 716 | p51->next = 0; | ||
| 717 | } | ||
| 718 | p5 = p51; | ||
| 719 | } | ||
| 720 | return b; | ||
| 721 | } | ||
| 722 | |||
| 723 | static Bigint * | ||
| 724 | lshift | ||
| 725 | #ifdef KR_headers | ||
| 726 | (b, k) Bigint *b; int k; | ||
| 727 | #else | ||
| 728 | (Bigint *b, int k) | ||
| 729 | #endif | ||
| 730 | { | ||
| 731 | int i, k1, n, n1; | ||
| 732 | Bigint *b1; | ||
| 733 | ULong *x, *x1, *xe, z; | ||
| 734 | |||
| 735 | #ifdef Pack_32 | ||
| 736 | n = k >> 5; | ||
| 737 | #else | ||
| 738 | n = k >> 4; | ||
| 739 | #endif | ||
| 740 | k1 = b->k; | ||
| 741 | n1 = n + b->wds + 1; | ||
| 742 | for(i = b->maxwds; n1 > i; i <<= 1) | ||
| 743 | k1++; | ||
| 744 | b1 = Balloc(k1); | ||
| 745 | x1 = b1->x; | ||
| 746 | for(i = 0; i < n; i++) | ||
| 747 | *x1++ = 0; | ||
| 748 | x = b->x; | ||
| 749 | xe = x + b->wds; | ||
| 750 | #ifdef Pack_32 | ||
| 751 | if (k &= 0x1f) { | ||
| 752 | k1 = 32 - k; | ||
| 753 | z = 0; | ||
| 754 | do { | ||
| 755 | *x1++ = *x << k | z; | ||
| 756 | z = *x++ >> k1; | ||
| 757 | } | ||
| 758 | while(x < xe); | ||
| 759 | if (*x1 = z) | ||
| 760 | ++n1; | ||
| 761 | } | ||
| 762 | #else | ||
| 763 | if (k &= 0xf) { | ||
| 764 | k1 = 16 - k; | ||
| 765 | z = 0; | ||
| 766 | do { | ||
| 767 | *x1++ = *x << k & 0xffff | z; | ||
| 768 | z = *x++ >> k1; | ||
| 769 | } | ||
| 770 | while(x < xe); | ||
| 771 | if (*x1 = z) | ||
| 772 | ++n1; | ||
| 773 | } | ||
| 774 | #endif | ||
| 775 | else do | ||
| 776 | *x1++ = *x++; | ||
| 777 | while(x < xe); | ||
| 778 | b1->wds = n1 - 1; | ||
| 779 | Bfree(b); | ||
| 780 | return b1; | ||
| 781 | } | ||
| 782 | |||
| 783 | static int | ||
| 784 | cmp | ||
| 785 | #ifdef KR_headers | ||
| 786 | (a, b) Bigint *a, *b; | ||
| 787 | #else | ||
| 788 | (Bigint *a, Bigint *b) | ||
| 789 | #endif | ||
| 790 | { | ||
| 791 | ULong *xa, *xa0, *xb, *xb0; | ||
| 792 | int i, j; | ||
| 793 | |||
| 794 | i = a->wds; | ||
| 795 | j = b->wds; | ||
| 796 | #ifdef DEBUG | ||
| 797 | if (i > 1 && !a->x[i-1]) | ||
| 798 | Bug("cmp called with a->x[a->wds-1] == 0"); | ||
| 799 | if (j > 1 && !b->x[j-1]) | ||
| 800 | Bug("cmp called with b->x[b->wds-1] == 0"); | ||
| 801 | #endif | ||
| 802 | if (i -= j) | ||
| 803 | return i; | ||
| 804 | xa0 = a->x; | ||
| 805 | xa = xa0 + j; | ||
| 806 | xb0 = b->x; | ||
| 807 | xb = xb0 + j; | ||
| 808 | for(;;) { | ||
| 809 | if (*--xa != *--xb) | ||
| 810 | return *xa < *xb ? -1 : 1; | ||
| 811 | if (xa <= xa0) | ||
| 812 | break; | ||
| 813 | } | ||
| 814 | return 0; | ||
| 815 | } | ||
| 816 | |||
| 817 | static Bigint * | ||
| 818 | diff | ||
| 819 | #ifdef KR_headers | ||
| 820 | (a, b) Bigint *a, *b; | ||
| 821 | #else | ||
| 822 | (Bigint *a, Bigint *b) | ||
| 823 | #endif | ||
| 824 | { | ||
| 825 | Bigint *c; | ||
| 826 | int i, wa, wb; | ||
| 827 | Long borrow, y; /* We need signed shifts here. */ | ||
| 828 | ULong *xa, *xae, *xb, *xbe, *xc; | ||
| 829 | #ifdef Pack_32 | ||
| 830 | Long z; | ||
| 831 | #endif | ||
| 832 | |||
| 833 | i = cmp(a,b); | ||
| 834 | if (!i) { | ||
| 835 | c = Balloc(0); | ||
| 836 | c->wds = 1; | ||
| 837 | c->x[0] = 0; | ||
| 838 | return c; | ||
| 839 | } | ||
| 840 | if (i < 0) { | ||
| 841 | c = a; | ||
| 842 | a = b; | ||
| 843 | b = c; | ||
| 844 | i = 1; | ||
| 845 | } | ||
| 846 | else | ||
| 847 | i = 0; | ||
| 848 | c = Balloc(a->k); | ||
| 849 | c->sign = i; | ||
| 850 | wa = a->wds; | ||
| 851 | xa = a->x; | ||
| 852 | xae = xa + wa; | ||
| 853 | wb = b->wds; | ||
| 854 | xb = b->x; | ||
| 855 | xbe = xb + wb; | ||
| 856 | xc = c->x; | ||
| 857 | borrow = 0; | ||
| 858 | #ifdef Pack_32 | ||
| 859 | do { | ||
| 860 | y = (*xa & 0xffff) - (*xb & 0xffff) + borrow; | ||
| 861 | borrow = y >> 16; | ||
| 862 | Sign_Extend(borrow, y); | ||
| 863 | z = (*xa++ >> 16) - (*xb++ >> 16) + borrow; | ||
| 864 | borrow = z >> 16; | ||
| 865 | Sign_Extend(borrow, z); | ||
| 866 | Storeinc(xc, z, y); | ||
| 867 | } | ||
| 868 | while(xb < xbe); | ||
| 869 | while(xa < xae) { | ||
| 870 | y = (*xa & 0xffff) + borrow; | ||
| 871 | borrow = y >> 16; | ||
| 872 | Sign_Extend(borrow, y); | ||
| 873 | z = (*xa++ >> 16) + borrow; | ||
| 874 | borrow = z >> 16; | ||
| 875 | Sign_Extend(borrow, z); | ||
| 876 | Storeinc(xc, z, y); | ||
| 877 | } | ||
| 878 | #else | ||
| 879 | do { | ||
| 880 | y = *xa++ - *xb++ + borrow; | ||
| 881 | borrow = y >> 16; | ||
| 882 | Sign_Extend(borrow, y); | ||
| 883 | *xc++ = y & 0xffff; | ||
| 884 | } | ||
| 885 | while(xb < xbe); | ||
| 886 | while(xa < xae) { | ||
| 887 | y = *xa++ + borrow; | ||
| 888 | borrow = y >> 16; | ||
| 889 | Sign_Extend(borrow, y); | ||
| 890 | *xc++ = y & 0xffff; | ||
| 891 | } | ||
| 892 | #endif | ||
| 893 | while(!*--xc) | ||
| 894 | wa--; | ||
| 895 | c->wds = wa; | ||
| 896 | return c; | ||
| 897 | } | ||
| 898 | |||
| 899 | static double | ||
| 900 | ulp | ||
| 901 | #ifdef KR_headers | ||
| 902 | (x) double x; | ||
| 903 | #else | ||
| 904 | (double x) | ||
| 905 | #endif | ||
| 906 | { | ||
| 907 | register Long L; | ||
| 908 | double a; | ||
| 909 | |||
| 910 | L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1; | ||
| 911 | #ifndef Sudden_Underflow | ||
| 912 | if (L > 0) { | ||
| 913 | #endif | ||
| 914 | #ifdef IBM | ||
| 915 | L |= Exp_msk1 >> 4; | ||
| 916 | #endif | ||
| 917 | word0(a) = L; | ||
| 918 | word1(a) = 0; | ||
| 919 | #ifndef Sudden_Underflow | ||
| 920 | } | ||
| 921 | else { | ||
| 922 | L = -L >> Exp_shift; | ||
| 923 | if (L < Exp_shift) { | ||
| 924 | word0(a) = 0x80000 >> L; | ||
| 925 | word1(a) = 0; | ||
| 926 | } | ||
| 927 | else { | ||
| 928 | word0(a) = 0; | ||
| 929 | L -= Exp_shift; | ||
| 930 | word1(a) = L >= 31 ? 1 : 1 << 31 - L; | ||
| 931 | } | ||
| 932 | } | ||
| 933 | #endif | ||
| 934 | return a; | ||
| 935 | } | ||
| 936 | |||
| 937 | static double | ||
| 938 | b2d | ||
| 939 | #ifdef KR_headers | ||
| 940 | (a, e) Bigint *a; int *e; | ||
| 941 | #else | ||
| 942 | (Bigint *a, int *e) | ||
| 943 | #endif | ||
| 944 | { | ||
| 945 | ULong *xa, *xa0, w, y, z; | ||
| 946 | int k; | ||
| 947 | double d; | ||
| 948 | #ifdef VAX | ||
| 949 | ULong d0, d1; | ||
| 950 | #else | ||
| 951 | #define d0 word0(d) | ||
| 952 | #define d1 word1(d) | ||
| 953 | #endif | ||
| 954 | |||
| 955 | xa0 = a->x; | ||
| 956 | xa = xa0 + a->wds; | ||
| 957 | y = *--xa; | ||
| 958 | #ifdef DEBUG | ||
| 959 | if (!y) Bug("zero y in b2d"); | ||
| 960 | #endif | ||
| 961 | k = hi0bits(y); | ||
| 962 | *e = 32 - k; | ||
| 963 | #ifdef Pack_32 | ||
| 964 | if (k < Ebits) { | ||
| 965 | d0 = Exp_1 | y >> Ebits - k; | ||
| 966 | w = xa > xa0 ? *--xa : 0; | ||
| 967 | d1 = y << (32-Ebits) + k | w >> Ebits - k; | ||
| 968 | goto ret_d; | ||
| 969 | } | ||
| 970 | z = xa > xa0 ? *--xa : 0; | ||
| 971 | if (k -= Ebits) { | ||
| 972 | d0 = Exp_1 | y << k | z >> 32 - k; | ||
| 973 | y = xa > xa0 ? *--xa : 0; | ||
| 974 | d1 = z << k | y >> 32 - k; | ||
| 975 | } | ||
| 976 | else { | ||
| 977 | d0 = Exp_1 | y; | ||
| 978 | d1 = z; | ||
| 979 | } | ||
| 980 | #else | ||
| 981 | if (k < Ebits + 16) { | ||
| 982 | z = xa > xa0 ? *--xa : 0; | ||
| 983 | d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k; | ||
| 984 | w = xa > xa0 ? *--xa : 0; | ||
| 985 | y = xa > xa0 ? *--xa : 0; | ||
| 986 | d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k; | ||
| 987 | goto ret_d; | ||
| 988 | } | ||
| 989 | z = xa > xa0 ? *--xa : 0; | ||
| 990 | w = xa > xa0 ? *--xa : 0; | ||
| 991 | k -= Ebits + 16; | ||
| 992 | d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k; | ||
| 993 | y = xa > xa0 ? *--xa : 0; | ||
| 994 | d1 = w << k + 16 | y << k; | ||
| 995 | #endif | ||
| 996 | ret_d: | ||
| 997 | #ifdef VAX | ||
| 998 | word0(d) = d0 >> 16 | d0 << 16; | ||
| 999 | word1(d) = d1 >> 16 | d1 << 16; | ||
| 1000 | #else | ||
| 1001 | #undef d0 | ||
| 1002 | #undef d1 | ||
| 1003 | #endif | ||
| 1004 | return d; | ||
| 1005 | } | ||
| 1006 | |||
| 1007 | static Bigint * | ||
| 1008 | d2b | ||
| 1009 | #ifdef KR_headers | ||
| 1010 | (d, e, bits) double d; int *e, *bits; | ||
| 1011 | #else | ||
| 1012 | (double d, int *e, int *bits) | ||
| 1013 | #endif | ||
| 1014 | { | ||
| 1015 | Bigint *b; | ||
| 1016 | int de, i, k; | ||
| 1017 | ULong *x, y, z; | ||
| 1018 | #ifdef VAX | ||
| 1019 | ULong d0, d1; | ||
| 1020 | d0 = word0(d) >> 16 | word0(d) << 16; | ||
| 1021 | d1 = word1(d) >> 16 | word1(d) << 16; | ||
| 1022 | #else | ||
| 1023 | #define d0 word0(d) | ||
| 1024 | #define d1 word1(d) | ||
| 1025 | #endif | ||
| 1026 | |||
| 1027 | #ifdef Pack_32 | ||
| 1028 | b = Balloc(1); | ||
| 1029 | #else | ||
| 1030 | b = Balloc(2); | ||
| 1031 | #endif | ||
| 1032 | x = b->x; | ||
| 1033 | |||
| 1034 | z = d0 & Frac_mask; | ||
| 1035 | d0 &= 0x7fffffff; /* clear sign bit, which we ignore */ | ||
| 1036 | #ifdef Sudden_Underflow | ||
| 1037 | de = (int)(d0 >> Exp_shift); | ||
| 1038 | #ifndef IBM | ||
| 1039 | z |= Exp_msk11; | ||
| 1040 | #endif | ||
| 1041 | #else | ||
| 1042 | if (de = (int)(d0 >> Exp_shift)) | ||
| 1043 | z |= Exp_msk1; | ||
| 1044 | #endif | ||
| 1045 | #ifdef Pack_32 | ||
| 1046 | if (y = d1) { | ||
| 1047 | if (k = lo0bits(&y)) { | ||
| 1048 | x[0] = y | z << 32 - k; | ||
| 1049 | z >>= k; | ||
| 1050 | } | ||
| 1051 | else | ||
| 1052 | x[0] = y; | ||
| 1053 | i = b->wds = (x[1] = z) ? 2 : 1; | ||
| 1054 | } | ||
| 1055 | else { | ||
| 1056 | #ifdef DEBUG | ||
| 1057 | if (!z) | ||
| 1058 | Bug("Zero passed to d2b"); | ||
| 1059 | #endif | ||
| 1060 | k = lo0bits(&z); | ||
| 1061 | x[0] = z; | ||
| 1062 | i = b->wds = 1; | ||
| 1063 | k += 32; | ||
| 1064 | } | ||
| 1065 | #else | ||
| 1066 | if (y = d1) { | ||
| 1067 | if (k = lo0bits(&y)) | ||
| 1068 | if (k >= 16) { | ||
| 1069 | x[0] = y | z << 32 - k & 0xffff; | ||
| 1070 | x[1] = z >> k - 16 & 0xffff; | ||
| 1071 | x[2] = z >> k; | ||
| 1072 | i = 2; | ||
| 1073 | } | ||
| 1074 | else { | ||
| 1075 | x[0] = y & 0xffff; | ||
| 1076 | x[1] = y >> 16 | z << 16 - k & 0xffff; | ||
| 1077 | x[2] = z >> k & 0xffff; | ||
| 1078 | x[3] = z >> k+16; | ||
| 1079 | i = 3; | ||
| 1080 | } | ||
| 1081 | else { | ||
| 1082 | x[0] = y & 0xffff; | ||
| 1083 | x[1] = y >> 16; | ||
| 1084 | x[2] = z & 0xffff; | ||
| 1085 | x[3] = z >> 16; | ||
| 1086 | i = 3; | ||
| 1087 | } | ||
| 1088 | } | ||
| 1089 | else { | ||
| 1090 | #ifdef DEBUG | ||
| 1091 | if (!z) | ||
| 1092 | Bug("Zero passed to d2b"); | ||
| 1093 | #endif | ||
| 1094 | k = lo0bits(&z); | ||
| 1095 | if (k >= 16) { | ||
| 1096 | x[0] = z; | ||
| 1097 | i = 0; | ||
| 1098 | } | ||
| 1099 | else { | ||
| 1100 | x[0] = z & 0xffff; | ||
| 1101 | x[1] = z >> 16; | ||
| 1102 | i = 1; | ||
| 1103 | } | ||
| 1104 | k += 32; | ||
| 1105 | } | ||
| 1106 | while(!x[i]) | ||
| 1107 | --i; | ||
| 1108 | b->wds = i + 1; | ||
| 1109 | #endif | ||
| 1110 | #ifndef Sudden_Underflow | ||
| 1111 | if (de) { | ||
| 1112 | #endif | ||
| 1113 | #ifdef IBM | ||
| 1114 | *e = (de - Bias - (P-1) << 2) + k; | ||
| 1115 | *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask); | ||
| 1116 | #else | ||
| 1117 | *e = de - Bias - (P-1) + k; | ||
| 1118 | *bits = P - k; | ||
| 1119 | #endif | ||
| 1120 | #ifndef Sudden_Underflow | ||
| 1121 | } | ||
| 1122 | else { | ||
| 1123 | *e = de - Bias - (P-1) + 1 + k; | ||
| 1124 | #ifdef Pack_32 | ||
| 1125 | *bits = 32*i - hi0bits(x[i-1]); | ||
| 1126 | #else | ||
| 1127 | *bits = (i+2)*16 - hi0bits(x[i]); | ||
| 1128 | #endif | ||
| 1129 | } | ||
| 1130 | #endif | ||
| 1131 | return b; | ||
| 1132 | } | ||
| 1133 | #undef d0 | ||
| 1134 | #undef d1 | ||
| 1135 | |||
| 1136 | static double | ||
| 1137 | ratio | ||
| 1138 | #ifdef KR_headers | ||
| 1139 | (a, b) Bigint *a, *b; | ||
| 1140 | #else | ||
| 1141 | (Bigint *a, Bigint *b) | ||
| 1142 | #endif | ||
| 1143 | { | ||
| 1144 | double da, db; | ||
| 1145 | int k, ka, kb; | ||
| 1146 | |||
| 1147 | da = b2d(a, &ka); | ||
| 1148 | db = b2d(b, &kb); | ||
| 1149 | #ifdef Pack_32 | ||
| 1150 | k = ka - kb + 32*(a->wds - b->wds); | ||
| 1151 | #else | ||
| 1152 | k = ka - kb + 16*(a->wds - b->wds); | ||
| 1153 | #endif | ||
| 1154 | #ifdef IBM | ||
| 1155 | if (k > 0) { | ||
| 1156 | word0(da) += (k >> 2)*Exp_msk1; | ||
| 1157 | if (k &= 3) | ||
| 1158 | da *= 1 << k; | ||
| 1159 | } | ||
| 1160 | else { | ||
| 1161 | k = -k; | ||
| 1162 | word0(db) += (k >> 2)*Exp_msk1; | ||
| 1163 | if (k &= 3) | ||
| 1164 | db *= 1 << k; | ||
| 1165 | } | ||
| 1166 | #else | ||
| 1167 | if (k > 0) | ||
| 1168 | word0(da) += k*Exp_msk1; | ||
| 1169 | else { | ||
| 1170 | k = -k; | ||
| 1171 | word0(db) += k*Exp_msk1; | ||
| 1172 | } | ||
| 1173 | #endif | ||
| 1174 | return da / db; | ||
| 1175 | } | ||
| 1176 | |||
| 1177 | static CONST double | ||
| 1178 | tens[] = { | ||
| 1179 | 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, | ||
| 1180 | 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, | ||
| 1181 | 1e20, 1e21, 1e22 | ||
| 1182 | #ifdef VAX | ||
| 1183 | , 1e23, 1e24 | ||
| 1184 | #endif | ||
| 1185 | }; | ||
| 1186 | |||
| 1187 | #ifdef IEEE_Arith | ||
| 1188 | static CONST double bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 }; | ||
| 1189 | static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256 }; | ||
| 1190 | #define n_bigtens 5 | ||
| 1191 | #else | ||
| 1192 | #ifdef IBM | ||
| 1193 | static CONST double bigtens[] = { 1e16, 1e32, 1e64 }; | ||
| 1194 | static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 }; | ||
| 1195 | #define n_bigtens 3 | ||
| 1196 | #else | ||
| 1197 | static CONST double bigtens[] = { 1e16, 1e32 }; | ||
| 1198 | static CONST double tinytens[] = { 1e-16, 1e-32 }; | ||
| 1199 | #define n_bigtens 2 | ||
| 1200 | #endif | ||
| 1201 | #endif | ||
| 1202 | |||
| 1203 | double | ||
| 1204 | strtod | ||
| 1205 | #ifdef KR_headers | ||
| 1206 | (s00, se) CONST char *s00; char **se; | ||
| 1207 | #else | ||
| 1208 | (CONST char *s00, char **se) | ||
| 1209 | #endif | ||
| 1210 | { | ||
| 1211 | int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign, | ||
| 1212 | e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign; | ||
| 1213 | CONST char *s, *s0, *s1; | ||
| 1214 | double aadj, aadj1, adj, rv, rv0; | ||
| 1215 | Long L; | ||
| 1216 | ULong y, z; | ||
| 1217 | Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; | ||
| 1218 | |||
| 1219 | #ifndef KR_headers | ||
| 1220 | CONST char decimal_point = localeconv()->decimal_point[0]; | ||
| 1221 | #else | ||
| 1222 | CONST char decimal_point = '.'; | ||
| 1223 | #endif | ||
| 1224 | |||
| 1225 | sign = nz0 = nz = 0; | ||
| 1226 | rv = 0.; | ||
| 1227 | |||
| 1228 | |||
| 1229 | for(s = s00; isspace(*s); s++) | ||
| 1230 | ; | ||
| 1231 | |||
| 1232 | if (*s == '-') { | ||
| 1233 | sign = 1; | ||
| 1234 | s++; | ||
| 1235 | } else if (*s == '+') { | ||
| 1236 | s++; | ||
| 1237 | } | ||
| 1238 | |||
| 1239 | if (*s == '\0') { | ||
| 1240 | s = s00; | ||
| 1241 | goto ret; | ||
| 1242 | } | ||
| 1243 | |||
| 1244 | if (*s == '0') { | ||
| 1245 | nz0 = 1; | ||
| 1246 | while(*++s == '0') ; | ||
| 1247 | if (!*s) | ||
| 1248 | goto ret; | ||
| 1249 | } | ||
| 1250 | s0 = s; | ||
| 1251 | y = z = 0; | ||
| 1252 | for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) | ||
| 1253 | if (nd < 9) | ||
| 1254 | y = 10*y + c - '0'; | ||
| 1255 | else if (nd < 16) | ||
| 1256 | z = 10*z + c - '0'; | ||
| 1257 | nd0 = nd; | ||
| 1258 | if (c == decimal_point) { | ||
| 1259 | c = *++s; | ||
| 1260 | if (!nd) { | ||
| 1261 | for(; c == '0'; c = *++s) | ||
| 1262 | nz++; | ||
| 1263 | if (c > '0' && c <= '9') { | ||
| 1264 | s0 = s; | ||
| 1265 | nf += nz; | ||
| 1266 | nz = 0; | ||
| 1267 | goto have_dig; | ||
| 1268 | } | ||
| 1269 | goto dig_done; | ||
| 1270 | } | ||
| 1271 | for(; c >= '0' && c <= '9'; c = *++s) { | ||
| 1272 | have_dig: | ||
| 1273 | nz++; | ||
| 1274 | if (c -= '0') { | ||
| 1275 | nf += nz; | ||
| 1276 | for(i = 1; i < nz; i++) | ||
| 1277 | if (nd++ < 9) | ||
| 1278 | y *= 10; | ||
| 1279 | else if (nd <= DBL_DIG + 1) | ||
| 1280 | z *= 10; | ||
| 1281 | if (nd++ < 9) | ||
| 1282 | y = 10*y + c; | ||
| 1283 | else if (nd <= DBL_DIG + 1) | ||
| 1284 | z = 10*z + c; | ||
| 1285 | nz = 0; | ||
| 1286 | } | ||
| 1287 | } | ||
| 1288 | } | ||
| 1289 | dig_done: | ||
| 1290 | e = 0; | ||
| 1291 | if (c == 'e' || c == 'E') { | ||
| 1292 | if (!nd && !nz && !nz0) { | ||
| 1293 | s = s00; | ||
| 1294 | goto ret; | ||
| 1295 | } | ||
| 1296 | s00 = s; | ||
| 1297 | esign = 0; | ||
| 1298 | switch(c = *++s) { | ||
| 1299 | case '-': | ||
| 1300 | esign = 1; | ||
| 1301 | case '+': | ||
| 1302 | c = *++s; | ||
| 1303 | } | ||
| 1304 | if (c >= '0' && c <= '9') { | ||
| 1305 | while(c == '0') | ||
| 1306 | c = *++s; | ||
| 1307 | if (c > '0' && c <= '9') { | ||
| 1308 | L = c - '0'; | ||
| 1309 | s1 = s; | ||
| 1310 | while((c = *++s) >= '0' && c <= '9') | ||
| 1311 | L = 10*L + c - '0'; | ||
| 1312 | if (s - s1 > 8 || L > 19999) | ||
| 1313 | /* Avoid confusion from exponents | ||
| 1314 | * so large that e might overflow. | ||
| 1315 | */ | ||
| 1316 | e = 19999; /* safe for 16 bit ints */ | ||
| 1317 | else | ||
| 1318 | e = (int)L; | ||
| 1319 | if (esign) | ||
| 1320 | e = -e; | ||
| 1321 | } | ||
| 1322 | else | ||
| 1323 | e = 0; | ||
| 1324 | } | ||
| 1325 | else | ||
| 1326 | s = s00; | ||
| 1327 | } | ||
| 1328 | if (!nd) { | ||
| 1329 | if (!nz && !nz0) | ||
| 1330 | s = s00; | ||
| 1331 | goto ret; | ||
| 1332 | } | ||
| 1333 | e1 = e -= nf; | ||
| 1334 | |||
| 1335 | /* Now we have nd0 digits, starting at s0, followed by a | ||
| 1336 | * decimal point, followed by nd-nd0 digits. The number we're | ||
| 1337 | * after is the integer represented by those digits times | ||
| 1338 | * 10**e */ | ||
| 1339 | |||
| 1340 | if (!nd0) | ||
| 1341 | nd0 = nd; | ||
| 1342 | k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; | ||
| 1343 | rv = y; | ||
| 1344 | if (k > 9) | ||
| 1345 | rv = tens[k - 9] * rv + z; | ||
| 1346 | bd0 = 0; | ||
| 1347 | if (nd <= DBL_DIG | ||
| 1348 | #ifndef RND_PRODQUOT | ||
| 1349 | && FLT_ROUNDS == 1 | ||
| 1350 | #endif | ||
| 1351 | ) { | ||
| 1352 | if (!e) | ||
| 1353 | goto ret; | ||
| 1354 | if (e > 0) { | ||
| 1355 | if (e <= Ten_pmax) { | ||
| 1356 | #ifdef VAX | ||
| 1357 | goto vax_ovfl_check; | ||
| 1358 | #else | ||
| 1359 | /* rv = */ rounded_product(rv, tens[e]); | ||
| 1360 | goto ret; | ||
| 1361 | #endif | ||
| 1362 | } | ||
| 1363 | i = DBL_DIG - nd; | ||
| 1364 | if (e <= Ten_pmax + i) { | ||
| 1365 | /* A fancier test would sometimes let us do | ||
| 1366 | * this for larger i values. | ||
| 1367 | */ | ||
| 1368 | e -= i; | ||
| 1369 | rv *= tens[i]; | ||
| 1370 | #ifdef VAX | ||
| 1371 | /* VAX exponent range is so narrow we must | ||
| 1372 | * worry about overflow here... | ||
| 1373 | */ | ||
| 1374 | vax_ovfl_check: | ||
| 1375 | word0(rv) -= P*Exp_msk1; | ||
| 1376 | /* rv = */ rounded_product(rv, tens[e]); | ||
| 1377 | if ((word0(rv) & Exp_mask) | ||
| 1378 | > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) | ||
| 1379 | goto ovfl; | ||
| 1380 | word0(rv) += P*Exp_msk1; | ||
| 1381 | #else | ||
| 1382 | /* rv = */ rounded_product(rv, tens[e]); | ||
| 1383 | #endif | ||
| 1384 | goto ret; | ||
| 1385 | } | ||
| 1386 | } | ||
| 1387 | #ifndef Inaccurate_Divide | ||
| 1388 | else if (e >= -Ten_pmax) { | ||
| 1389 | /* rv = */ rounded_quotient(rv, tens[-e]); | ||
| 1390 | goto ret; | ||
| 1391 | } | ||
| 1392 | #endif | ||
| 1393 | } | ||
| 1394 | e1 += nd - k; | ||
| 1395 | |||
| 1396 | /* Get starting approximation = rv * 10**e1 */ | ||
| 1397 | |||
| 1398 | if (e1 > 0) { | ||
| 1399 | if (i = e1 & 15) | ||
| 1400 | rv *= tens[i]; | ||
| 1401 | if (e1 &= ~15) { | ||
| 1402 | if (e1 > DBL_MAX_10_EXP) { | ||
| 1403 | ovfl: | ||
| 1404 | errno = ERANGE; | ||
| 1405 | #ifdef __STDC__ | ||
| 1406 | rv = HUGE_VAL; | ||
| 1407 | #else | ||
| 1408 | /* Can't trust HUGE_VAL */ | ||
| 1409 | #ifdef IEEE_Arith | ||
| 1410 | word0(rv) = Exp_mask; | ||
| 1411 | word1(rv) = 0; | ||
| 1412 | #else | ||
| 1413 | word0(rv) = Big0; | ||
| 1414 | word1(rv) = Big1; | ||
| 1415 | #endif | ||
| 1416 | #endif | ||
| 1417 | if (bd0) | ||
| 1418 | goto retfree; | ||
| 1419 | goto ret; | ||
| 1420 | } | ||
| 1421 | if (e1 >>= 4) { | ||
| 1422 | for(j = 0; e1 > 1; j++, e1 >>= 1) | ||
| 1423 | if (e1 & 1) | ||
| 1424 | rv *= bigtens[j]; | ||
| 1425 | /* The last multiplication could overflow. */ | ||
| 1426 | word0(rv) -= P*Exp_msk1; | ||
| 1427 | rv *= bigtens[j]; | ||
| 1428 | if ((z = word0(rv) & Exp_mask) | ||
| 1429 | > Exp_msk1*(DBL_MAX_EXP+Bias-P)) | ||
| 1430 | goto ovfl; | ||
| 1431 | if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) { | ||
| 1432 | /* set to largest number */ | ||
| 1433 | /* (Can't trust DBL_MAX) */ | ||
| 1434 | word0(rv) = Big0; | ||
| 1435 | word1(rv) = Big1; | ||
| 1436 | } | ||
| 1437 | else | ||
| 1438 | word0(rv) += P*Exp_msk1; | ||
| 1439 | } | ||
| 1440 | |||
| 1441 | } | ||
| 1442 | } | ||
| 1443 | else if (e1 < 0) { | ||
| 1444 | e1 = -e1; | ||
| 1445 | if (i = e1 & 15) | ||
| 1446 | rv /= tens[i]; | ||
| 1447 | if (e1 &= ~15) { | ||
| 1448 | e1 >>= 4; | ||
| 1449 | if (e1 >= 1 << n_bigtens) | ||
| 1450 | goto undfl; | ||
| 1451 | for(j = 0; e1 > 1; j++, e1 >>= 1) | ||
| 1452 | if (e1 & 1) | ||
| 1453 | rv *= tinytens[j]; | ||
| 1454 | /* The last multiplication could underflow. */ | ||
| 1455 | rv0 = rv; | ||
| 1456 | rv *= tinytens[j]; | ||
| 1457 | if (!rv) { | ||
| 1458 | rv = 2.*rv0; | ||
| 1459 | rv *= tinytens[j]; | ||
| 1460 | if (!rv) { | ||
| 1461 | undfl: | ||
| 1462 | rv = 0.; | ||
| 1463 | errno = ERANGE; | ||
| 1464 | if (bd0) | ||
| 1465 | goto retfree; | ||
| 1466 | goto ret; | ||
| 1467 | } | ||
| 1468 | word0(rv) = Tiny0; | ||
| 1469 | word1(rv) = Tiny1; | ||
| 1470 | /* The refinement below will clean | ||
| 1471 | * this approximation up. | ||
| 1472 | */ | ||
| 1473 | } | ||
| 1474 | } | ||
| 1475 | } | ||
| 1476 | |||
| 1477 | /* Now the hard part -- adjusting rv to the correct value.*/ | ||
| 1478 | |||
| 1479 | /* Put digits into bd: true value = bd * 10^e */ | ||
| 1480 | |||
| 1481 | bd0 = s2b(s0, nd0, nd, y); | ||
| 1482 | |||
| 1483 | for(;;) { | ||
| 1484 | bd = Balloc(bd0->k); | ||
| 1485 | Bcopy(bd, bd0); | ||
| 1486 | bb = d2b(rv, &bbe, &bbbits); /* rv = bb * 2^bbe */ | ||
| 1487 | bs = i2b(1); | ||
| 1488 | |||
| 1489 | if (e >= 0) { | ||
| 1490 | bb2 = bb5 = 0; | ||
| 1491 | bd2 = bd5 = e; | ||
| 1492 | } | ||
| 1493 | else { | ||
| 1494 | bb2 = bb5 = -e; | ||
| 1495 | bd2 = bd5 = 0; | ||
| 1496 | } | ||
| 1497 | if (bbe >= 0) | ||
| 1498 | bb2 += bbe; | ||
| 1499 | else | ||
| 1500 | bd2 -= bbe; | ||
| 1501 | bs2 = bb2; | ||
| 1502 | #ifdef Sudden_Underflow | ||
| 1503 | #ifdef IBM | ||
| 1504 | j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3); | ||
| 1505 | #else | ||
| 1506 | j = P + 1 - bbbits; | ||
| 1507 | #endif | ||
| 1508 | #else | ||
| 1509 | i = bbe + bbbits - 1; /* logb(rv) */ | ||
| 1510 | if (i < Emin) /* denormal */ | ||
| 1511 | j = bbe + (P-Emin); | ||
| 1512 | else | ||
| 1513 | j = P + 1 - bbbits; | ||
| 1514 | #endif | ||
| 1515 | bb2 += j; | ||
| 1516 | bd2 += j; | ||
| 1517 | i = bb2 < bd2 ? bb2 : bd2; | ||
| 1518 | if (i > bs2) | ||
| 1519 | i = bs2; | ||
| 1520 | if (i > 0) { | ||
| 1521 | bb2 -= i; | ||
| 1522 | bd2 -= i; | ||
| 1523 | bs2 -= i; | ||
| 1524 | } | ||
| 1525 | if (bb5 > 0) { | ||
| 1526 | bs = pow5mult(bs, bb5); | ||
| 1527 | bb1 = mult(bs, bb); | ||
| 1528 | Bfree(bb); | ||
| 1529 | bb = bb1; | ||
| 1530 | } | ||
| 1531 | if (bb2 > 0) | ||
| 1532 | bb = lshift(bb, bb2); | ||
| 1533 | if (bd5 > 0) | ||
| 1534 | bd = pow5mult(bd, bd5); | ||
| 1535 | if (bd2 > 0) | ||
| 1536 | bd = lshift(bd, bd2); | ||
| 1537 | if (bs2 > 0) | ||
| 1538 | bs = lshift(bs, bs2); | ||
| 1539 | delta = diff(bb, bd); | ||
| 1540 | dsign = delta->sign; | ||
| 1541 | delta->sign = 0; | ||
| 1542 | i = cmp(delta, bs); | ||
| 1543 | if (i < 0) { | ||
| 1544 | /* Error is less than half an ulp -- check for | ||
| 1545 | * special case of mantissa a power of two. | ||
| 1546 | */ | ||
| 1547 | if (dsign || word1(rv) || word0(rv) & Bndry_mask) | ||
| 1548 | break; | ||
| 1549 | delta = lshift(delta,Log2P); | ||
| 1550 | if (cmp(delta, bs) > 0) | ||
| 1551 | goto drop_down; | ||
| 1552 | break; | ||
| 1553 | } | ||
| 1554 | if (i == 0) { | ||
| 1555 | /* exactly half-way between */ | ||
| 1556 | if (dsign) { | ||
| 1557 | if ((word0(rv) & Bndry_mask1) == Bndry_mask1 | ||
| 1558 | && word1(rv) == 0xffffffff) { | ||
| 1559 | /*boundary case -- increment exponent*/ | ||
| 1560 | word0(rv) = (word0(rv) & Exp_mask) | ||
| 1561 | + Exp_msk1 | ||
| 1562 | #ifdef IBM | ||
| 1563 | | Exp_msk1 >> 4 | ||
| 1564 | #endif | ||
| 1565 | ; | ||
| 1566 | word1(rv) = 0; | ||
| 1567 | break; | ||
| 1568 | } | ||
| 1569 | } | ||
| 1570 | else if (!(word0(rv) & Bndry_mask) && !word1(rv)) { | ||
| 1571 | drop_down: | ||
| 1572 | /* boundary case -- decrement exponent */ | ||
| 1573 | #ifdef Sudden_Underflow | ||
| 1574 | L = word0(rv) & Exp_mask; | ||
| 1575 | #ifdef IBM | ||
| 1576 | if (L < Exp_msk1) | ||
| 1577 | #else | ||
| 1578 | if (L <= Exp_msk1) | ||
| 1579 | #endif | ||
| 1580 | goto undfl; | ||
| 1581 | L -= Exp_msk1; | ||
| 1582 | #else | ||
| 1583 | L = (word0(rv) & Exp_mask) - Exp_msk1; | ||
| 1584 | #endif | ||
| 1585 | word0(rv) = L | Bndry_mask1; | ||
| 1586 | word1(rv) = 0xffffffff; | ||
| 1587 | #ifdef IBM | ||
| 1588 | goto cont; | ||
| 1589 | #else | ||
| 1590 | break; | ||
| 1591 | #endif | ||
| 1592 | } | ||
| 1593 | #ifndef ROUND_BIASED | ||
| 1594 | if (!(word1(rv) & LSB)) | ||
| 1595 | break; | ||
| 1596 | #endif | ||
| 1597 | if (dsign) | ||
| 1598 | rv += ulp(rv); | ||
| 1599 | #ifndef ROUND_BIASED | ||
| 1600 | else { | ||
| 1601 | rv -= ulp(rv); | ||
| 1602 | #ifndef Sudden_Underflow | ||
| 1603 | if (!rv) | ||
| 1604 | goto undfl; | ||
| 1605 | #endif | ||
| 1606 | } | ||
| 1607 | #endif | ||
| 1608 | break; | ||
| 1609 | } | ||
| 1610 | if ((aadj = ratio(delta, bs)) <= 2.) { | ||
| 1611 | if (dsign) | ||
| 1612 | aadj = aadj1 = 1.; | ||
| 1613 | else if (word1(rv) || word0(rv) & Bndry_mask) { | ||
| 1614 | #ifndef Sudden_Underflow | ||
| 1615 | if (word1(rv) == Tiny1 && !word0(rv)) | ||
| 1616 | goto undfl; | ||
| 1617 | #endif | ||
| 1618 | aadj = 1.; | ||
| 1619 | aadj1 = -1.; | ||
| 1620 | } | ||
| 1621 | else { | ||
| 1622 | /* special case -- power of FLT_RADIX to be */ | ||
| 1623 | /* rounded down... */ | ||
| 1624 | |||
| 1625 | if (aadj < 2./FLT_RADIX) | ||
| 1626 | aadj = 1./FLT_RADIX; | ||
| 1627 | else | ||
| 1628 | aadj *= 0.5; | ||
| 1629 | aadj1 = -aadj; | ||
| 1630 | } | ||
| 1631 | } | ||
| 1632 | else { | ||
| 1633 | aadj *= 0.5; | ||
| 1634 | aadj1 = dsign ? aadj : -aadj; | ||
| 1635 | #ifdef Check_FLT_ROUNDS | ||
| 1636 | switch(FLT_ROUNDS) { | ||
| 1637 | case 2: /* towards +infinity */ | ||
| 1638 | aadj1 -= 0.5; | ||
| 1639 | break; | ||
| 1640 | case 0: /* towards 0 */ | ||
| 1641 | case 3: /* towards -infinity */ | ||
| 1642 | aadj1 += 0.5; | ||
| 1643 | } | ||
| 1644 | #else | ||
| 1645 | if (FLT_ROUNDS == 0) | ||
| 1646 | aadj1 += 0.5; | ||
| 1647 | #endif | ||
| 1648 | } | ||
| 1649 | y = word0(rv) & Exp_mask; | ||
| 1650 | |||
| 1651 | /* Check for overflow */ | ||
| 1652 | |||
| 1653 | if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { | ||
| 1654 | rv0 = rv; | ||
| 1655 | word0(rv) -= P*Exp_msk1; | ||
| 1656 | adj = aadj1 * ulp(rv); | ||
| 1657 | rv += adj; | ||
| 1658 | if ((word0(rv) & Exp_mask) >= | ||
| 1659 | Exp_msk1*(DBL_MAX_EXP+Bias-P)) { | ||
| 1660 | if (word0(rv0) == Big0 && word1(rv0) == Big1) | ||
| 1661 | goto ovfl; | ||
| 1662 | word0(rv) = Big0; | ||
| 1663 | word1(rv) = Big1; | ||
| 1664 | goto cont; | ||
| 1665 | } | ||
| 1666 | else | ||
| 1667 | word0(rv) += P*Exp_msk1; | ||
| 1668 | } | ||
| 1669 | else { | ||
| 1670 | #ifdef Sudden_Underflow | ||
| 1671 | if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { | ||
| 1672 | rv0 = rv; | ||
| 1673 | word0(rv) += P*Exp_msk1; | ||
| 1674 | adj = aadj1 * ulp(rv); | ||
| 1675 | rv += adj; | ||
| 1676 | #ifdef IBM | ||
| 1677 | if ((word0(rv) & Exp_mask) < P*Exp_msk1) | ||
| 1678 | #else | ||
| 1679 | if ((word0(rv) & Exp_mask) <= P*Exp_msk1) | ||
| 1680 | #endif | ||
| 1681 | { | ||
| 1682 | if (word0(rv0) == Tiny0 | ||
| 1683 | && word1(rv0) == Tiny1) | ||
| 1684 | goto undfl; | ||
| 1685 | word0(rv) = Tiny0; | ||
| 1686 | word1(rv) = Tiny1; | ||
| 1687 | goto cont; | ||
| 1688 | } | ||
| 1689 | else | ||
| 1690 | word0(rv) -= P*Exp_msk1; | ||
| 1691 | } | ||
| 1692 | else { | ||
| 1693 | adj = aadj1 * ulp(rv); | ||
| 1694 | rv += adj; | ||
| 1695 | } | ||
| 1696 | #else | ||
| 1697 | /* Compute adj so that the IEEE rounding rules will | ||
| 1698 | * correctly round rv + adj in some half-way cases. | ||
| 1699 | * If rv * ulp(rv) is denormalized (i.e., | ||
| 1700 | * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid | ||
| 1701 | * trouble from bits lost to denormalization; | ||
| 1702 | * example: 1.2e-307 . | ||
| 1703 | */ | ||
| 1704 | if (y <= (P-1)*Exp_msk1 && aadj >= 1.) { | ||
| 1705 | aadj1 = (double)(int)(aadj + 0.5); | ||
| 1706 | if (!dsign) | ||
| 1707 | aadj1 = -aadj1; | ||
| 1708 | } | ||
| 1709 | adj = aadj1 * ulp(rv); | ||
| 1710 | rv += adj; | ||
| 1711 | #endif | ||
| 1712 | } | ||
| 1713 | z = word0(rv) & Exp_mask; | ||
| 1714 | if (y == z) { | ||
| 1715 | /* Can we stop now? */ | ||
| 1716 | L = aadj; | ||
| 1717 | aadj -= L; | ||
| 1718 | /* The tolerances below are conservative. */ | ||
| 1719 | if (dsign || word1(rv) || word0(rv) & Bndry_mask) { | ||
| 1720 | if (aadj < .4999999 || aadj > .5000001) | ||
| 1721 | break; | ||
| 1722 | } | ||
| 1723 | else if (aadj < .4999999/FLT_RADIX) | ||
| 1724 | break; | ||
| 1725 | } | ||
| 1726 | cont: | ||
| 1727 | Bfree(bb); | ||
| 1728 | Bfree(bd); | ||
| 1729 | Bfree(bs); | ||
| 1730 | Bfree(delta); | ||
| 1731 | } | ||
| 1732 | retfree: | ||
| 1733 | Bfree(bb); | ||
| 1734 | Bfree(bd); | ||
| 1735 | Bfree(bs); | ||
| 1736 | Bfree(bd0); | ||
| 1737 | Bfree(delta); | ||
| 1738 | ret: | ||
| 1739 | if (se) | ||
| 1740 | *se = (char *)s; | ||
| 1741 | return sign ? -rv : rv; | ||
| 1742 | } | ||
| 1743 | |||
| 1744 | static int | ||
| 1745 | quorem | ||
| 1746 | #ifdef KR_headers | ||
| 1747 | (b, S) Bigint *b, *S; | ||
| 1748 | #else | ||
| 1749 | (Bigint *b, Bigint *S) | ||
| 1750 | #endif | ||
| 1751 | { | ||
| 1752 | int n; | ||
| 1753 | Long borrow, y; | ||
| 1754 | ULong carry, q, ys; | ||
| 1755 | ULong *bx, *bxe, *sx, *sxe; | ||
| 1756 | #ifdef Pack_32 | ||
| 1757 | Long z; | ||
| 1758 | ULong si, zs; | ||
| 1759 | #endif | ||
| 1760 | |||
| 1761 | n = S->wds; | ||
| 1762 | #ifdef DEBUG | ||
| 1763 | /*debug*/ if (b->wds > n) | ||
| 1764 | /*debug*/ Bug("oversize b in quorem"); | ||
| 1765 | #endif | ||
| 1766 | if (b->wds < n) | ||
| 1767 | return 0; | ||
| 1768 | sx = S->x; | ||
| 1769 | sxe = sx + --n; | ||
| 1770 | bx = b->x; | ||
| 1771 | bxe = bx + n; | ||
| 1772 | q = *bxe / (*sxe + 1); /* ensure q <= true quotient */ | ||
| 1773 | #ifdef DEBUG | ||
| 1774 | /*debug*/ if (q > 9) | ||
| 1775 | /*debug*/ Bug("oversized quotient in quorem"); | ||
| 1776 | #endif | ||
| 1777 | if (q) { | ||
| 1778 | borrow = 0; | ||
| 1779 | carry = 0; | ||
| 1780 | do { | ||
| 1781 | #ifdef Pack_32 | ||
| 1782 | si = *sx++; | ||
| 1783 | ys = (si & 0xffff) * q + carry; | ||
| 1784 | zs = (si >> 16) * q + (ys >> 16); | ||
| 1785 | carry = zs >> 16; | ||
| 1786 | y = (*bx & 0xffff) - (ys & 0xffff) + borrow; | ||
| 1787 | borrow = y >> 16; | ||
| 1788 | Sign_Extend(borrow, y); | ||
| 1789 | z = (*bx >> 16) - (zs & 0xffff) + borrow; | ||
| 1790 | borrow = z >> 16; | ||
| 1791 | Sign_Extend(borrow, z); | ||
| 1792 | Storeinc(bx, z, y); | ||
| 1793 | #else | ||
| 1794 | ys = *sx++ * q + carry; | ||
| 1795 | carry = ys >> 16; | ||
| 1796 | y = *bx - (ys & 0xffff) + borrow; | ||
| 1797 | borrow = y >> 16; | ||
| 1798 | Sign_Extend(borrow, y); | ||
| 1799 | *bx++ = y & 0xffff; | ||
| 1800 | #endif | ||
| 1801 | } | ||
| 1802 | while(sx <= sxe); | ||
| 1803 | if (!*bxe) { | ||
| 1804 | bx = b->x; | ||
| 1805 | while(--bxe > bx && !*bxe) | ||
| 1806 | --n; | ||
| 1807 | b->wds = n; | ||
| 1808 | } | ||
| 1809 | } | ||
| 1810 | if (cmp(b, S) >= 0) { | ||
| 1811 | q++; | ||
| 1812 | borrow = 0; | ||
| 1813 | carry = 0; | ||
| 1814 | bx = b->x; | ||
| 1815 | sx = S->x; | ||
| 1816 | do { | ||
| 1817 | #ifdef Pack_32 | ||
| 1818 | si = *sx++; | ||
| 1819 | ys = (si & 0xffff) + carry; | ||
| 1820 | zs = (si >> 16) + (ys >> 16); | ||
| 1821 | carry = zs >> 16; | ||
| 1822 | y = (*bx & 0xffff) - (ys & 0xffff) + borrow; | ||
| 1823 | borrow = y >> 16; | ||
| 1824 | Sign_Extend(borrow, y); | ||
| 1825 | z = (*bx >> 16) - (zs & 0xffff) + borrow; | ||
| 1826 | borrow = z >> 16; | ||
| 1827 | Sign_Extend(borrow, z); | ||
| 1828 | Storeinc(bx, z, y); | ||
| 1829 | #else | ||
| 1830 | ys = *sx++ + carry; | ||
| 1831 | carry = ys >> 16; | ||
| 1832 | y = *bx - (ys & 0xffff) + borrow; | ||
| 1833 | borrow = y >> 16; | ||
| 1834 | Sign_Extend(borrow, y); | ||
| 1835 | *bx++ = y & 0xffff; | ||
| 1836 | #endif | ||
| 1837 | } | ||
| 1838 | while(sx <= sxe); | ||
| 1839 | bx = b->x; | ||
| 1840 | bxe = bx + n; | ||
| 1841 | if (!*bxe) { | ||
| 1842 | while(--bxe > bx && !*bxe) | ||
| 1843 | --n; | ||
| 1844 | b->wds = n; | ||
| 1845 | } | ||
| 1846 | } | ||
| 1847 | return q; | ||
| 1848 | } | ||
| 1849 | |||
| 1850 | /* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. | ||
| 1851 | * | ||
| 1852 | * Inspired by "How to Print Floating-Point Numbers Accurately" by | ||
| 1853 | * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101]. | ||
| 1854 | * | ||
| 1855 | * Modifications: | ||
| 1856 | * 1. Rather than iterating, we use a simple numeric overestimate | ||
| 1857 | * to determine k = floor(log10(d)). We scale relevant | ||
| 1858 | * quantities using O(log2(k)) rather than O(k) multiplications. | ||
| 1859 | * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't | ||
| 1860 | * try to generate digits strictly left to right. Instead, we | ||
| 1861 | * compute with fewer bits and propagate the carry if necessary | ||
| 1862 | * when rounding the final digit up. This is often faster. | ||
| 1863 | * 3. Under the assumption that input will be rounded nearest, | ||
| 1864 | * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22. | ||
| 1865 | * That is, we allow equality in stopping tests when the | ||
| 1866 | * round-nearest rule will give the same floating-point value | ||
| 1867 | * as would satisfaction of the stopping test with strict | ||
| 1868 | * inequality. | ||
| 1869 | * 4. We remove common factors of powers of 2 from relevant | ||
| 1870 | * quantities. | ||
| 1871 | * 5. When converting floating-point integers less than 1e16, | ||
| 1872 | * we use floating-point arithmetic rather than resorting | ||
| 1873 | * to multiple-precision integers. | ||
| 1874 | * 6. When asked to produce fewer than 15 digits, we first try | ||
| 1875 | * to get by with floating-point arithmetic; we resort to | ||
| 1876 | * multiple-precision integer arithmetic only if we cannot | ||
| 1877 | * guarantee that the floating-point calculation has given | ||
| 1878 | * the correctly rounded result. For k requested digits and | ||
| 1879 | * "uniformly" distributed input, the probability is | ||
| 1880 | * something like 10^(k-15) that we must resort to the Long | ||
| 1881 | * calculation. | ||
| 1882 | */ | ||
| 1883 | |||
| 1884 | char * | ||
| 1885 | __dtoa | ||
| 1886 | #ifdef KR_headers | ||
| 1887 | (d, mode, ndigits, decpt, sign, rve) | ||
| 1888 | double d; int mode, ndigits, *decpt, *sign; char **rve; | ||
| 1889 | #else | ||
| 1890 | (double d, int mode, int ndigits, int *decpt, int *sign, char **rve) | ||
| 1891 | #endif | ||
| 1892 | { | ||
| 1893 | /* Arguments ndigits, decpt, sign are similar to those | ||
| 1894 | of ecvt and fcvt; trailing zeros are suppressed from | ||
| 1895 | the returned string. If not null, *rve is set to point | ||
| 1896 | to the end of the return value. If d is +-Infinity or NaN, | ||
| 1897 | then *decpt is set to 9999. | ||
| 1898 | |||
| 1899 | mode: | ||
| 1900 | 0 ==> shortest string that yields d when read in | ||
| 1901 | and rounded to nearest. | ||
| 1902 | 1 ==> like 0, but with Steele & White stopping rule; | ||
| 1903 | e.g. with IEEE P754 arithmetic , mode 0 gives | ||
| 1904 | 1e23 whereas mode 1 gives 9.999999999999999e22. | ||
| 1905 | 2 ==> max(1,ndigits) significant digits. This gives a | ||
| 1906 | return value similar to that of ecvt, except | ||
| 1907 | that trailing zeros are suppressed. | ||
| 1908 | 3 ==> through ndigits past the decimal point. This | ||
| 1909 | gives a return value similar to that from fcvt, | ||
| 1910 | except that trailing zeros are suppressed, and | ||
| 1911 | ndigits can be negative. | ||
| 1912 | 4-9 should give the same return values as 2-3, i.e., | ||
| 1913 | 4 <= mode <= 9 ==> same return as mode | ||
| 1914 | 2 + (mode & 1). These modes are mainly for | ||
| 1915 | debugging; often they run slower but sometimes | ||
| 1916 | faster than modes 2-3. | ||
| 1917 | 4,5,8,9 ==> left-to-right digit generation. | ||
| 1918 | 6-9 ==> don't try fast floating-point estimate | ||
| 1919 | (if applicable). | ||
| 1920 | |||
| 1921 | Values of mode other than 0-9 are treated as mode 0. | ||
| 1922 | |||
| 1923 | Sufficient space is allocated to the return value | ||
| 1924 | to hold the suppressed trailing zeros. | ||
| 1925 | */ | ||
| 1926 | |||
| 1927 | int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1, | ||
| 1928 | j, j1, k, k0, k_check, leftright, m2, m5, s2, s5, | ||
| 1929 | spec_case, try_quick; | ||
| 1930 | Long L; | ||
| 1931 | #ifndef Sudden_Underflow | ||
| 1932 | int denorm; | ||
| 1933 | ULong x; | ||
| 1934 | #endif | ||
| 1935 | Bigint *b, *b1, *delta, *mlo, *mhi, *S; | ||
| 1936 | double d2, ds, eps; | ||
| 1937 | char *s, *s0; | ||
| 1938 | static Bigint *result; | ||
| 1939 | static int result_k; | ||
| 1940 | |||
| 1941 | if (result) { | ||
| 1942 | result->k = result_k; | ||
| 1943 | result->maxwds = 1 << result_k; | ||
| 1944 | Bfree(result); | ||
| 1945 | result = 0; | ||
| 1946 | } | ||
| 1947 | |||
| 1948 | if (word0(d) & Sign_bit) { | ||
| 1949 | /* set sign for everything, including 0's and NaNs */ | ||
| 1950 | *sign = 1; | ||
| 1951 | word0(d) &= ~Sign_bit; /* clear sign bit */ | ||
| 1952 | } | ||
| 1953 | else | ||
| 1954 | *sign = 0; | ||
| 1955 | |||
| 1956 | #if defined(IEEE_Arith) + defined(VAX) | ||
| 1957 | #ifdef IEEE_Arith | ||
| 1958 | if ((word0(d) & Exp_mask) == Exp_mask) | ||
| 1959 | #else | ||
| 1960 | if (word0(d) == 0x8000) | ||
| 1961 | #endif | ||
| 1962 | { | ||
| 1963 | /* Infinity or NaN */ | ||
| 1964 | *decpt = 9999; | ||
| 1965 | s = | ||
| 1966 | #ifdef IEEE_Arith | ||
| 1967 | !word1(d) && !(word0(d) & 0xfffff) ? "Infinity" : | ||
| 1968 | #endif | ||
| 1969 | "NaN"; | ||
| 1970 | if (rve) | ||
| 1971 | *rve = | ||
| 1972 | #ifdef IEEE_Arith | ||
| 1973 | s[3] ? s + 8 : | ||
| 1974 | #endif | ||
| 1975 | s + 3; | ||
| 1976 | return s; | ||
| 1977 | } | ||
| 1978 | #endif | ||
| 1979 | #ifdef IBM | ||
| 1980 | d += 0; /* normalize */ | ||
| 1981 | #endif | ||
| 1982 | if (!d) { | ||
| 1983 | *decpt = 1; | ||
| 1984 | s = "0"; | ||
| 1985 | if (rve) | ||
| 1986 | *rve = s + 1; | ||
| 1987 | return s; | ||
| 1988 | } | ||
| 1989 | |||
| 1990 | b = d2b(d, &be, &bbits); | ||
| 1991 | #ifdef Sudden_Underflow | ||
| 1992 | i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); | ||
| 1993 | #else | ||
| 1994 | if (i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) { | ||
| 1995 | #endif | ||
| 1996 | d2 = d; | ||
| 1997 | word0(d2) &= Frac_mask1; | ||
| 1998 | word0(d2) |= Exp_11; | ||
| 1999 | #ifdef IBM | ||
| 2000 | if (j = 11 - hi0bits(word0(d2) & Frac_mask)) | ||
| 2001 | d2 /= 1 << j; | ||
| 2002 | #endif | ||
| 2003 | |||
| 2004 | /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 | ||
| 2005 | * log10(x) = log(x) / log(10) | ||
| 2006 | * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) | ||
| 2007 | * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) | ||
| 2008 | * | ||
| 2009 | * This suggests computing an approximation k to log10(d) by | ||
| 2010 | * | ||
| 2011 | * k = (i - Bias)*0.301029995663981 | ||
| 2012 | * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); | ||
| 2013 | * | ||
| 2014 | * We want k to be too large rather than too small. | ||
| 2015 | * The error in the first-order Taylor series approximation | ||
| 2016 | * is in our favor, so we just round up the constant enough | ||
| 2017 | * to compensate for any error in the multiplication of | ||
| 2018 | * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, | ||
| 2019 | * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, | ||
| 2020 | * adding 1e-13 to the constant term more than suffices. | ||
| 2021 | * Hence we adjust the constant term to 0.1760912590558. | ||
| 2022 | * (We could get a more accurate k by invoking log10, | ||
| 2023 | * but this is probably not worthwhile.) | ||
| 2024 | */ | ||
| 2025 | |||
| 2026 | i -= Bias; | ||
| 2027 | #ifdef IBM | ||
| 2028 | i <<= 2; | ||
| 2029 | i += j; | ||
| 2030 | #endif | ||
| 2031 | #ifndef Sudden_Underflow | ||
| 2032 | denorm = 0; | ||
| 2033 | } | ||
| 2034 | else { | ||
| 2035 | /* d is denormalized */ | ||
| 2036 | |||
| 2037 | i = bbits + be + (Bias + (P-1) - 1); | ||
| 2038 | x = i > 32 ? word0(d) << 64 - i | word1(d) >> i - 32 | ||
| 2039 | : word1(d) << 32 - i; | ||
| 2040 | d2 = x; | ||
| 2041 | word0(d2) -= 31*Exp_msk1; /* adjust exponent */ | ||
| 2042 | i -= (Bias + (P-1) - 1) + 1; | ||
| 2043 | denorm = 1; | ||
| 2044 | } | ||
| 2045 | #endif | ||
| 2046 | ds = (d2-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; | ||
| 2047 | k = (int)ds; | ||
| 2048 | if (ds < 0. && ds != k) | ||
| 2049 | k--; /* want k = floor(ds) */ | ||
| 2050 | k_check = 1; | ||
| 2051 | if (k >= 0 && k <= Ten_pmax) { | ||
| 2052 | if (d < tens[k]) | ||
| 2053 | k--; | ||
| 2054 | k_check = 0; | ||
| 2055 | } | ||
| 2056 | j = bbits - i - 1; | ||
| 2057 | if (j >= 0) { | ||
| 2058 | b2 = 0; | ||
| 2059 | s2 = j; | ||
| 2060 | } | ||
| 2061 | else { | ||
| 2062 | b2 = -j; | ||
| 2063 | s2 = 0; | ||
| 2064 | } | ||
| 2065 | if (k >= 0) { | ||
| 2066 | b5 = 0; | ||
| 2067 | s5 = k; | ||
| 2068 | s2 += k; | ||
| 2069 | } | ||
| 2070 | else { | ||
| 2071 | b2 -= k; | ||
| 2072 | b5 = -k; | ||
| 2073 | s5 = 0; | ||
| 2074 | } | ||
| 2075 | if (mode < 0 || mode > 9) | ||
| 2076 | mode = 0; | ||
| 2077 | try_quick = 1; | ||
| 2078 | if (mode > 5) { | ||
| 2079 | mode -= 4; | ||
| 2080 | try_quick = 0; | ||
| 2081 | } | ||
| 2082 | leftright = 1; | ||
| 2083 | switch(mode) { | ||
| 2084 | case 0: | ||
| 2085 | case 1: | ||
| 2086 | ilim = ilim1 = -1; | ||
| 2087 | i = 18; | ||
| 2088 | ndigits = 0; | ||
| 2089 | break; | ||
| 2090 | case 2: | ||
| 2091 | leftright = 0; | ||
| 2092 | /* no break */ | ||
| 2093 | case 4: | ||
| 2094 | if (ndigits <= 0) | ||
| 2095 | ndigits = 1; | ||
| 2096 | ilim = ilim1 = i = ndigits; | ||
| 2097 | break; | ||
| 2098 | case 3: | ||
| 2099 | leftright = 0; | ||
| 2100 | /* no break */ | ||
| 2101 | case 5: | ||
| 2102 | i = ndigits + k + 1; | ||
| 2103 | ilim = i; | ||
| 2104 | ilim1 = i - 1; | ||
| 2105 | if (i <= 0) | ||
| 2106 | i = 1; | ||
| 2107 | } | ||
| 2108 | j = sizeof(ULong); | ||
| 2109 | for(result_k = 0; sizeof(Bigint) - sizeof(ULong) + j <= i; | ||
| 2110 | j <<= 1) result_k++; | ||
| 2111 | result = Balloc(result_k); | ||
| 2112 | s = s0 = (char *)result; | ||
| 2113 | |||
| 2114 | if (ilim >= 0 && ilim <= Quick_max && try_quick) { | ||
| 2115 | |||
| 2116 | /* Try to get by with floating-point arithmetic. */ | ||
| 2117 | |||
| 2118 | i = 0; | ||
| 2119 | d2 = d; | ||
| 2120 | k0 = k; | ||
| 2121 | ilim0 = ilim; | ||
| 2122 | ieps = 2; /* conservative */ | ||
| 2123 | if (k > 0) { | ||
| 2124 | ds = tens[k&0xf]; | ||
| 2125 | j = k >> 4; | ||
| 2126 | if (j & Bletch) { | ||
| 2127 | /* prevent overflows */ | ||
| 2128 | j &= Bletch - 1; | ||
| 2129 | d /= bigtens[n_bigtens-1]; | ||
| 2130 | ieps++; | ||
| 2131 | } | ||
| 2132 | for(; j; j >>= 1, i++) | ||
| 2133 | if (j & 1) { | ||
| 2134 | ieps++; | ||
| 2135 | ds *= bigtens[i]; | ||
| 2136 | } | ||
| 2137 | d /= ds; | ||
| 2138 | } | ||
| 2139 | else if (j1 = -k) { | ||
| 2140 | d *= tens[j1 & 0xf]; | ||
| 2141 | for(j = j1 >> 4; j; j >>= 1, i++) | ||
| 2142 | if (j & 1) { | ||
| 2143 | ieps++; | ||
| 2144 | d *= bigtens[i]; | ||
| 2145 | } | ||
| 2146 | } | ||
| 2147 | if (k_check && d < 1. && ilim > 0) { | ||
| 2148 | if (ilim1 <= 0) | ||
| 2149 | goto fast_failed; | ||
| 2150 | ilim = ilim1; | ||
| 2151 | k--; | ||
| 2152 | d *= 10.; | ||
| 2153 | ieps++; | ||
| 2154 | } | ||
| 2155 | eps = ieps*d + 7.; | ||
| 2156 | word0(eps) -= (P-1)*Exp_msk1; | ||
| 2157 | if (ilim == 0) { | ||
| 2158 | S = mhi = 0; | ||
| 2159 | d -= 5.; | ||
| 2160 | if (d > eps) | ||
| 2161 | goto one_digit; | ||
| 2162 | if (d < -eps) | ||
| 2163 | goto no_digits; | ||
| 2164 | goto fast_failed; | ||
| 2165 | } | ||
| 2166 | #ifndef No_leftright | ||
| 2167 | if (leftright) { | ||
| 2168 | /* Use Steele & White method of only | ||
| 2169 | * generating digits needed. | ||
| 2170 | */ | ||
| 2171 | eps = 0.5/tens[ilim-1] - eps; | ||
| 2172 | for(i = 0;;) { | ||
| 2173 | L = d; | ||
| 2174 | d -= L; | ||
| 2175 | *s++ = '0' + (int)L; | ||
| 2176 | if (d < eps) | ||
| 2177 | goto ret1; | ||
| 2178 | if (1. - d < eps) | ||
| 2179 | goto bump_up; | ||
| 2180 | if (++i >= ilim) | ||
| 2181 | break; | ||
| 2182 | eps *= 10.; | ||
| 2183 | d *= 10.; | ||
| 2184 | } | ||
| 2185 | } | ||
| 2186 | else { | ||
| 2187 | #endif | ||
| 2188 | /* Generate ilim digits, then fix them up. */ | ||
| 2189 | eps *= tens[ilim-1]; | ||
| 2190 | for(i = 1;; i++, d *= 10.) { | ||
| 2191 | L = d; | ||
| 2192 | d -= L; | ||
| 2193 | *s++ = '0' + (int)L; | ||
| 2194 | if (i == ilim) { | ||
| 2195 | if (d > 0.5 + eps) | ||
| 2196 | goto bump_up; | ||
| 2197 | else if (d < 0.5 - eps) { | ||
| 2198 | while(*--s == '0'); | ||
| 2199 | s++; | ||
| 2200 | goto ret1; | ||
| 2201 | } | ||
| 2202 | break; | ||
| 2203 | } | ||
| 2204 | } | ||
| 2205 | #ifndef No_leftright | ||
| 2206 | } | ||
| 2207 | #endif | ||
| 2208 | fast_failed: | ||
| 2209 | s = s0; | ||
| 2210 | d = d2; | ||
| 2211 | k = k0; | ||
| 2212 | ilim = ilim0; | ||
| 2213 | } | ||
| 2214 | |||
| 2215 | /* Do we have a "small" integer? */ | ||
| 2216 | |||
| 2217 | if (be >= 0 && k <= Int_max) { | ||
| 2218 | /* Yes. */ | ||
| 2219 | ds = tens[k]; | ||
| 2220 | if (ndigits < 0 && ilim <= 0) { | ||
| 2221 | S = mhi = 0; | ||
| 2222 | if (ilim < 0 || d <= 5*ds) | ||
| 2223 | goto no_digits; | ||
| 2224 | goto one_digit; | ||
| 2225 | } | ||
| 2226 | for(i = 1;; i++) { | ||
| 2227 | L = d / ds; | ||
| 2228 | d -= L*ds; | ||
| 2229 | #ifdef Check_FLT_ROUNDS | ||
| 2230 | /* If FLT_ROUNDS == 2, L will usually be high by 1 */ | ||
| 2231 | if (d < 0) { | ||
| 2232 | L--; | ||
| 2233 | d += ds; | ||
| 2234 | } | ||
| 2235 | #endif | ||
| 2236 | *s++ = '0' + (int)L; | ||
| 2237 | if (i == ilim) { | ||
| 2238 | d += d; | ||
| 2239 | if (d > ds || d == ds && L & 1) { | ||
| 2240 | bump_up: | ||
| 2241 | while(*--s == '9') | ||
| 2242 | if (s == s0) { | ||
| 2243 | k++; | ||
| 2244 | *s = '0'; | ||
| 2245 | break; | ||
| 2246 | } | ||
| 2247 | ++*s++; | ||
| 2248 | } | ||
| 2249 | break; | ||
| 2250 | } | ||
| 2251 | if (!(d *= 10.)) | ||
| 2252 | break; | ||
| 2253 | } | ||
| 2254 | goto ret1; | ||
| 2255 | } | ||
| 2256 | |||
| 2257 | m2 = b2; | ||
| 2258 | m5 = b5; | ||
| 2259 | mhi = mlo = 0; | ||
| 2260 | if (leftright) { | ||
| 2261 | if (mode < 2) { | ||
| 2262 | i = | ||
| 2263 | #ifndef Sudden_Underflow | ||
| 2264 | denorm ? be + (Bias + (P-1) - 1 + 1) : | ||
| 2265 | #endif | ||
| 2266 | #ifdef IBM | ||
| 2267 | 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3); | ||
| 2268 | #else | ||
| 2269 | 1 + P - bbits; | ||
| 2270 | #endif | ||
| 2271 | } | ||
| 2272 | else { | ||
| 2273 | j = ilim - 1; | ||
| 2274 | if (m5 >= j) | ||
| 2275 | m5 -= j; | ||
| 2276 | else { | ||
| 2277 | s5 += j -= m5; | ||
| 2278 | b5 += j; | ||
| 2279 | m5 = 0; | ||
| 2280 | } | ||
| 2281 | if ((i = ilim) < 0) { | ||
| 2282 | m2 -= i; | ||
| 2283 | i = 0; | ||
| 2284 | } | ||
| 2285 | } | ||
| 2286 | b2 += i; | ||
| 2287 | s2 += i; | ||
| 2288 | mhi = i2b(1); | ||
| 2289 | } | ||
| 2290 | if (m2 > 0 && s2 > 0) { | ||
| 2291 | i = m2 < s2 ? m2 : s2; | ||
| 2292 | b2 -= i; | ||
| 2293 | m2 -= i; | ||
| 2294 | s2 -= i; | ||
| 2295 | } | ||
| 2296 | if (b5 > 0) { | ||
| 2297 | if (leftright) { | ||
| 2298 | if (m5 > 0) { | ||
| 2299 | mhi = pow5mult(mhi, m5); | ||
| 2300 | b1 = mult(mhi, b); | ||
| 2301 | Bfree(b); | ||
| 2302 | b = b1; | ||
| 2303 | } | ||
| 2304 | if (j = b5 - m5) | ||
| 2305 | b = pow5mult(b, j); | ||
| 2306 | } | ||
| 2307 | else | ||
| 2308 | b = pow5mult(b, b5); | ||
| 2309 | } | ||
| 2310 | S = i2b(1); | ||
| 2311 | if (s5 > 0) | ||
| 2312 | S = pow5mult(S, s5); | ||
| 2313 | |||
| 2314 | /* Check for special case that d is a normalized power of 2. */ | ||
| 2315 | |||
| 2316 | if (mode < 2) { | ||
| 2317 | if (!word1(d) && !(word0(d) & Bndry_mask) | ||
| 2318 | #ifndef Sudden_Underflow | ||
| 2319 | && word0(d) & Exp_mask | ||
| 2320 | #endif | ||
| 2321 | ) { | ||
| 2322 | /* The special case */ | ||
| 2323 | b2 += Log2P; | ||
| 2324 | s2 += Log2P; | ||
| 2325 | spec_case = 1; | ||
| 2326 | } | ||
| 2327 | else | ||
| 2328 | spec_case = 0; | ||
| 2329 | } | ||
| 2330 | |||
| 2331 | /* Arrange for convenient computation of quotients: | ||
| 2332 | * shift left if necessary so divisor has 4 leading 0 bits. | ||
| 2333 | * | ||
| 2334 | * Perhaps we should just compute leading 28 bits of S once | ||
| 2335 | * and for all and pass them and a shift to quorem, so it | ||
| 2336 | * can do shifts and ors to compute the numerator for q. | ||
| 2337 | */ | ||
| 2338 | #ifdef Pack_32 | ||
| 2339 | if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f) | ||
| 2340 | i = 32 - i; | ||
| 2341 | #else | ||
| 2342 | if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf) | ||
| 2343 | i = 16 - i; | ||
| 2344 | #endif | ||
| 2345 | if (i > 4) { | ||
| 2346 | i -= 4; | ||
| 2347 | b2 += i; | ||
| 2348 | m2 += i; | ||
| 2349 | s2 += i; | ||
| 2350 | } | ||
| 2351 | else if (i < 4) { | ||
| 2352 | i += 28; | ||
| 2353 | b2 += i; | ||
| 2354 | m2 += i; | ||
| 2355 | s2 += i; | ||
| 2356 | } | ||
| 2357 | if (b2 > 0) | ||
| 2358 | b = lshift(b, b2); | ||
| 2359 | if (s2 > 0) | ||
| 2360 | S = lshift(S, s2); | ||
| 2361 | if (k_check) { | ||
| 2362 | if (cmp(b,S) < 0) { | ||
| 2363 | k--; | ||
| 2364 | b = multadd(b, 10, 0); /* we botched the k estimate */ | ||
| 2365 | if (leftright) | ||
| 2366 | mhi = multadd(mhi, 10, 0); | ||
| 2367 | ilim = ilim1; | ||
| 2368 | } | ||
| 2369 | } | ||
| 2370 | if (ilim <= 0 && mode > 2) { | ||
| 2371 | if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) { | ||
| 2372 | /* no digits, fcvt style */ | ||
| 2373 | no_digits: | ||
| 2374 | k = -1 - ndigits; | ||
| 2375 | goto ret; | ||
| 2376 | } | ||
| 2377 | one_digit: | ||
| 2378 | *s++ = '1'; | ||
| 2379 | k++; | ||
| 2380 | goto ret; | ||
| 2381 | } | ||
| 2382 | if (leftright) { | ||
| 2383 | if (m2 > 0) | ||
| 2384 | mhi = lshift(mhi, m2); | ||
| 2385 | |||
| 2386 | /* Compute mlo -- check for special case | ||
| 2387 | * that d is a normalized power of 2. | ||
| 2388 | */ | ||
| 2389 | |||
| 2390 | mlo = mhi; | ||
| 2391 | if (spec_case) { | ||
| 2392 | mhi = Balloc(mhi->k); | ||
| 2393 | Bcopy(mhi, mlo); | ||
| 2394 | mhi = lshift(mhi, Log2P); | ||
| 2395 | } | ||
| 2396 | |||
| 2397 | for(i = 1;;i++) { | ||
| 2398 | dig = quorem(b,S) + '0'; | ||
| 2399 | /* Do we yet have the shortest decimal string | ||
| 2400 | * that will round to d? | ||
| 2401 | */ | ||
| 2402 | j = cmp(b, mlo); | ||
| 2403 | delta = diff(S, mhi); | ||
| 2404 | j1 = delta->sign ? 1 : cmp(b, delta); | ||
| 2405 | Bfree(delta); | ||
| 2406 | #ifndef ROUND_BIASED | ||
| 2407 | if (j1 == 0 && !mode && !(word1(d) & 1)) { | ||
| 2408 | if (dig == '9') | ||
| 2409 | goto round_9_up; | ||
| 2410 | if (j > 0) | ||
| 2411 | dig++; | ||
| 2412 | *s++ = dig; | ||
| 2413 | goto ret; | ||
| 2414 | } | ||
| 2415 | #endif | ||
| 2416 | if (j < 0 || j == 0 && !mode | ||
| 2417 | #ifndef ROUND_BIASED | ||
| 2418 | && !(word1(d) & 1) | ||
| 2419 | #endif | ||
| 2420 | ) { | ||
| 2421 | if (j1 > 0) { | ||
| 2422 | b = lshift(b, 1); | ||
| 2423 | j1 = cmp(b, S); | ||
| 2424 | if ((j1 > 0 || j1 == 0 && dig & 1) | ||
| 2425 | && dig++ == '9') | ||
| 2426 | goto round_9_up; | ||
| 2427 | } | ||
| 2428 | *s++ = dig; | ||
| 2429 | goto ret; | ||
| 2430 | } | ||
| 2431 | if (j1 > 0) { | ||
| 2432 | if (dig == '9') { /* possible if i == 1 */ | ||
| 2433 | round_9_up: | ||
| 2434 | *s++ = '9'; | ||
| 2435 | goto roundoff; | ||
| 2436 | } | ||
| 2437 | *s++ = dig + 1; | ||
| 2438 | goto ret; | ||
| 2439 | } | ||
| 2440 | *s++ = dig; | ||
| 2441 | if (i == ilim) | ||
| 2442 | break; | ||
| 2443 | b = multadd(b, 10, 0); | ||
| 2444 | if (mlo == mhi) | ||
| 2445 | mlo = mhi = multadd(mhi, 10, 0); | ||
| 2446 | else { | ||
| 2447 | mlo = multadd(mlo, 10, 0); | ||
| 2448 | mhi = multadd(mhi, 10, 0); | ||
| 2449 | } | ||
| 2450 | } | ||
| 2451 | } | ||
| 2452 | else | ||
| 2453 | for(i = 1;; i++) { | ||
| 2454 | *s++ = dig = quorem(b,S) + '0'; | ||
| 2455 | if (i >= ilim) | ||
| 2456 | break; | ||
| 2457 | b = multadd(b, 10, 0); | ||
| 2458 | } | ||
| 2459 | |||
| 2460 | /* Round off last digit */ | ||
| 2461 | |||
| 2462 | b = lshift(b, 1); | ||
| 2463 | j = cmp(b, S); | ||
| 2464 | if (j > 0 || j == 0 && dig & 1) { | ||
| 2465 | roundoff: | ||
| 2466 | while(*--s == '9') | ||
| 2467 | if (s == s0) { | ||
| 2468 | k++; | ||
| 2469 | *s++ = '1'; | ||
| 2470 | goto ret; | ||
| 2471 | } | ||
| 2472 | ++*s++; | ||
| 2473 | } | ||
| 2474 | else { | ||
| 2475 | while(*--s == '0'); | ||
| 2476 | s++; | ||
| 2477 | } | ||
| 2478 | ret: | ||
| 2479 | Bfree(S); | ||
| 2480 | if (mhi) { | ||
| 2481 | if (mlo && mlo != mhi) | ||
| 2482 | Bfree(mlo); | ||
| 2483 | Bfree(mhi); | ||
| 2484 | } | ||
| 2485 | ret1: | ||
| 2486 | Bfree(b); | ||
| 2487 | if (s == s0) { /* don't return empty string */ | ||
| 2488 | *s++ = '0'; | ||
| 2489 | k = 0; | ||
| 2490 | } | ||
| 2491 | *s = 0; | ||
| 2492 | *decpt = k + 1; | ||
| 2493 | if (rve) | ||
| 2494 | *rve = s; | ||
| 2495 | return s0; | ||
| 2496 | } | ||
| 2497 | #ifdef __cplusplus | ||
| 2498 | } | ||
| 2499 | #endif | ||
diff --git a/src/lib/libc/stdlib/strtoimax.c b/src/lib/libc/stdlib/strtoimax.c new file mode 100644 index 0000000000..2c77f41650 --- /dev/null +++ b/src/lib/libc/stdlib/strtoimax.c | |||
| @@ -0,0 +1,140 @@ | |||
| 1 | /* $OpenBSD: strtoimax.c,v 1.1 2006/01/13 17:58:09 millert Exp $ */ | ||
| 2 | |||
| 3 | /*- | ||
| 4 | * Copyright (c) 1992 The Regents of the University of California. | ||
| 5 | * All rights reserved. | ||
| 6 | * | ||
| 7 | * Redistribution and use in source and binary forms, with or without | ||
| 8 | * modification, are permitted provided that the following conditions | ||
| 9 | * are met: | ||
| 10 | * 1. Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 13 | * notice, this list of conditions and the following disclaimer in the | ||
| 14 | * documentation and/or other materials provided with the distribution. | ||
| 15 | * 3. Neither the name of the University nor the names of its contributors | ||
| 16 | * may be used to endorse or promote products derived from this software | ||
| 17 | * without specific prior written permission. | ||
| 18 | * | ||
| 19 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
| 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
| 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 29 | * SUCH DAMAGE. | ||
| 30 | */ | ||
| 31 | |||
| 32 | #include <ctype.h> | ||
| 33 | #include <errno.h> | ||
| 34 | #include <inttypes.h> | ||
| 35 | |||
| 36 | /* | ||
| 37 | * Convert a string to an intmax_t | ||
| 38 | * | ||
| 39 | * Ignores `locale' stuff. Assumes that the upper and lower case | ||
| 40 | * alphabets and digits are each contiguous. | ||
| 41 | */ | ||
| 42 | intmax_t | ||
| 43 | strtoimax(const char *nptr, char **endptr, int base) | ||
| 44 | { | ||
| 45 | const char *s; | ||
| 46 | intmax_t acc, cutoff; | ||
| 47 | int c; | ||
| 48 | int neg, any, cutlim; | ||
| 49 | |||
| 50 | /* | ||
| 51 | * Skip white space and pick up leading +/- sign if any. | ||
| 52 | * If base is 0, allow 0x for hex and 0 for octal, else | ||
| 53 | * assume decimal; if base is already 16, allow 0x. | ||
| 54 | */ | ||
| 55 | s = nptr; | ||
| 56 | do { | ||
| 57 | c = (unsigned char) *s++; | ||
| 58 | } while (isspace(c)); | ||
| 59 | if (c == '-') { | ||
| 60 | neg = 1; | ||
| 61 | c = *s++; | ||
| 62 | } else { | ||
| 63 | neg = 0; | ||
| 64 | if (c == '+') | ||
| 65 | c = *s++; | ||
| 66 | } | ||
| 67 | if ((base == 0 || base == 16) && | ||
| 68 | c == '0' && (*s == 'x' || *s == 'X')) { | ||
| 69 | c = s[1]; | ||
| 70 | s += 2; | ||
| 71 | base = 16; | ||
| 72 | } | ||
| 73 | if (base == 0) | ||
| 74 | base = c == '0' ? 8 : 10; | ||
| 75 | |||
| 76 | /* | ||
| 77 | * Compute the cutoff value between legal numbers and illegal | ||
| 78 | * numbers. That is the largest legal value, divided by the | ||
| 79 | * base. An input number that is greater than this value, if | ||
| 80 | * followed by a legal input character, is too big. One that | ||
| 81 | * is equal to this value may be valid or not; the limit | ||
| 82 | * between valid and invalid numbers is then based on the last | ||
| 83 | * digit. For instance, if the range for intmax_t is | ||
| 84 | * [-9223372036854775808..9223372036854775807] and the input base | ||
| 85 | * is 10, cutoff will be set to 922337203685477580 and cutlim to | ||
| 86 | * either 7 (neg==0) or 8 (neg==1), meaning that if we have | ||
| 87 | * accumulated a value > 922337203685477580, or equal but the | ||
| 88 | * next digit is > 7 (or 8), the number is too big, and we will | ||
| 89 | * return a range error. | ||
| 90 | * | ||
| 91 | * Set any if any `digits' consumed; make it negative to indicate | ||
| 92 | * overflow. | ||
| 93 | */ | ||
| 94 | cutoff = neg ? INTMAX_MIN : INTMAX_MAX; | ||
| 95 | cutlim = cutoff % base; | ||
| 96 | cutoff /= base; | ||
| 97 | if (neg) { | ||
| 98 | if (cutlim > 0) { | ||
| 99 | cutlim -= base; | ||
| 100 | cutoff += 1; | ||
| 101 | } | ||
| 102 | cutlim = -cutlim; | ||
| 103 | } | ||
| 104 | for (acc = 0, any = 0;; c = (unsigned char) *s++) { | ||
| 105 | if (isdigit(c)) | ||
| 106 | c -= '0'; | ||
| 107 | else if (isalpha(c)) | ||
| 108 | c -= isupper(c) ? 'A' - 10 : 'a' - 10; | ||
| 109 | else | ||
| 110 | break; | ||
| 111 | if (c >= base) | ||
| 112 | break; | ||
| 113 | if (any < 0) | ||
| 114 | continue; | ||
| 115 | if (neg) { | ||
| 116 | if (acc < cutoff || (acc == cutoff && c > cutlim)) { | ||
| 117 | any = -1; | ||
| 118 | acc = INTMAX_MIN; | ||
| 119 | errno = ERANGE; | ||
| 120 | } else { | ||
| 121 | any = 1; | ||
| 122 | acc *= base; | ||
| 123 | acc -= c; | ||
| 124 | } | ||
| 125 | } else { | ||
| 126 | if (acc > cutoff || (acc == cutoff && c > cutlim)) { | ||
| 127 | any = -1; | ||
| 128 | acc = INTMAX_MAX; | ||
| 129 | errno = ERANGE; | ||
| 130 | } else { | ||
| 131 | any = 1; | ||
| 132 | acc *= base; | ||
| 133 | acc += c; | ||
| 134 | } | ||
| 135 | } | ||
| 136 | } | ||
| 137 | if (endptr != 0) | ||
| 138 | *endptr = (char *) (any ? s - 1 : nptr); | ||
| 139 | return (acc); | ||
| 140 | } | ||
diff --git a/src/lib/libc/stdlib/strtol.3 b/src/lib/libc/stdlib/strtol.3 index 808ba90165..c0a60979d9 100644 --- a/src/lib/libc/stdlib/strtol.3 +++ b/src/lib/libc/stdlib/strtol.3 | |||
| @@ -13,11 +13,7 @@ | |||
| 13 | .\" 2. Redistributions in binary form must reproduce the above copyright | 13 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 14 | .\" notice, this list of conditions and the following disclaimer in the | 14 | .\" notice, this list of conditions and the following disclaimer in the |
| 15 | .\" documentation and/or other materials provided with the distribution. | 15 | .\" documentation and/or other materials provided with the distribution. |
| 16 | .\" 3. All advertising materials mentioning features or use of this software | 16 | .\" 3. Neither the name of the University nor the names of its contributors |
| 17 | .\" must display the following acknowledgement: | ||
| 18 | .\" This product includes software developed by the University of | ||
| 19 | .\" California, Berkeley and its contributors. | ||
| 20 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 21 | .\" may be used to endorse or promote products derived from this software | 17 | .\" may be used to endorse or promote products derived from this software |
| 22 | .\" without specific prior written permission. | 18 | .\" without specific prior written permission. |
| 23 | .\" | 19 | .\" |
| @@ -33,49 +29,67 @@ | |||
| 33 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 29 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 34 | .\" SUCH DAMAGE. | 30 | .\" SUCH DAMAGE. |
| 35 | .\" | 31 | .\" |
| 36 | .\" from: @(#)strtol.3 5.4 (Berkeley) 6/25/92 | 32 | .\" $OpenBSD: strtol.3,v 1.24 2013/08/14 06:32:28 jmc Exp $ |
| 37 | .\" $Id: strtol.3,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $ | ||
| 38 | .\" | 33 | .\" |
| 39 | .Dd June 25, 1992 | 34 | .Dd $Mdocdate: August 14 2013 $ |
| 40 | .Dt STRTOL 3 | 35 | .Dt STRTOL 3 |
| 41 | .Os | 36 | .Os |
| 42 | .Sh NAME | 37 | .Sh NAME |
| 43 | .Nm strtol, strtoq | 38 | .Nm strtol , |
| 44 | .Nd convert string value to a long or quad_t integer | 39 | .Nm strtoll , |
| 40 | .Nm strtoimax , | ||
| 41 | .Nm strtoq , | ||
| 42 | .Nd convert string value to a long, long long or intmax_t integer | ||
| 45 | .Sh SYNOPSIS | 43 | .Sh SYNOPSIS |
| 46 | .Fd #include <stdlib.h> | 44 | .In limits.h |
| 47 | .Fd #include <limits.h> | 45 | .In stdlib.h |
| 48 | .Ft long | 46 | .Ft long |
| 49 | .Fn strtol "char *nptr" "char **endptr" "int base" | 47 | .Fn strtol "const char *nptr" "char **endptr" "int base" |
| 50 | 48 | .Pp | |
| 51 | .Fd #include <sys/types.h> | 49 | .Ft long long |
| 52 | .Fd #include <stdlib.h> | 50 | .Fn strtoll "const char *nptr" "char **endptr" "int base" |
| 53 | .Fd #include <limits.h> | 51 | .Pp |
| 52 | .In inttypes.h | ||
| 53 | .Ft intmax_t | ||
| 54 | .Fn strtoimax "const char *nptr" "char **endptr" "int base" | ||
| 55 | .Pp | ||
| 56 | .In sys/types.h | ||
| 57 | .In limits.h | ||
| 58 | .In stdlib.h | ||
| 54 | .Ft quad_t | 59 | .Ft quad_t |
| 55 | .Fn strtoq "char *nptr" "char **endptr" "int base" | 60 | .Fn strtoq "const char *nptr" "char **endptr" "int base" |
| 56 | .Sh DESCRIPTION | 61 | .Sh DESCRIPTION |
| 57 | The | 62 | The |
| 58 | .Fn strtol | 63 | .Fn strtol |
| 59 | function | 64 | function converts the string in |
| 60 | converts the string in | ||
| 61 | .Fa nptr | 65 | .Fa nptr |
| 62 | to a | 66 | to a |
| 63 | .Em long | 67 | .Li long |
| 64 | value. | 68 | value. |
| 65 | The | 69 | The |
| 66 | .Fn strtoq | 70 | .Fn strtoll |
| 67 | function | 71 | function converts the string in |
| 68 | converts the string in | ||
| 69 | .Fa nptr | 72 | .Fa nptr |
| 70 | to a | 73 | to a |
| 71 | .Em quad_t | 74 | .Li long long |
| 72 | value. | 75 | value. |
| 76 | The | ||
| 77 | .Fn strtoimax | ||
| 78 | function converts the string in | ||
| 79 | .Fa nptr | ||
| 80 | to an | ||
| 81 | .Li intmax_t | ||
| 82 | value. | ||
| 83 | The | ||
| 84 | .Fn strtoq | ||
| 85 | function is a deprecated equivalent of | ||
| 86 | .Fn strtoll | ||
| 87 | and is provided for backwards compatibility with legacy programs. | ||
| 73 | The conversion is done according to the given | 88 | The conversion is done according to the given |
| 74 | .Fa base , | 89 | .Fa base , |
| 75 | which must be between 2 and 36 inclusive, | 90 | which must be a number between 2 and 36 inclusive or the special value 0. |
| 76 | or be the special value 0. | ||
| 77 | .Pp | 91 | .Pp |
| 78 | The string may begin with an arbitrary amount of white space | 92 | The string may begin with an arbitrary amount of whitespace |
| 79 | (as determined by | 93 | (as determined by |
| 80 | .Xr isspace 3 ) | 94 | .Xr isspace 3 ) |
| 81 | followed by a single optional | 95 | followed by a single optional |
| @@ -85,25 +99,25 @@ or | |||
| 85 | sign. | 99 | sign. |
| 86 | If | 100 | If |
| 87 | .Fa base | 101 | .Fa base |
| 88 | is zero or 16, | 102 | is zero or 16, the string may then include a |
| 89 | the string may then include a | ||
| 90 | .Ql 0x | 103 | .Ql 0x |
| 91 | prefix, | 104 | prefix, and the number will be read in base 16; otherwise, a zero |
| 92 | and the number will be read in base 16; otherwise, a zero | ||
| 93 | .Fa base | 105 | .Fa base |
| 94 | is taken as 10 (decimal) unless the next character is | 106 | is taken as 10 (decimal) unless the next character is |
| 95 | .Ql 0 , | 107 | .Ql 0 , |
| 96 | in which case it is taken as 8 (octal). | 108 | in which case it is taken as 8 (octal). |
| 97 | .Pp | 109 | .Pp |
| 98 | The remainder of the string is converted to a | 110 | The remainder of the string is converted to a |
| 99 | .Em long | 111 | .Li long , |
| 112 | .Li long long , | ||
| 113 | or | ||
| 114 | .Li intmax_t , | ||
| 100 | value in the obvious manner, | 115 | value in the obvious manner, |
| 101 | stopping at the first character which is not a valid digit | 116 | stopping at the first character which is not a valid digit |
| 102 | in the given base. | 117 | in the given base. |
| 103 | (In bases above 10, the letter | 118 | (In bases above 10, the letter |
| 104 | .Ql A | 119 | .Ql A |
| 105 | in either upper or lower case | 120 | in either upper or lower case represents 10, |
| 106 | represents 10, | ||
| 107 | .Ql B | 121 | .Ql B |
| 108 | represents 11, and so forth, with | 122 | represents 11, and so forth, with |
| 109 | .Ql Z | 123 | .Ql Z |
| @@ -111,7 +125,7 @@ representing 35.) | |||
| 111 | .Pp | 125 | .Pp |
| 112 | If | 126 | If |
| 113 | .Fa endptr | 127 | .Fa endptr |
| 114 | is non nil, | 128 | is non-null, |
| 115 | .Fn strtol | 129 | .Fn strtol |
| 116 | stores the address of the first invalid character in | 130 | stores the address of the first invalid character in |
| 117 | .Fa *endptr . | 131 | .Fa *endptr . |
| @@ -132,22 +146,93 @@ is | |||
| 132 | on return, the entire string was valid.) | 146 | on return, the entire string was valid.) |
| 133 | .Sh RETURN VALUES | 147 | .Sh RETURN VALUES |
| 134 | The | 148 | The |
| 135 | .Fn strtol | 149 | .Fn strtol , |
| 136 | function | 150 | .Fn strtoll , |
| 137 | returns the result of the conversion, | 151 | .Fn strtoimax , |
| 152 | and | ||
| 153 | .Fn strtoq | ||
| 154 | functions return the result of the conversion, | ||
| 138 | unless the value would underflow or overflow. | 155 | unless the value would underflow or overflow. |
| 139 | If an underflow occurs, | 156 | If no conversion could be performed, 0 is returned; |
| 140 | .Fn strtol | 157 | the global variable |
| 141 | returns | 158 | .Va errno |
| 142 | .Dv LONG_MIN . | 159 | is also set to |
| 143 | If an overflow occurs, | 160 | .Er EINVAL , |
| 144 | .Fn strtol | 161 | though this is not portable across all platforms. |
| 145 | returns | 162 | If overflow or underflow occurs, |
| 146 | .Dv LONG_MAX . | ||
| 147 | In both cases, | ||
| 148 | .Va errno | 163 | .Va errno |
| 149 | is set to | 164 | is set to |
| 150 | .Er ERANGE . | 165 | .Er ERANGE |
| 166 | and the function return value is as follows: | ||
| 167 | .Bl -column "strtoimaxXX" "INTMAX_MIN" "INTMAX_MAX" -offset indent | ||
| 168 | .It Sy Function Ta Sy underflow Ta Sy overflow | ||
| 169 | .It Fn strtol Ta Dv LONG_MIN Ta Dv LONG_MAX | ||
| 170 | .It Fn strtoll Ta Dv LLONG_MIN Ta Dv LLONG_MAX | ||
| 171 | .It Fn strtoimax Ta Dv INTMAX_MIN Ta Dv INTMAX_MAX | ||
| 172 | .It Fn strtoq Ta Dv LLONG_MIN Ta Dv LLONG_MAX | ||
| 173 | .El | ||
| 174 | .Sh EXAMPLES | ||
| 175 | Ensuring that a string is a valid number (i.e., in range and containing no | ||
| 176 | trailing characters) requires clearing | ||
| 177 | .Va errno | ||
| 178 | beforehand explicitly since | ||
| 179 | .Va errno | ||
| 180 | is not changed on a successful call to | ||
| 181 | .Fn strtol , | ||
| 182 | and the return value of | ||
| 183 | .Fn strtol | ||
| 184 | cannot be used unambiguously to signal an error: | ||
| 185 | .Bd -literal -offset indent | ||
| 186 | char *ep; | ||
| 187 | long lval; | ||
| 188 | |||
| 189 | \&... | ||
| 190 | |||
| 191 | errno = 0; | ||
| 192 | lval = strtol(buf, &ep, 10); | ||
| 193 | if (buf[0] == '\e0' || *ep != '\e0') | ||
| 194 | goto not_a_number; | ||
| 195 | if (errno == ERANGE && (lval == LONG_MAX || lval == LONG_MIN)) | ||
| 196 | goto out_of_range; | ||
| 197 | .Ed | ||
| 198 | .Pp | ||
| 199 | This example will accept | ||
| 200 | .Dq 12 | ||
| 201 | but not | ||
| 202 | .Dq 12foo | ||
| 203 | or | ||
| 204 | .Dq 12\en . | ||
| 205 | If trailing whitespace is acceptable, further checks must be done on | ||
| 206 | .Va *ep ; | ||
| 207 | alternately, use | ||
| 208 | .Xr sscanf 3 . | ||
| 209 | .Pp | ||
| 210 | If | ||
| 211 | .Fn strtol | ||
| 212 | is being used instead of | ||
| 213 | .Xr atoi 3 , | ||
| 214 | error checking is further complicated because the desired return value is an | ||
| 215 | .Li int | ||
| 216 | rather than a | ||
| 217 | .Li long ; | ||
| 218 | however, on some architectures integers and long integers are the same size. | ||
| 219 | Thus the following is necessary: | ||
| 220 | .Bd -literal -offset indent | ||
| 221 | char *ep; | ||
| 222 | int ival; | ||
| 223 | long lval; | ||
| 224 | |||
| 225 | \&... | ||
| 226 | |||
| 227 | errno = 0; | ||
| 228 | lval = strtol(buf, &ep, 10); | ||
| 229 | if (buf[0] == '\e0' || *ep != '\e0') | ||
| 230 | goto not_a_number; | ||
| 231 | if ((errno == ERANGE && (lval == LONG_MAX || lval == LONG_MIN)) || | ||
| 232 | (lval > INT_MAX || lval < INT_MIN)) | ||
| 233 | goto out_of_range; | ||
| 234 | ival = lval; | ||
| 235 | .Ed | ||
| 151 | .Sh ERRORS | 236 | .Sh ERRORS |
| 152 | .Bl -tag -width Er | 237 | .Bl -tag -width Er |
| 153 | .It Bq Er ERANGE | 238 | .It Bq Er ERANGE |
| @@ -157,13 +242,23 @@ The given string was out of range; the value converted has been clamped. | |||
| 157 | .Xr atof 3 , | 242 | .Xr atof 3 , |
| 158 | .Xr atoi 3 , | 243 | .Xr atoi 3 , |
| 159 | .Xr atol 3 , | 244 | .Xr atol 3 , |
| 245 | .Xr atoll 3 , | ||
| 246 | .Xr sscanf 3 , | ||
| 160 | .Xr strtod 3 , | 247 | .Xr strtod 3 , |
| 248 | .Xr strtonum 3 , | ||
| 161 | .Xr strtoul 3 | 249 | .Xr strtoul 3 |
| 162 | .Sh STANDARDS | 250 | .Sh STANDARDS |
| 163 | The | 251 | The |
| 164 | .Fn strtol | 252 | .Fn strtol , |
| 165 | function | 253 | .Fn strtoll , |
| 166 | conforms to | 254 | and |
| 167 | .St -ansiC . | 255 | .Fn strtoimax |
| 256 | functions conform to | ||
| 257 | .St -ansiC-99 . | ||
| 258 | The | ||
| 259 | .Fn strtoq | ||
| 260 | function is a | ||
| 261 | .Bx | ||
| 262 | extension and is provided for backwards compatibility with legacy programs. | ||
| 168 | .Sh BUGS | 263 | .Sh BUGS |
| 169 | Ignores the current locale. | 264 | Ignores the current locale. |
diff --git a/src/lib/libc/stdlib/strtol.c b/src/lib/libc/stdlib/strtol.c index 6f374abd5f..dc2cf8871c 100644 --- a/src/lib/libc/stdlib/strtol.c +++ b/src/lib/libc/stdlib/strtol.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: strtol.c,v 1.9 2013/04/17 17:40:35 tedu Exp $ */ | ||
| 1 | /*- | 2 | /*- |
| 2 | * Copyright (c) 1990 The Regents of the University of California. | 3 | * Copyright (c) 1990 The Regents of the University of California. |
| 3 | * All rights reserved. | 4 | * All rights reserved. |
| @@ -10,11 +11,7 @@ | |||
| 10 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the |
| 12 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. Neither the name of the University nor the names of its contributors |
| 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 | 15 | * may be used to endorse or promote products derived from this software |
| 19 | * without specific prior written permission. | 16 | * without specific prior written permission. |
| 20 | * | 17 | * |
| @@ -31,14 +28,9 @@ | |||
| 31 | * SUCH DAMAGE. | 28 | * SUCH DAMAGE. |
| 32 | */ | 29 | */ |
| 33 | 30 | ||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 35 | /*static char *sccsid = "from: @(#)strtol.c 5.4 (Berkeley) 2/23/91";*/ | ||
| 36 | static char *rcsid = "$Id: strtol.c,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $"; | ||
| 37 | #endif /* LIBC_SCCS and not lint */ | ||
| 38 | |||
| 39 | #include <limits.h> | ||
| 40 | #include <ctype.h> | 31 | #include <ctype.h> |
| 41 | #include <errno.h> | 32 | #include <errno.h> |
| 33 | #include <limits.h> | ||
| 42 | #include <stdlib.h> | 34 | #include <stdlib.h> |
| 43 | 35 | ||
| 44 | 36 | ||
| @@ -49,30 +41,41 @@ static char *rcsid = "$Id: strtol.c,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $" | |||
| 49 | * alphabets and digits are each contiguous. | 41 | * alphabets and digits are each contiguous. |
| 50 | */ | 42 | */ |
| 51 | long | 43 | long |
| 52 | strtol(nptr, endptr, base) | 44 | strtol(const char *nptr, char **endptr, int base) |
| 53 | const char *nptr; | ||
| 54 | char **endptr; | ||
| 55 | register int base; | ||
| 56 | { | 45 | { |
| 57 | register const char *s = nptr; | 46 | const char *s; |
| 58 | register unsigned long acc; | 47 | long acc, cutoff; |
| 59 | register int c; | 48 | int c; |
| 60 | register unsigned long cutoff; | 49 | int neg, any, cutlim; |
| 61 | register int neg = 0, any, cutlim; | 50 | |
| 51 | /* | ||
| 52 | * Ensure that base is between 2 and 36 inclusive, or the special | ||
| 53 | * value of 0. | ||
| 54 | */ | ||
| 55 | if (base != 0 && (base < 2 || base > 36)) { | ||
| 56 | if (endptr != 0) | ||
| 57 | *endptr = (char *)nptr; | ||
| 58 | errno = EINVAL; | ||
| 59 | return 0; | ||
| 60 | } | ||
| 62 | 61 | ||
| 63 | /* | 62 | /* |
| 64 | * Skip white space and pick up leading +/- sign if any. | 63 | * Skip white space and pick up leading +/- sign if any. |
| 65 | * If base is 0, allow 0x for hex and 0 for octal, else | 64 | * If base is 0, allow 0x for hex and 0 for octal, else |
| 66 | * assume decimal; if base is already 16, allow 0x. | 65 | * assume decimal; if base is already 16, allow 0x. |
| 67 | */ | 66 | */ |
| 67 | s = nptr; | ||
| 68 | do { | 68 | do { |
| 69 | c = *s++; | 69 | c = (unsigned char) *s++; |
| 70 | } while (isspace(c)); | 70 | } while (isspace(c)); |
| 71 | if (c == '-') { | 71 | if (c == '-') { |
| 72 | neg = 1; | 72 | neg = 1; |
| 73 | c = *s++; | 73 | c = *s++; |
| 74 | } else if (c == '+') | 74 | } else { |
| 75 | c = *s++; | 75 | neg = 0; |
| 76 | if (c == '+') | ||
| 77 | c = *s++; | ||
| 78 | } | ||
| 76 | if ((base == 0 || base == 16) && | 79 | if ((base == 0 || base == 16) && |
| 77 | c == '0' && (*s == 'x' || *s == 'X')) { | 80 | c == '0' && (*s == 'x' || *s == 'X')) { |
| 78 | c = s[1]; | 81 | c = s[1]; |
| @@ -99,10 +102,17 @@ strtol(nptr, endptr, base) | |||
| 99 | * Set any if any `digits' consumed; make it negative to indicate | 102 | * Set any if any `digits' consumed; make it negative to indicate |
| 100 | * overflow. | 103 | * overflow. |
| 101 | */ | 104 | */ |
| 102 | cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX; | 105 | cutoff = neg ? LONG_MIN : LONG_MAX; |
| 103 | cutlim = cutoff % (unsigned long)base; | 106 | cutlim = cutoff % base; |
| 104 | cutoff /= (unsigned long)base; | 107 | cutoff /= base; |
| 105 | for (acc = 0, any = 0;; c = *s++) { | 108 | if (neg) { |
| 109 | if (cutlim > 0) { | ||
| 110 | cutlim -= base; | ||
| 111 | cutoff += 1; | ||
| 112 | } | ||
| 113 | cutlim = -cutlim; | ||
| 114 | } | ||
| 115 | for (acc = 0, any = 0;; c = (unsigned char) *s++) { | ||
| 106 | if (isdigit(c)) | 116 | if (isdigit(c)) |
| 107 | c -= '0'; | 117 | c -= '0'; |
| 108 | else if (isalpha(c)) | 118 | else if (isalpha(c)) |
| @@ -111,19 +121,30 @@ strtol(nptr, endptr, base) | |||
| 111 | break; | 121 | break; |
| 112 | if (c >= base) | 122 | if (c >= base) |
| 113 | break; | 123 | break; |
| 114 | if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) | 124 | if (any < 0) |
| 115 | any = -1; | 125 | continue; |
| 116 | else { | 126 | if (neg) { |
| 117 | any = 1; | 127 | if (acc < cutoff || (acc == cutoff && c > cutlim)) { |
| 118 | acc *= base; | 128 | any = -1; |
| 119 | acc += c; | 129 | acc = LONG_MIN; |
| 130 | errno = ERANGE; | ||
| 131 | } else { | ||
| 132 | any = 1; | ||
| 133 | acc *= base; | ||
| 134 | acc -= c; | ||
| 135 | } | ||
| 136 | } else { | ||
| 137 | if (acc > cutoff || (acc == cutoff && c > cutlim)) { | ||
| 138 | any = -1; | ||
| 139 | acc = LONG_MAX; | ||
| 140 | errno = ERANGE; | ||
| 141 | } else { | ||
| 142 | any = 1; | ||
| 143 | acc *= base; | ||
| 144 | acc += c; | ||
| 145 | } | ||
| 120 | } | 146 | } |
| 121 | } | 147 | } |
| 122 | if (any < 0) { | ||
| 123 | acc = neg ? LONG_MIN : LONG_MAX; | ||
| 124 | errno = ERANGE; | ||
| 125 | } else if (neg) | ||
| 126 | acc = -acc; | ||
| 127 | if (endptr != 0) | 148 | if (endptr != 0) |
| 128 | *endptr = (char *) (any ? s - 1 : nptr); | 149 | *endptr = (char *) (any ? s - 1 : nptr); |
| 129 | return (acc); | 150 | return (acc); |
diff --git a/src/lib/libc/stdlib/strtoq.c b/src/lib/libc/stdlib/strtoll.c index fc559e9d7f..4bcc5565be 100644 --- a/src/lib/libc/stdlib/strtoq.c +++ b/src/lib/libc/stdlib/strtoll.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: strtoll.c,v 1.7 2013/03/28 18:09:38 martynas Exp $ */ | ||
| 1 | /*- | 2 | /*- |
| 2 | * Copyright (c) 1992 The Regents of the University of California. | 3 | * Copyright (c) 1992 The Regents of the University of California. |
| 3 | * All rights reserved. | 4 | * All rights reserved. |
| @@ -10,11 +11,7 @@ | |||
| 10 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the |
| 12 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. Neither the name of the University nor the names of its contributors |
| 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 | 15 | * may be used to endorse or promote products derived from this software |
| 19 | * without specific prior written permission. | 16 | * without specific prior written permission. |
| 20 | * | 17 | * |
| @@ -31,34 +28,26 @@ | |||
| 31 | * SUCH DAMAGE. | 28 | * SUCH DAMAGE. |
| 32 | */ | 29 | */ |
| 33 | 30 | ||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 35 | static char sccsid[] = "@(#)strtoq.c 5.1 (Berkeley) 6/26/92"; | ||
| 36 | #endif /* LIBC_SCCS and not lint */ | ||
| 37 | |||
| 38 | #include <sys/types.h> | 31 | #include <sys/types.h> |
| 39 | 32 | ||
| 40 | #include <limits.h> | ||
| 41 | #include <errno.h> | ||
| 42 | #include <ctype.h> | 33 | #include <ctype.h> |
| 34 | #include <errno.h> | ||
| 35 | #include <limits.h> | ||
| 43 | #include <stdlib.h> | 36 | #include <stdlib.h> |
| 44 | 37 | ||
| 45 | /* | 38 | /* |
| 46 | * Convert a string to a quad integer. | 39 | * Convert a string to a long long. |
| 47 | * | 40 | * |
| 48 | * Ignores `locale' stuff. Assumes that the upper and lower case | 41 | * Ignores `locale' stuff. Assumes that the upper and lower case |
| 49 | * alphabets and digits are each contiguous. | 42 | * alphabets and digits are each contiguous. |
| 50 | */ | 43 | */ |
| 51 | quad_t | 44 | long long |
| 52 | strtoq(nptr, endptr, base) | 45 | strtoll(const char *nptr, char **endptr, int base) |
| 53 | const char *nptr; | ||
| 54 | char **endptr; | ||
| 55 | register int base; | ||
| 56 | { | 46 | { |
| 57 | register const char *s; | 47 | const char *s; |
| 58 | register u_quad_t acc; | 48 | long long acc, cutoff; |
| 59 | register int c; | 49 | int c; |
| 60 | register u_quad_t qbase, cutoff; | 50 | int neg, any, cutlim; |
| 61 | register int neg, any, cutlim; | ||
| 62 | 51 | ||
| 63 | /* | 52 | /* |
| 64 | * Skip white space and pick up leading +/- sign if any. | 53 | * Skip white space and pick up leading +/- sign if any. |
| @@ -67,7 +56,7 @@ strtoq(nptr, endptr, base) | |||
| 67 | */ | 56 | */ |
| 68 | s = nptr; | 57 | s = nptr; |
| 69 | do { | 58 | do { |
| 70 | c = *s++; | 59 | c = (unsigned char) *s++; |
| 71 | } while (isspace(c)); | 60 | } while (isspace(c)); |
| 72 | if (c == '-') { | 61 | if (c == '-') { |
| 73 | neg = 1; | 62 | neg = 1; |
| @@ -93,7 +82,7 @@ strtoq(nptr, endptr, base) | |||
| 93 | * followed by a legal input character, is too big. One that | 82 | * followed by a legal input character, is too big. One that |
| 94 | * is equal to this value may be valid or not; the limit | 83 | * is equal to this value may be valid or not; the limit |
| 95 | * between valid and invalid numbers is then based on the last | 84 | * between valid and invalid numbers is then based on the last |
| 96 | * digit. For instance, if the range for quads is | 85 | * digit. For instance, if the range for long longs is |
| 97 | * [-9223372036854775808..9223372036854775807] and the input base | 86 | * [-9223372036854775808..9223372036854775807] and the input base |
| 98 | * is 10, cutoff will be set to 922337203685477580 and cutlim to | 87 | * is 10, cutoff will be set to 922337203685477580 and cutlim to |
| 99 | * either 7 (neg==0) or 8 (neg==1), meaning that if we have | 88 | * either 7 (neg==0) or 8 (neg==1), meaning that if we have |
| @@ -104,11 +93,17 @@ strtoq(nptr, endptr, base) | |||
| 104 | * Set any if any `digits' consumed; make it negative to indicate | 93 | * Set any if any `digits' consumed; make it negative to indicate |
| 105 | * overflow. | 94 | * overflow. |
| 106 | */ | 95 | */ |
| 107 | qbase = (unsigned)base; | 96 | cutoff = neg ? LLONG_MIN : LLONG_MAX; |
| 108 | cutoff = neg ? -(u_quad_t)QUAD_MIN : QUAD_MAX; | 97 | cutlim = cutoff % base; |
| 109 | cutlim = cutoff % qbase; | 98 | cutoff /= base; |
| 110 | cutoff /= qbase; | 99 | if (neg) { |
| 111 | for (acc = 0, any = 0;; c = *s++) { | 100 | if (cutlim > 0) { |
| 101 | cutlim -= base; | ||
| 102 | cutoff += 1; | ||
| 103 | } | ||
| 104 | cutlim = -cutlim; | ||
| 105 | } | ||
| 106 | for (acc = 0, any = 0;; c = (unsigned char) *s++) { | ||
| 112 | if (isdigit(c)) | 107 | if (isdigit(c)) |
| 113 | c -= '0'; | 108 | c -= '0'; |
| 114 | else if (isalpha(c)) | 109 | else if (isalpha(c)) |
| @@ -117,20 +112,33 @@ strtoq(nptr, endptr, base) | |||
| 117 | break; | 112 | break; |
| 118 | if (c >= base) | 113 | if (c >= base) |
| 119 | break; | 114 | break; |
| 120 | if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) | 115 | if (any < 0) |
| 121 | any = -1; | 116 | continue; |
| 122 | else { | 117 | if (neg) { |
| 123 | any = 1; | 118 | if (acc < cutoff || (acc == cutoff && c > cutlim)) { |
| 124 | acc *= qbase; | 119 | any = -1; |
| 125 | acc += c; | 120 | acc = LLONG_MIN; |
| 121 | errno = ERANGE; | ||
| 122 | } else { | ||
| 123 | any = 1; | ||
| 124 | acc *= base; | ||
| 125 | acc -= c; | ||
| 126 | } | ||
| 127 | } else { | ||
| 128 | if (acc > cutoff || (acc == cutoff && c > cutlim)) { | ||
| 129 | any = -1; | ||
| 130 | acc = LLONG_MAX; | ||
| 131 | errno = ERANGE; | ||
| 132 | } else { | ||
| 133 | any = 1; | ||
| 134 | acc *= base; | ||
| 135 | acc += c; | ||
| 136 | } | ||
| 126 | } | 137 | } |
| 127 | } | 138 | } |
| 128 | if (any < 0) { | ||
| 129 | acc = neg ? QUAD_MIN : QUAD_MAX; | ||
| 130 | errno = ERANGE; | ||
| 131 | } else if (neg) | ||
| 132 | acc = -acc; | ||
| 133 | if (endptr != 0) | 139 | if (endptr != 0) |
| 134 | *endptr = (char *) (any ? s - 1 : nptr); | 140 | *endptr = (char *) (any ? s - 1 : nptr); |
| 135 | return (acc); | 141 | return (acc); |
| 136 | } | 142 | } |
| 143 | |||
| 144 | __strong_alias(strtoq, strtoll); | ||
diff --git a/src/lib/libc/stdlib/strtonum.3 b/src/lib/libc/stdlib/strtonum.3 new file mode 100644 index 0000000000..ed638cdbe2 --- /dev/null +++ b/src/lib/libc/stdlib/strtonum.3 | |||
| @@ -0,0 +1,152 @@ | |||
| 1 | .\" $OpenBSD: strtonum.3,v 1.17 2013/08/14 06:32:28 jmc Exp $ | ||
| 2 | .\" | ||
| 3 | .\" Copyright (c) 2004 Ted Unangst | ||
| 4 | .\" | ||
| 5 | .\" Permission to use, copy, modify, and distribute this software for any | ||
| 6 | .\" purpose with or without fee is hereby granted, provided that the above | ||
| 7 | .\" copyright notice and this permission notice appear in all copies. | ||
| 8 | .\" | ||
| 9 | .\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 10 | .\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 11 | .\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 12 | .\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 13 | .\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 14 | .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 15 | .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 16 | .\" | ||
| 17 | .Dd $Mdocdate: August 14 2013 $ | ||
| 18 | .Dt STRTONUM 3 | ||
| 19 | .Os | ||
| 20 | .Sh NAME | ||
| 21 | .Nm strtonum | ||
| 22 | .Nd reliably convert string value to an integer | ||
| 23 | .Sh SYNOPSIS | ||
| 24 | .In stdlib.h | ||
| 25 | .Ft long long | ||
| 26 | .Fo strtonum | ||
| 27 | .Fa "const char *nptr" | ||
| 28 | .Fa "long long minval" | ||
| 29 | .Fa "long long maxval" | ||
| 30 | .Fa "const char **errstr" | ||
| 31 | .Fc | ||
| 32 | .Sh DESCRIPTION | ||
| 33 | The | ||
| 34 | .Fn strtonum | ||
| 35 | function converts the string in | ||
| 36 | .Fa nptr | ||
| 37 | to a | ||
| 38 | .Li long long | ||
| 39 | value. | ||
| 40 | The | ||
| 41 | .Fn strtonum | ||
| 42 | function was designed to facilitate safe, robust programming | ||
| 43 | and overcome the shortcomings of the | ||
| 44 | .Xr atoi 3 | ||
| 45 | and | ||
| 46 | .Xr strtol 3 | ||
| 47 | family of interfaces. | ||
| 48 | .Pp | ||
| 49 | The string may begin with an arbitrary amount of whitespace | ||
| 50 | (as determined by | ||
| 51 | .Xr isspace 3 ) | ||
| 52 | followed by a single optional | ||
| 53 | .Ql + | ||
| 54 | or | ||
| 55 | .Ql - | ||
| 56 | sign. | ||
| 57 | .Pp | ||
| 58 | The remainder of the string is converted to a | ||
| 59 | .Li long long | ||
| 60 | value according to base 10. | ||
| 61 | .Pp | ||
| 62 | The value obtained is then checked against the provided | ||
| 63 | .Fa minval | ||
| 64 | and | ||
| 65 | .Fa maxval | ||
| 66 | bounds. | ||
| 67 | If | ||
| 68 | .Fa errstr | ||
| 69 | is non-null, | ||
| 70 | .Fn strtonum | ||
| 71 | stores an error string in | ||
| 72 | .Fa *errstr | ||
| 73 | indicating the failure. | ||
| 74 | .Sh RETURN VALUES | ||
| 75 | The | ||
| 76 | .Fn strtonum | ||
| 77 | function returns the result of the conversion, | ||
| 78 | unless the value would exceed the provided bounds or is invalid. | ||
| 79 | On error, 0 is returned, | ||
| 80 | .Va errno | ||
| 81 | is set, and | ||
| 82 | .Fa errstr | ||
| 83 | will point to an error message. | ||
| 84 | .Fa *errstr | ||
| 85 | will be set to | ||
| 86 | .Dv NULL | ||
| 87 | on success; | ||
| 88 | this fact can be used to differentiate | ||
| 89 | a successful return of 0 from an error. | ||
| 90 | .Sh EXAMPLES | ||
| 91 | Using | ||
| 92 | .Fn strtonum | ||
| 93 | correctly is meant to be simpler than the alternative functions. | ||
| 94 | .Bd -literal -offset indent | ||
| 95 | int iterations; | ||
| 96 | const char *errstr; | ||
| 97 | |||
| 98 | iterations = strtonum(optarg, 1, 64, &errstr); | ||
| 99 | if (errstr) | ||
| 100 | errx(1, "number of iterations is %s: %s", errstr, optarg); | ||
| 101 | .Ed | ||
| 102 | .Pp | ||
| 103 | The above example will guarantee that the value of iterations is between | ||
| 104 | 1 and 64 (inclusive). | ||
| 105 | .Sh ERRORS | ||
| 106 | .Bl -tag -width Er | ||
| 107 | .It Bq Er ERANGE | ||
| 108 | The given string was out of range. | ||
| 109 | .It Bq Er EINVAL | ||
| 110 | The given string did not consist solely of digit characters. | ||
| 111 | .It Bq Er EINVAL | ||
| 112 | .Ar minval | ||
| 113 | was larger than | ||
| 114 | .Ar maxval . | ||
| 115 | .El | ||
| 116 | .Pp | ||
| 117 | If an error occurs, | ||
| 118 | .Fa errstr | ||
| 119 | will be set to one of the following strings: | ||
| 120 | .Pp | ||
| 121 | .Bl -tag -width "too largeXX" -compact | ||
| 122 | .It Qq too large | ||
| 123 | The result was larger than the provided maximum value. | ||
| 124 | .It Qq too small | ||
| 125 | The result was smaller than the provided minimum value. | ||
| 126 | .It Qq invalid | ||
| 127 | The string did not consist solely of digit characters. | ||
| 128 | .El | ||
| 129 | .Sh SEE ALSO | ||
| 130 | .Xr atof 3 , | ||
| 131 | .Xr atoi 3 , | ||
| 132 | .Xr atol 3 , | ||
| 133 | .Xr atoll 3 , | ||
| 134 | .Xr sscanf 3 , | ||
| 135 | .Xr strtod 3 , | ||
| 136 | .Xr strtol 3 , | ||
| 137 | .Xr strtoul 3 | ||
| 138 | .Sh STANDARDS | ||
| 139 | .Fn strtonum | ||
| 140 | is an | ||
| 141 | .Ox | ||
| 142 | extension. | ||
| 143 | The existing alternatives, such as | ||
| 144 | .Xr atoi 3 | ||
| 145 | and | ||
| 146 | .Xr strtol 3 , | ||
| 147 | are either impossible or difficult to use safely. | ||
| 148 | .Sh HISTORY | ||
| 149 | The | ||
| 150 | .Fn strtonum | ||
| 151 | function first appeared in | ||
| 152 | .Ox 3.6 . | ||
diff --git a/src/lib/libc/stdlib/strtonum.c b/src/lib/libc/stdlib/strtonum.c new file mode 100644 index 0000000000..1aeee3467b --- /dev/null +++ b/src/lib/libc/stdlib/strtonum.c | |||
| @@ -0,0 +1,65 @@ | |||
| 1 | /* $OpenBSD: strtonum.c,v 1.7 2013/04/17 18:40:58 tedu Exp $ */ | ||
| 2 | |||
| 3 | /* | ||
| 4 | * Copyright (c) 2004 Ted Unangst and Todd Miller | ||
| 5 | * All rights reserved. | ||
| 6 | * | ||
| 7 | * Permission to use, copy, modify, and distribute this software for any | ||
| 8 | * purpose with or without fee is hereby granted, provided that the above | ||
| 9 | * copyright notice and this permission notice appear in all copies. | ||
| 10 | * | ||
| 11 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 12 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 13 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 14 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 15 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 16 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 17 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <errno.h> | ||
| 21 | #include <limits.h> | ||
| 22 | #include <stdlib.h> | ||
| 23 | |||
| 24 | #define INVALID 1 | ||
| 25 | #define TOOSMALL 2 | ||
| 26 | #define TOOLARGE 3 | ||
| 27 | |||
| 28 | long long | ||
| 29 | strtonum(const char *numstr, long long minval, long long maxval, | ||
| 30 | const char **errstrp) | ||
| 31 | { | ||
| 32 | long long ll = 0; | ||
| 33 | int error = 0; | ||
| 34 | char *ep; | ||
| 35 | struct errval { | ||
| 36 | const char *errstr; | ||
| 37 | int err; | ||
| 38 | } ev[4] = { | ||
| 39 | { NULL, 0 }, | ||
| 40 | { "invalid", EINVAL }, | ||
| 41 | { "too small", ERANGE }, | ||
| 42 | { "too large", ERANGE }, | ||
| 43 | }; | ||
| 44 | |||
| 45 | ev[0].err = errno; | ||
| 46 | errno = 0; | ||
| 47 | if (minval > maxval) { | ||
| 48 | error = INVALID; | ||
| 49 | } else { | ||
| 50 | ll = strtoll(numstr, &ep, 10); | ||
| 51 | if (numstr == ep || *ep != '\0') | ||
| 52 | error = INVALID; | ||
| 53 | else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval) | ||
| 54 | error = TOOSMALL; | ||
| 55 | else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval) | ||
| 56 | error = TOOLARGE; | ||
| 57 | } | ||
| 58 | if (errstrp != NULL) | ||
| 59 | *errstrp = ev[error].errstr; | ||
| 60 | errno = ev[error].err; | ||
| 61 | if (error) | ||
| 62 | ll = 0; | ||
| 63 | |||
| 64 | return (ll); | ||
| 65 | } | ||
diff --git a/src/lib/libc/stdlib/strtoul.3 b/src/lib/libc/stdlib/strtoul.3 index db551b0141..1353637d68 100644 --- a/src/lib/libc/stdlib/strtoul.3 +++ b/src/lib/libc/stdlib/strtoul.3 | |||
| @@ -13,11 +13,7 @@ | |||
| 13 | .\" 2. Redistributions in binary form must reproduce the above copyright | 13 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 14 | .\" notice, this list of conditions and the following disclaimer in the | 14 | .\" notice, this list of conditions and the following disclaimer in the |
| 15 | .\" documentation and/or other materials provided with the distribution. | 15 | .\" documentation and/or other materials provided with the distribution. |
| 16 | .\" 3. All advertising materials mentioning features or use of this software | 16 | .\" 3. Neither the name of the University nor the names of its contributors |
| 17 | .\" must display the following acknowledgement: | ||
| 18 | .\" This product includes software developed by the University of | ||
| 19 | .\" California, Berkeley and its contributors. | ||
| 20 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 21 | .\" may be used to endorse or promote products derived from this software | 17 | .\" may be used to endorse or promote products derived from this software |
| 22 | .\" without specific prior written permission. | 18 | .\" without specific prior written permission. |
| 23 | .\" | 19 | .\" |
| @@ -33,49 +29,70 @@ | |||
| 33 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 29 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 34 | .\" SUCH DAMAGE. | 30 | .\" SUCH DAMAGE. |
| 35 | .\" | 31 | .\" |
| 36 | .\" from: @(#)strtoul.3 5.4 (Berkeley) 6/25/92 | 32 | .\" $OpenBSD: strtoul.3,v 1.22 2013/08/14 06:32:28 jmc Exp $ |
| 37 | .\" $Id: strtoul.3,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $ | ||
| 38 | .\" | 33 | .\" |
| 39 | .Dd June 25, 1992 | 34 | .Dd $Mdocdate: August 14 2013 $ |
| 40 | .Dt STRTOUL 3 | 35 | .Dt STRTOUL 3 |
| 41 | .Os | 36 | .Os |
| 42 | .Sh NAME | 37 | .Sh NAME |
| 43 | .Nm strtoul, strtouq | 38 | .Nm strtoul , |
| 44 | .Nd convert a string to an unsigned long or uquad_t integer | 39 | .Nm strtoull , |
| 40 | .Nm strtoumax , | ||
| 41 | .Nm strtouq | ||
| 42 | .Nd convert a string to an unsigned long, unsigned long long or uintmax_t integer | ||
| 45 | .Sh SYNOPSIS | 43 | .Sh SYNOPSIS |
| 46 | .Fd #include <stdlib.h> | 44 | .In limits.h |
| 47 | .Fd #include <limits.h> | 45 | .In stdlib.h |
| 48 | .Ft unsigned long | 46 | .Ft unsigned long |
| 49 | .Fn strtoul "const char *nptr" "char **endptr" "int base" | 47 | .Fn strtoul "const char *nptr" "char **endptr" "int base" |
| 50 | 48 | .Ft unsigned long long | |
| 51 | .Fd #include <sys/types.h> | 49 | .Fn strtoull "const char *nptr" "char **endptr" "int base" |
| 52 | .Fd #include <stdlib.h> | 50 | .In inttypes.h |
| 53 | .Fd #include <limits.h> | 51 | .Ft uintmax_t |
| 52 | .Fn strtoumax "const char *nptr" "char **endptr" "int base" | ||
| 53 | .In sys/types.h | ||
| 54 | .In limits.h | ||
| 55 | .In stdlib.h | ||
| 54 | .Ft u_quad_t | 56 | .Ft u_quad_t |
| 55 | .Fn strtouq "const char *nptr" "char **endptr" "int base" | 57 | .Fn strtouq "const char *nptr" "char **endptr" "int base" |
| 56 | .Sh DESCRIPTION | 58 | .Sh DESCRIPTION |
| 57 | The | 59 | The |
| 58 | .Fn strtoul | 60 | .Fn strtoul |
| 59 | function | 61 | function converts the string in |
| 60 | converts the string in | ||
| 61 | .Fa nptr | 62 | .Fa nptr |
| 62 | to an | 63 | to an |
| 63 | .Em unsigned long | 64 | .Li unsigned long |
| 64 | value. | 65 | value. |
| 65 | The | 66 | The |
| 66 | .Fn strtouq | 67 | .Fn strtoull |
| 67 | function | 68 | function converts the string in |
| 68 | converts the string in | 69 | .Fa nptr |
| 70 | to an | ||
| 71 | .Li unsigned long long | ||
| 72 | value. | ||
| 73 | The | ||
| 74 | .Fn strtoumax | ||
| 75 | function converts the string in | ||
| 69 | .Fa nptr | 76 | .Fa nptr |
| 70 | to a | 77 | to a |
| 71 | .Em u_quad_t | 78 | .Li umaxint_t |
| 72 | value. | 79 | value. |
| 80 | The | ||
| 81 | .Fn strtouq | ||
| 82 | function is a deprecated equivalent of | ||
| 83 | .Fn strtoull | ||
| 84 | and is provided for backwards compatibility with legacy programs. | ||
| 73 | The conversion is done according to the given | 85 | The conversion is done according to the given |
| 74 | .Fa base , | 86 | .Fa base , |
| 75 | which must be between 2 and 36 inclusive, | 87 | which must be a number between 2 and 36 inclusive |
| 76 | or be the special value 0. | 88 | or the special value 0. |
| 89 | If the string in | ||
| 90 | .Fa nptr | ||
| 91 | represents a negative number, it will be converted to its unsigned equivalent. | ||
| 92 | This behavior is consistent with what happens when a signed integer type is | ||
| 93 | cast to its unsigned counterpart. | ||
| 77 | .Pp | 94 | .Pp |
| 78 | The string may begin with an arbitrary amount of white space | 95 | The string may begin with an arbitrary amount of whitespace |
| 79 | (as determined by | 96 | (as determined by |
| 80 | .Xr isspace 3 ) | 97 | .Xr isspace 3 ) |
| 81 | followed by a single optional | 98 | followed by a single optional |
| @@ -85,26 +102,22 @@ or | |||
| 85 | sign. | 102 | sign. |
| 86 | If | 103 | If |
| 87 | .Fa base | 104 | .Fa base |
| 88 | is zero or 16, | 105 | is zero or 16, the string may then include a |
| 89 | the string may then include a | ||
| 90 | .Ql 0x | 106 | .Ql 0x |
| 91 | prefix, | 107 | prefix, and the number will be read in base 16; otherwise, a zero |
| 92 | and the number will be read in base 16; otherwise, a zero | ||
| 93 | .Fa base | 108 | .Fa base |
| 94 | is taken as 10 (decimal) unless the next character is | 109 | is taken as 10 (decimal) unless the next character is |
| 95 | .Ql 0 , | 110 | .Ql 0 , |
| 96 | in which case it is taken as 8 (octal). | 111 | in which case it is taken as 8 (octal). |
| 97 | .Pp | 112 | .Pp |
| 98 | The remainder of the string is converted to an | 113 | The remainder of the string is converted to an |
| 99 | .Em unsigned long | 114 | .Li unsigned long |
| 100 | value in the obvious manner, | 115 | value in the obvious manner, stopping at the end of the string |
| 101 | stopping at the end of the string | ||
| 102 | or at the first character that does not produce a valid digit | 116 | or at the first character that does not produce a valid digit |
| 103 | in the given base. | 117 | in the given base. |
| 104 | (In bases above 10, the letter | 118 | (In bases above 10, the letter |
| 105 | .Ql A | 119 | .Ql A |
| 106 | in either upper or lower case | 120 | in either upper or lower case represents 10, |
| 107 | represents 10, | ||
| 108 | .Ql B | 121 | .Ql B |
| 109 | represents 11, and so forth, with | 122 | represents 11, and so forth, with |
| 110 | .Ql Z | 123 | .Ql Z |
| @@ -112,7 +125,7 @@ representing 35.) | |||
| 112 | .Pp | 125 | .Pp |
| 113 | If | 126 | If |
| 114 | .Fa endptr | 127 | .Fa endptr |
| 115 | is non nil, | 128 | is non-null, |
| 116 | .Fn strtoul | 129 | .Fn strtoul |
| 117 | stores the address of the first invalid character in | 130 | stores the address of the first invalid character in |
| 118 | .Fa *endptr . | 131 | .Fa *endptr . |
| @@ -133,32 +146,100 @@ is | |||
| 133 | on return, the entire string was valid.) | 146 | on return, the entire string was valid.) |
| 134 | .Sh RETURN VALUES | 147 | .Sh RETURN VALUES |
| 135 | The | 148 | The |
| 136 | .Fn strtoul | 149 | .Fn strtoul , |
| 137 | function | 150 | .Fn strtoull , |
| 138 | returns either the result of the conversion | 151 | .Fn strtoumax |
| 139 | or, if there was a leading minus sign, | 152 | and |
| 153 | .Fn strtouq | ||
| 154 | functions return either the result of the conversion or, | ||
| 155 | if there was a leading minus sign, | ||
| 140 | the negation of the result of the conversion, | 156 | the negation of the result of the conversion, |
| 141 | unless the original (non-negated) value would overflow; | 157 | unless the original (non-negated) value would overflow. |
| 142 | in the latter case, | 158 | If overflow occurs, |
| 143 | .Fn strtoul | 159 | .Fn strtoul |
| 144 | returns | 160 | returns |
| 145 | .Dv ULONG_MAX | 161 | .Dv ULONG_MAX , |
| 146 | and sets the global variable | 162 | .Fn strtoull |
| 163 | returns | ||
| 164 | .Dv ULLONG_MAX , | ||
| 165 | .Fn strtoumax | ||
| 166 | returns | ||
| 167 | .Dv UINTMAX_MAX , | ||
| 168 | .Fn strtouq | ||
| 169 | returns | ||
| 170 | .Dv ULLONG_MAX | ||
| 171 | and the global variable | ||
| 147 | .Va errno | 172 | .Va errno |
| 148 | to | 173 | is set to |
| 149 | .Er ERANGE . | 174 | .Er ERANGE . |
| 175 | If no conversion could be performed, 0 is returned; | ||
| 176 | the global variable | ||
| 177 | .Va errno | ||
| 178 | is also set to | ||
| 179 | .Er EINVAL , | ||
| 180 | though this is not portable across all platforms. | ||
| 181 | .Pp | ||
| 182 | There is no way to determine if | ||
| 183 | .Fn strtoul | ||
| 184 | has processed a negative number (and returned an unsigned value) short of | ||
| 185 | examining the string in | ||
| 186 | .Fa nptr | ||
| 187 | directly. | ||
| 188 | .Sh EXAMPLES | ||
| 189 | Ensuring that a string is a valid number (i.e., in range and containing no | ||
| 190 | trailing characters) requires clearing | ||
| 191 | .Va errno | ||
| 192 | beforehand explicitly since | ||
| 193 | .Va errno | ||
| 194 | is not changed on a successful call to | ||
| 195 | .Fn strtoul , | ||
| 196 | and the return value of | ||
| 197 | .Fn strtoul | ||
| 198 | cannot be used unambiguously to signal an error: | ||
| 199 | .Bd -literal -offset indent | ||
| 200 | char *ep; | ||
| 201 | unsigned long ulval; | ||
| 202 | |||
| 203 | \&... | ||
| 204 | |||
| 205 | errno = 0; | ||
| 206 | ulval = strtoul(buf, &ep, 10); | ||
| 207 | if (buf[0] == '\e0' || *ep != '\e0') | ||
| 208 | goto not_a_number; | ||
| 209 | if (errno == ERANGE && ulval == ULONG_MAX) | ||
| 210 | goto out_of_range; | ||
| 211 | .Ed | ||
| 212 | .Pp | ||
| 213 | This example will accept | ||
| 214 | .Dq 12 | ||
| 215 | but not | ||
| 216 | .Dq 12foo | ||
| 217 | or | ||
| 218 | .Dq 12\en . | ||
| 219 | If trailing whitespace is acceptable, further checks must be done on | ||
| 220 | .Va *ep ; | ||
| 221 | alternately, use | ||
| 222 | .Xr sscanf 3 . | ||
| 150 | .Sh ERRORS | 223 | .Sh ERRORS |
| 151 | .Bl -tag -width Er | 224 | .Bl -tag -width Er |
| 152 | .It Bq Er ERANGE | 225 | .It Bq Er ERANGE |
| 153 | The given string was out of range; the value converted has been clamped. | 226 | The given string was out of range; the value converted has been clamped. |
| 154 | .El | 227 | .El |
| 155 | .Sh SEE ALSO | 228 | .Sh SEE ALSO |
| 229 | .Xr sscanf 3 , | ||
| 156 | .Xr strtol 3 | 230 | .Xr strtol 3 |
| 157 | .Sh STANDARDS | 231 | .Sh STANDARDS |
| 158 | The | 232 | The |
| 159 | .Fn strtoul | 233 | .Fn strtoul , |
| 160 | function | 234 | .Fn strtoull , |
| 161 | conforms to | 235 | and |
| 162 | .St -ansiC . | 236 | .Fn strtoumax |
| 237 | functions conform to | ||
| 238 | .St -ansiC-99 . | ||
| 239 | The | ||
| 240 | .Fn strtouq | ||
| 241 | function is a | ||
| 242 | .Bx | ||
| 243 | extension and is provided for backwards compatibility with legacy programs. | ||
| 163 | .Sh BUGS | 244 | .Sh BUGS |
| 164 | Ignores the current locale. | 245 | Ignores the current locale. |
diff --git a/src/lib/libc/stdlib/strtoul.c b/src/lib/libc/stdlib/strtoul.c index 00f7210fa1..a236365d2f 100644 --- a/src/lib/libc/stdlib/strtoul.c +++ b/src/lib/libc/stdlib/strtoul.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: strtoul.c,v 1.8 2013/04/17 17:40:35 tedu Exp $ */ | ||
| 1 | /* | 2 | /* |
| 2 | * Copyright (c) 1990 Regents of the University of California. | 3 | * Copyright (c) 1990 Regents of the University of California. |
| 3 | * All rights reserved. | 4 | * All rights reserved. |
| @@ -10,11 +11,7 @@ | |||
| 10 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the |
| 12 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. Neither the name of the University nor the names of its contributors |
| 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 | 15 | * may be used to endorse or promote products derived from this software |
| 19 | * without specific prior written permission. | 16 | * without specific prior written permission. |
| 20 | * | 17 | * |
| @@ -31,14 +28,9 @@ | |||
| 31 | * SUCH DAMAGE. | 28 | * SUCH DAMAGE. |
| 32 | */ | 29 | */ |
| 33 | 30 | ||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 35 | /*static char *sccsid = "from: @(#)strtoul.c 5.3 (Berkeley) 2/23/91";*/ | ||
| 36 | static char *rcsid = "$Id: strtoul.c,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $"; | ||
| 37 | #endif /* LIBC_SCCS and not lint */ | ||
| 38 | |||
| 39 | #include <limits.h> | ||
| 40 | #include <ctype.h> | 31 | #include <ctype.h> |
| 41 | #include <errno.h> | 32 | #include <errno.h> |
| 33 | #include <limits.h> | ||
| 42 | #include <stdlib.h> | 34 | #include <stdlib.h> |
| 43 | 35 | ||
| 44 | /* | 36 | /* |
| @@ -48,28 +40,28 @@ static char *rcsid = "$Id: strtoul.c,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $ | |||
| 48 | * alphabets and digits are each contiguous. | 40 | * alphabets and digits are each contiguous. |
| 49 | */ | 41 | */ |
| 50 | unsigned long | 42 | unsigned long |
| 51 | strtoul(nptr, endptr, base) | 43 | strtoul(const char *nptr, char **endptr, int base) |
| 52 | const char *nptr; | ||
| 53 | char **endptr; | ||
| 54 | register int base; | ||
| 55 | { | 44 | { |
| 56 | register const char *s = nptr; | 45 | const char *s; |
| 57 | register unsigned long acc; | 46 | unsigned long acc, cutoff; |
| 58 | register int c; | 47 | int c; |
| 59 | register unsigned long cutoff; | 48 | int neg, any, cutlim; |
| 60 | register int neg = 0, any, cutlim; | ||
| 61 | 49 | ||
| 62 | /* | 50 | /* |
| 63 | * See strtol for comments as to the logic used. | 51 | * See strtol for comments as to the logic used. |
| 64 | */ | 52 | */ |
| 53 | s = nptr; | ||
| 65 | do { | 54 | do { |
| 66 | c = *s++; | 55 | c = (unsigned char) *s++; |
| 67 | } while (isspace(c)); | 56 | } while (isspace(c)); |
| 68 | if (c == '-') { | 57 | if (c == '-') { |
| 69 | neg = 1; | 58 | neg = 1; |
| 70 | c = *s++; | 59 | c = *s++; |
| 71 | } else if (c == '+') | 60 | } else { |
| 72 | c = *s++; | 61 | neg = 0; |
| 62 | if (c == '+') | ||
| 63 | c = *s++; | ||
| 64 | } | ||
| 73 | if ((base == 0 || base == 16) && | 65 | if ((base == 0 || base == 16) && |
| 74 | c == '0' && (*s == 'x' || *s == 'X')) { | 66 | c == '0' && (*s == 'x' || *s == 'X')) { |
| 75 | c = s[1]; | 67 | c = s[1]; |
| @@ -78,9 +70,10 @@ strtoul(nptr, endptr, base) | |||
| 78 | } | 70 | } |
| 79 | if (base == 0) | 71 | if (base == 0) |
| 80 | base = c == '0' ? 8 : 10; | 72 | base = c == '0' ? 8 : 10; |
| 81 | cutoff = (unsigned long)ULONG_MAX / (unsigned long)base; | 73 | |
| 82 | cutlim = (unsigned long)ULONG_MAX % (unsigned long)base; | 74 | cutoff = ULONG_MAX / (unsigned long)base; |
| 83 | for (acc = 0, any = 0;; c = *s++) { | 75 | cutlim = ULONG_MAX % (unsigned long)base; |
| 76 | for (acc = 0, any = 0;; c = (unsigned char) *s++) { | ||
| 84 | if (isdigit(c)) | 77 | if (isdigit(c)) |
| 85 | c -= '0'; | 78 | c -= '0'; |
| 86 | else if (isalpha(c)) | 79 | else if (isalpha(c)) |
| @@ -89,18 +82,19 @@ strtoul(nptr, endptr, base) | |||
| 89 | break; | 82 | break; |
| 90 | if (c >= base) | 83 | if (c >= base) |
| 91 | break; | 84 | break; |
| 92 | if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) | 85 | if (any < 0) |
| 86 | continue; | ||
| 87 | if (acc > cutoff || (acc == cutoff && c > cutlim)) { | ||
| 93 | any = -1; | 88 | any = -1; |
| 94 | else { | 89 | acc = ULONG_MAX; |
| 90 | errno = ERANGE; | ||
| 91 | } else { | ||
| 95 | any = 1; | 92 | any = 1; |
| 96 | acc *= base; | 93 | acc *= (unsigned long)base; |
| 97 | acc += c; | 94 | acc += c; |
| 98 | } | 95 | } |
| 99 | } | 96 | } |
| 100 | if (any < 0) { | 97 | if (neg && any > 0) |
| 101 | acc = ULONG_MAX; | ||
| 102 | errno = ERANGE; | ||
| 103 | } else if (neg) | ||
| 104 | acc = -acc; | 98 | acc = -acc; |
| 105 | if (endptr != 0) | 99 | if (endptr != 0) |
| 106 | *endptr = (char *) (any ? s - 1 : nptr); | 100 | *endptr = (char *) (any ? s - 1 : nptr); |
diff --git a/src/lib/libc/stdlib/strtouq.c b/src/lib/libc/stdlib/strtoull.c index cc647d8d28..28f613a087 100644 --- a/src/lib/libc/stdlib/strtouq.c +++ b/src/lib/libc/stdlib/strtoull.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: strtoull.c,v 1.6 2013/03/28 18:09:38 martynas Exp $ */ | ||
| 1 | /*- | 2 | /*- |
| 2 | * Copyright (c) 1992 The Regents of the University of California. | 3 | * Copyright (c) 1992 The Regents of the University of California. |
| 3 | * All rights reserved. | 4 | * All rights reserved. |
| @@ -10,11 +11,7 @@ | |||
| 10 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the |
| 12 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. Neither the name of the University nor the names of its contributors |
| 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 | 15 | * may be used to endorse or promote products derived from this software |
| 19 | * without specific prior written permission. | 16 | * without specific prior written permission. |
| 20 | * | 17 | * |
| @@ -31,41 +28,33 @@ | |||
| 31 | * SUCH DAMAGE. | 28 | * SUCH DAMAGE. |
| 32 | */ | 29 | */ |
| 33 | 30 | ||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 35 | static char sccsid[] = "@(#)strtouq.c 5.1 (Berkeley) 6/26/92"; | ||
| 36 | #endif /* LIBC_SCCS and not lint */ | ||
| 37 | |||
| 38 | #include <sys/types.h> | 31 | #include <sys/types.h> |
| 39 | 32 | ||
| 40 | #include <limits.h> | ||
| 41 | #include <errno.h> | ||
| 42 | #include <ctype.h> | 33 | #include <ctype.h> |
| 34 | #include <errno.h> | ||
| 35 | #include <limits.h> | ||
| 43 | #include <stdlib.h> | 36 | #include <stdlib.h> |
| 44 | 37 | ||
| 45 | /* | 38 | /* |
| 46 | * Convert a string to an unsigned quad integer. | 39 | * Convert a string to an unsigned long long. |
| 47 | * | 40 | * |
| 48 | * Ignores `locale' stuff. Assumes that the upper and lower case | 41 | * Ignores `locale' stuff. Assumes that the upper and lower case |
| 49 | * alphabets and digits are each contiguous. | 42 | * alphabets and digits are each contiguous. |
| 50 | */ | 43 | */ |
| 51 | u_quad_t | 44 | unsigned long long |
| 52 | strtouq(nptr, endptr, base) | 45 | strtoull(const char *nptr, char **endptr, int base) |
| 53 | const char *nptr; | ||
| 54 | char **endptr; | ||
| 55 | register int base; | ||
| 56 | { | 46 | { |
| 57 | register const char *s = nptr; | 47 | const char *s; |
| 58 | register u_quad_t acc; | 48 | unsigned long long acc, cutoff; |
| 59 | register int c; | 49 | int c; |
| 60 | register u_quad_t qbase, cutoff; | 50 | int neg, any, cutlim; |
| 61 | register int neg, any, cutlim; | ||
| 62 | 51 | ||
| 63 | /* | 52 | /* |
| 64 | * See strtoq for comments as to the logic used. | 53 | * See strtoq for comments as to the logic used. |
| 65 | */ | 54 | */ |
| 66 | s = nptr; | 55 | s = nptr; |
| 67 | do { | 56 | do { |
| 68 | c = *s++; | 57 | c = (unsigned char) *s++; |
| 69 | } while (isspace(c)); | 58 | } while (isspace(c)); |
| 70 | if (c == '-') { | 59 | if (c == '-') { |
| 71 | neg = 1; | 60 | neg = 1; |
| @@ -83,10 +72,10 @@ strtouq(nptr, endptr, base) | |||
| 83 | } | 72 | } |
| 84 | if (base == 0) | 73 | if (base == 0) |
| 85 | base = c == '0' ? 8 : 10; | 74 | base = c == '0' ? 8 : 10; |
| 86 | qbase = (unsigned)base; | 75 | |
| 87 | cutoff = (u_quad_t)UQUAD_MAX / qbase; | 76 | cutoff = ULLONG_MAX / (unsigned long long)base; |
| 88 | cutlim = (u_quad_t)UQUAD_MAX % qbase; | 77 | cutlim = ULLONG_MAX % (unsigned long long)base; |
| 89 | for (acc = 0, any = 0;; c = *s++) { | 78 | for (acc = 0, any = 0;; c = (unsigned char) *s++) { |
| 90 | if (isdigit(c)) | 79 | if (isdigit(c)) |
| 91 | c -= '0'; | 80 | c -= '0'; |
| 92 | else if (isalpha(c)) | 81 | else if (isalpha(c)) |
| @@ -95,20 +84,23 @@ strtouq(nptr, endptr, base) | |||
| 95 | break; | 84 | break; |
| 96 | if (c >= base) | 85 | if (c >= base) |
| 97 | break; | 86 | break; |
| 98 | if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) | 87 | if (any < 0) |
| 88 | continue; | ||
| 89 | if (acc > cutoff || (acc == cutoff && c > cutlim)) { | ||
| 99 | any = -1; | 90 | any = -1; |
| 100 | else { | 91 | acc = ULLONG_MAX; |
| 92 | errno = ERANGE; | ||
| 93 | } else { | ||
| 101 | any = 1; | 94 | any = 1; |
| 102 | acc *= qbase; | 95 | acc *= (unsigned long long)base; |
| 103 | acc += c; | 96 | acc += c; |
| 104 | } | 97 | } |
| 105 | } | 98 | } |
| 106 | if (any < 0) { | 99 | if (neg && any > 0) |
| 107 | acc = UQUAD_MAX; | ||
| 108 | errno = ERANGE; | ||
| 109 | } else if (neg) | ||
| 110 | acc = -acc; | 100 | acc = -acc; |
| 111 | if (endptr != 0) | 101 | if (endptr != 0) |
| 112 | *endptr = (char *) (any ? s - 1 : nptr); | 102 | *endptr = (char *) (any ? s - 1 : nptr); |
| 113 | return (acc); | 103 | return (acc); |
| 114 | } | 104 | } |
| 105 | |||
| 106 | __strong_alias(strtouq, strtoull); | ||
diff --git a/src/lib/libc/stdlib/strtoumax.c b/src/lib/libc/stdlib/strtoumax.c new file mode 100644 index 0000000000..ce6e2c00f1 --- /dev/null +++ b/src/lib/libc/stdlib/strtoumax.c | |||
| @@ -0,0 +1,102 @@ | |||
| 1 | /* $OpenBSD: strtoumax.c,v 1.1 2006/01/13 17:58:09 millert Exp $ */ | ||
| 2 | |||
| 3 | /*- | ||
| 4 | * Copyright (c) 1992 The Regents of the University of California. | ||
| 5 | * All rights reserved. | ||
| 6 | * | ||
| 7 | * Redistribution and use in source and binary forms, with or without | ||
| 8 | * modification, are permitted provided that the following conditions | ||
| 9 | * are met: | ||
| 10 | * 1. Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 13 | * notice, this list of conditions and the following disclaimer in the | ||
| 14 | * documentation and/or other materials provided with the distribution. | ||
| 15 | * 3. Neither the name of the University nor the names of its contributors | ||
| 16 | * may be used to endorse or promote products derived from this software | ||
| 17 | * without specific prior written permission. | ||
| 18 | * | ||
| 19 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
| 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
| 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 29 | * SUCH DAMAGE. | ||
| 30 | */ | ||
| 31 | |||
| 32 | #include <ctype.h> | ||
| 33 | #include <errno.h> | ||
| 34 | #include <inttypes.h> | ||
| 35 | |||
| 36 | /* | ||
| 37 | * Convert a string to a uintmax_t. | ||
| 38 | * | ||
| 39 | * Ignores `locale' stuff. Assumes that the upper and lower case | ||
| 40 | * alphabets and digits are each contiguous. | ||
| 41 | */ | ||
| 42 | uintmax_t | ||
| 43 | strtoumax(const char *nptr, char **endptr, int base) | ||
| 44 | { | ||
| 45 | const char *s; | ||
| 46 | uintmax_t acc, cutoff; | ||
| 47 | int c; | ||
| 48 | int neg, any, cutlim; | ||
| 49 | |||
| 50 | /* | ||
| 51 | * See strtoq for comments as to the logic used. | ||
| 52 | */ | ||
| 53 | s = nptr; | ||
| 54 | do { | ||
| 55 | c = (unsigned char) *s++; | ||
| 56 | } while (isspace(c)); | ||
| 57 | if (c == '-') { | ||
| 58 | neg = 1; | ||
| 59 | c = *s++; | ||
| 60 | } else { | ||
| 61 | neg = 0; | ||
| 62 | if (c == '+') | ||
| 63 | c = *s++; | ||
| 64 | } | ||
| 65 | if ((base == 0 || base == 16) && | ||
| 66 | c == '0' && (*s == 'x' || *s == 'X')) { | ||
| 67 | c = s[1]; | ||
| 68 | s += 2; | ||
| 69 | base = 16; | ||
| 70 | } | ||
| 71 | if (base == 0) | ||
| 72 | base = c == '0' ? 8 : 10; | ||
| 73 | |||
| 74 | cutoff = UINTMAX_MAX / (uintmax_t)base; | ||
| 75 | cutlim = UINTMAX_MAX % (uintmax_t)base; | ||
| 76 | for (acc = 0, any = 0;; c = (unsigned char) *s++) { | ||
| 77 | if (isdigit(c)) | ||
| 78 | c -= '0'; | ||
| 79 | else if (isalpha(c)) | ||
| 80 | c -= isupper(c) ? 'A' - 10 : 'a' - 10; | ||
| 81 | else | ||
| 82 | break; | ||
| 83 | if (c >= base) | ||
| 84 | break; | ||
| 85 | if (any < 0) | ||
| 86 | continue; | ||
| 87 | if (acc > cutoff || (acc == cutoff && c > cutlim)) { | ||
| 88 | any = -1; | ||
| 89 | acc = UINTMAX_MAX; | ||
| 90 | errno = ERANGE; | ||
| 91 | } else { | ||
| 92 | any = 1; | ||
| 93 | acc *= (uintmax_t)base; | ||
| 94 | acc += c; | ||
| 95 | } | ||
| 96 | } | ||
| 97 | if (neg && any > 0) | ||
| 98 | acc = -acc; | ||
| 99 | if (endptr != 0) | ||
| 100 | *endptr = (char *) (any ? s - 1 : nptr); | ||
| 101 | return (acc); | ||
| 102 | } | ||
diff --git a/src/lib/libc/stdlib/system.3 b/src/lib/libc/stdlib/system.3 index 520f51db0a..878bb0a9d2 100644 --- a/src/lib/libc/stdlib/system.3 +++ b/src/lib/libc/stdlib/system.3 | |||
| @@ -13,11 +13,7 @@ | |||
| 13 | .\" 2. Redistributions in binary form must reproduce the above copyright | 13 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 14 | .\" notice, this list of conditions and the following disclaimer in the | 14 | .\" notice, this list of conditions and the following disclaimer in the |
| 15 | .\" documentation and/or other materials provided with the distribution. | 15 | .\" documentation and/or other materials provided with the distribution. |
| 16 | .\" 3. All advertising materials mentioning features or use of this software | 16 | .\" 3. Neither the name of the University nor the names of its contributors |
| 17 | .\" must display the following acknowledgement: | ||
| 18 | .\" This product includes software developed by the University of | ||
| 19 | .\" California, Berkeley and its contributors. | ||
| 20 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 21 | .\" may be used to endorse or promote products derived from this software | 17 | .\" may be used to endorse or promote products derived from this software |
| 22 | .\" without specific prior written permission. | 18 | .\" without specific prior written permission. |
| 23 | .\" | 19 | .\" |
| @@ -33,24 +29,22 @@ | |||
| 33 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 29 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 34 | .\" SUCH DAMAGE. | 30 | .\" SUCH DAMAGE. |
| 35 | .\" | 31 | .\" |
| 36 | .\" from: @(#)system.3 6.5 (Berkeley) 6/29/91 | 32 | .\" $OpenBSD: system.3,v 1.13 2013/07/18 10:14:50 schwarze Exp $ |
| 37 | .\" $Id: system.3,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $ | ||
| 38 | .\" | 33 | .\" |
| 39 | .Dd June 29, 1991 | 34 | .Dd $Mdocdate: July 18 2013 $ |
| 40 | .Dt SYSTEM 3 | 35 | .Dt SYSTEM 3 |
| 41 | .Os | 36 | .Os |
| 42 | .Sh NAME | 37 | .Sh NAME |
| 43 | .Nm system | 38 | .Nm system |
| 44 | .Nd pass a command to the shell | 39 | .Nd pass a command to the shell |
| 45 | .Sh SYNOPSIS | 40 | .Sh SYNOPSIS |
| 46 | .Fd #include <stdlib.h> | 41 | .In stdlib.h |
| 47 | .Ft int | 42 | .Ft int |
| 48 | .Fn system "const char *string" | 43 | .Fn system "const char *string" |
| 49 | .Sh DESCRIPTION | 44 | .Sh DESCRIPTION |
| 50 | The | 45 | The |
| 51 | .Fn system | 46 | .Fn system |
| 52 | function | 47 | function hands the argument |
| 53 | hands the argument | ||
| 54 | .Fa string | 48 | .Fa string |
| 55 | to the command interpreter | 49 | to the command interpreter |
| 56 | .Xr sh 1 . | 50 | .Xr sh 1 . |
| @@ -64,36 +58,52 @@ and blocking | |||
| 64 | .Pp | 58 | .Pp |
| 65 | If | 59 | If |
| 66 | .Fa string | 60 | .Fa string |
| 67 | is a | 61 | is |
| 68 | .Dv NULL | 62 | .Dv NULL , |
| 69 | pointer, | ||
| 70 | .Fn system | 63 | .Fn system |
| 71 | will return non-zero. | 64 | will return non-zero. |
| 72 | Otherwise, | 65 | Otherwise, |
| 73 | .Fn system | 66 | .Fn system |
| 74 | returns the termination status of the shell in the format specified by | 67 | returns the termination status of the shell in the format specified by |
| 75 | .Xr waitpid 3 . | 68 | .Xr waitpid 2 . |
| 76 | .Sh RETURN VALUES | 69 | .Pp |
| 70 | Note that fork handlers established using | ||
| 71 | .Xr pthread_atfork 3 | ||
| 72 | are not called when a multithreaded program calls | ||
| 73 | .Fn system . | ||
| 74 | .Sh RETURN VALUES | ||
| 77 | If a child process cannot be created, or the termination status of | 75 | If a child process cannot be created, or the termination status of |
| 78 | the shell cannot be obtained, | 76 | the shell cannot be obtained, |
| 79 | .Fn system | 77 | .Fn system |
| 80 | returns -1 and sets | 78 | returns \-1 and sets |
| 81 | .Va errno | 79 | .Va errno |
| 82 | to indicate the error. | 80 | to indicate the error. |
| 83 | If execution of the shell fails, | 81 | If execution of the shell fails, |
| 84 | .Fn system | 82 | .Fn system |
| 85 | returns the termination status for a program that terminates with a call of | 83 | returns the termination status for a program that terminates with a call of |
| 86 | .Fn exit 127 . | 84 | .Fn exit 127 . |
| 87 | .Sh SEE ALSO | 85 | .Sh SEE ALSO |
| 88 | .Xr sh 1 , | 86 | .Xr sh 1 , |
| 89 | .Xr execve 2 , | 87 | .Xr execve 2 , |
| 90 | .Xr popen 3 , | 88 | .Xr waitpid 2 , |
| 91 | .Xr waitpid 3 , | 89 | .Xr popen 3 |
| 92 | .Sh STANDARDS | 90 | .Sh STANDARDS |
| 93 | The | 91 | The |
| 94 | .Fn system | 92 | .Fn system |
| 95 | function | 93 | function conforms to |
| 96 | conforms to | 94 | .St -ansiC |
| 97 | .St -ansiC | ||
| 98 | and | 95 | and |
| 99 | .St -1003.2-92 . | 96 | .St -p1003.2-92 . |
| 97 | .Sh HISTORY | ||
| 98 | The | ||
| 99 | .Fn system | ||
| 100 | function first appeared in | ||
| 101 | .At v6 . | ||
| 102 | .Sh CAVEATS | ||
| 103 | Never supply the | ||
| 104 | .Fn system | ||
| 105 | function with a command containing any part of an unsanitized user-supplied | ||
| 106 | string. | ||
| 107 | Shell meta-characters present will be honored by the | ||
| 108 | .Xr sh 1 | ||
| 109 | command interpreter. | ||
diff --git a/src/lib/libc/stdlib/system.c b/src/lib/libc/stdlib/system.c index c2f39325f6..14ddcae8d3 100644 --- a/src/lib/libc/stdlib/system.c +++ b/src/lib/libc/stdlib/system.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: system.c,v 1.8 2005/08/08 08:05:37 espie Exp $ */ | ||
| 1 | /* | 2 | /* |
| 2 | * Copyright (c) 1988 The Regents of the University of California. | 3 | * Copyright (c) 1988 The Regents of the University of California. |
| 3 | * All rights reserved. | 4 | * All rights reserved. |
| @@ -10,11 +11,7 @@ | |||
| 10 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the |
| 12 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. Neither the name of the University nor the names of its contributors |
| 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 | 15 | * may be used to endorse or promote products derived from this software |
| 19 | * without specific prior written permission. | 16 | * without specific prior written permission. |
| 20 | * | 17 | * |
| @@ -31,11 +28,6 @@ | |||
| 31 | * SUCH DAMAGE. | 28 | * SUCH DAMAGE. |
| 32 | */ | 29 | */ |
| 33 | 30 | ||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 35 | /*static char *sccsid = "from: @(#)system.c 5.10 (Berkeley) 2/23/91";*/ | ||
| 36 | static char *rcsid = "$Id: system.c,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $"; | ||
| 37 | #endif /* LIBC_SCCS and not lint */ | ||
| 38 | |||
| 39 | #include <sys/types.h> | 31 | #include <sys/types.h> |
| 40 | #include <sys/wait.h> | 32 | #include <sys/wait.h> |
| 41 | #include <signal.h> | 33 | #include <signal.h> |
| @@ -46,25 +38,28 @@ static char *rcsid = "$Id: system.c,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $" | |||
| 46 | extern char **environ; | 38 | extern char **environ; |
| 47 | 39 | ||
| 48 | int | 40 | int |
| 49 | system(command) | 41 | system(const char *command) |
| 50 | const char *command; | ||
| 51 | { | 42 | { |
| 52 | pid_t pid; | 43 | pid_t pid; |
| 53 | sig_t intsave, quitsave; | 44 | sig_t intsave, quitsave; |
| 54 | int omask; | 45 | sigset_t mask, omask; |
| 55 | int pstat; | 46 | int pstat; |
| 56 | char *argp[] = {"sh", "-c", (char *) command, NULL}; | 47 | char *argp[] = {"sh", "-c", NULL, NULL}; |
| 57 | 48 | ||
| 58 | if (!command) /* just checking... */ | 49 | if (!command) /* just checking... */ |
| 59 | return(1); | 50 | return(1); |
| 60 | 51 | ||
| 61 | omask = sigblock(sigmask(SIGCHLD)); | 52 | argp[2] = (char *)command; |
| 62 | switch(pid = vfork()) { | 53 | |
| 54 | sigemptyset(&mask); | ||
| 55 | sigaddset(&mask, SIGCHLD); | ||
| 56 | sigprocmask(SIG_BLOCK, &mask, &omask); | ||
| 57 | switch (pid = vfork()) { | ||
| 63 | case -1: /* error */ | 58 | case -1: /* error */ |
| 64 | (void)sigsetmask(omask); | 59 | sigprocmask(SIG_SETMASK, &omask, NULL); |
| 65 | return(-1); | 60 | return(-1); |
| 66 | case 0: /* child */ | 61 | case 0: /* child */ |
| 67 | (void)sigsetmask(omask); | 62 | sigprocmask(SIG_SETMASK, &omask, NULL); |
| 68 | execve(_PATH_BSHELL, argp, environ); | 63 | execve(_PATH_BSHELL, argp, environ); |
| 69 | _exit(127); | 64 | _exit(127); |
| 70 | } | 65 | } |
| @@ -72,8 +67,8 @@ system(command) | |||
| 72 | intsave = signal(SIGINT, SIG_IGN); | 67 | intsave = signal(SIGINT, SIG_IGN); |
| 73 | quitsave = signal(SIGQUIT, SIG_IGN); | 68 | quitsave = signal(SIGQUIT, SIG_IGN); |
| 74 | pid = waitpid(pid, (int *)&pstat, 0); | 69 | pid = waitpid(pid, (int *)&pstat, 0); |
| 75 | (void)sigsetmask(omask); | 70 | sigprocmask(SIG_SETMASK, &omask, NULL); |
| 76 | (void)signal(SIGINT, intsave); | 71 | (void)signal(SIGINT, intsave); |
| 77 | (void)signal(SIGQUIT, quitsave); | 72 | (void)signal(SIGQUIT, quitsave); |
| 78 | return(pid == -1 ? -1 : pstat); | 73 | return (pid == -1 ? -1 : pstat); |
| 79 | } | 74 | } |
diff --git a/src/lib/libc/stdlib/tfind.c b/src/lib/libc/stdlib/tfind.c new file mode 100644 index 0000000000..0d1d5196d8 --- /dev/null +++ b/src/lib/libc/stdlib/tfind.c | |||
| @@ -0,0 +1,41 @@ | |||
| 1 | /* $OpenBSD: tfind.c,v 1.6 2014/03/16 18:38:30 guenther Exp $ */ | ||
| 2 | |||
| 3 | /* | ||
| 4 | * Tree search generalized from Knuth (6.2.2) Algorithm T just like | ||
| 5 | * the AT&T man page says. | ||
| 6 | * | ||
| 7 | * The node_t structure is for internal use only | ||
| 8 | * | ||
| 9 | * Written by reading the System V Interface Definition, not the code. | ||
| 10 | * | ||
| 11 | * Totally public domain. | ||
| 12 | */ | ||
| 13 | /*LINTLIBRARY*/ | ||
| 14 | #include <search.h> | ||
| 15 | |||
| 16 | typedef struct node_t | ||
| 17 | { | ||
| 18 | char *key; | ||
| 19 | struct node_t *llink, *rlink; | ||
| 20 | } node; | ||
| 21 | |||
| 22 | /* find a node, or return 0 */ | ||
| 23 | void * | ||
| 24 | tfind(const void *vkey, void * const *vrootp, | ||
| 25 | int (*compar)(const void *, const void *)) | ||
| 26 | { | ||
| 27 | char *key = (char *)vkey; | ||
| 28 | node **rootp = (node **)vrootp; | ||
| 29 | |||
| 30 | if (rootp == (struct node_t **)0) | ||
| 31 | return ((struct node_t *)0); | ||
| 32 | while (*rootp != (struct node_t *)0) { /* T1: */ | ||
| 33 | int r; | ||
| 34 | if ((r = (*compar)(key, (*rootp)->key)) == 0) /* T2: */ | ||
| 35 | return (*rootp); /* key found */ | ||
| 36 | rootp = (r < 0) ? | ||
| 37 | &(*rootp)->llink : /* T3: follow left branch */ | ||
| 38 | &(*rootp)->rlink; /* T4: follow right branch */ | ||
| 39 | } | ||
| 40 | return (node *)0; | ||
| 41 | } | ||
diff --git a/src/lib/libc/stdlib/tsearch.3 b/src/lib/libc/stdlib/tsearch.3 new file mode 100644 index 0000000000..46d0bba10c --- /dev/null +++ b/src/lib/libc/stdlib/tsearch.3 | |||
| @@ -0,0 +1,130 @@ | |||
| 1 | .\" $OpenBSD: tsearch.3,v 1.19 2013/06/05 03:39:23 tedu Exp $ | ||
| 2 | .\" | ||
| 3 | .\" Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com> | ||
| 4 | .\" | ||
| 5 | .\" Permission to use, copy, modify, and distribute this software for any | ||
| 6 | .\" purpose with or without fee is hereby granted, provided that the above | ||
| 7 | .\" copyright notice and this permission notice appear in all copies. | ||
| 8 | .\" | ||
| 9 | .\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 10 | .\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 11 | .\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 12 | .\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 13 | .\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 14 | .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 15 | .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 16 | .\" | ||
| 17 | .Dd $Mdocdate: June 5 2013 $ | ||
| 18 | .Dt TSEARCH 3 | ||
| 19 | .Os | ||
| 20 | .Sh NAME | ||
| 21 | .Nm tsearch , | ||
| 22 | .Nm tfind , | ||
| 23 | .Nm tdelete , | ||
| 24 | .Nm twalk | ||
| 25 | .Nd manipulate binary search trees | ||
| 26 | .Sh SYNOPSIS | ||
| 27 | .In search.h | ||
| 28 | .Ft void * | ||
| 29 | .Fn tdelete "const void *key" "void **rootp" "int (*compar)(const void *, const void *)" | ||
| 30 | .Ft void * | ||
| 31 | .Fn tfind "const void *key" "void * const *rootp" "int (*compar)(const void *, const void *)" | ||
| 32 | .Ft void * | ||
| 33 | .Fn tsearch "const void *key" "void **rootp" "int (*compar)(const void *, const void *)" | ||
| 34 | .Ft void | ||
| 35 | .Fn twalk "const void *root" "void (*action)(const void *, VISIT, int)" | ||
| 36 | .Sh DESCRIPTION | ||
| 37 | The | ||
| 38 | .Fn tdelete , | ||
| 39 | .Fn tfind , | ||
| 40 | .Fn tsearch , | ||
| 41 | and | ||
| 42 | .Fn twalk | ||
| 43 | functions manage binary search trees based on algorithms T and D | ||
| 44 | from Knuth (6.2.2). | ||
| 45 | The comparison function passed in by | ||
| 46 | the user has the same style of return values as | ||
| 47 | .Xr strcmp 3 . | ||
| 48 | .Pp | ||
| 49 | .Fn tfind | ||
| 50 | searches for the datum matched by the argument | ||
| 51 | .Fa key | ||
| 52 | in the binary tree rooted at | ||
| 53 | .Fa rootp , | ||
| 54 | returning a pointer to the datum if it is found and | ||
| 55 | .Dv NULL | ||
| 56 | if it is not. | ||
| 57 | .Pp | ||
| 58 | .Fn tsearch | ||
| 59 | is identical to | ||
| 60 | .Fn tfind | ||
| 61 | except that if no match is found, | ||
| 62 | .Fa key | ||
| 63 | is inserted into the tree and a pointer to it is returned. | ||
| 64 | If | ||
| 65 | .Fa rootp | ||
| 66 | points to a null value a new binary search tree is created. | ||
| 67 | .Pp | ||
| 68 | .Fn tdelete | ||
| 69 | deletes a node from the specified binary search tree and returns | ||
| 70 | a pointer to the parent of the node to be deleted. | ||
| 71 | If the node to be deleted is the root of the binary search tree, | ||
| 72 | .Fa rootp | ||
| 73 | will be adjusted and an unspecified non-null pointer will be returned. | ||
| 74 | It takes the same arguments as | ||
| 75 | .Fn tfind | ||
| 76 | and | ||
| 77 | .Fn tsearch . | ||
| 78 | .Pp | ||
| 79 | .Fn twalk | ||
| 80 | walks the binary search tree rooted in | ||
| 81 | .Fa root | ||
| 82 | and calls the function | ||
| 83 | .Fa action | ||
| 84 | on each node. | ||
| 85 | .Fa action | ||
| 86 | is called with three arguments: a pointer to the current node, | ||
| 87 | a value from the enum | ||
| 88 | .Sy "typedef enum { preorder, postorder, endorder, leaf } VISIT;" | ||
| 89 | specifying the traversal type, and a node level (where level | ||
| 90 | zero is the root of the tree). | ||
| 91 | .Sh RETURN VALUES | ||
| 92 | The | ||
| 93 | .Fn tsearch | ||
| 94 | function returns | ||
| 95 | .Dv NULL | ||
| 96 | if allocation of a new node fails (usually | ||
| 97 | due to a lack of free memory). | ||
| 98 | .Pp | ||
| 99 | .Fn tdelete | ||
| 100 | returns a pointer to the parent of the deleted node or an unspecified | ||
| 101 | non-null pointer if the root node is deleted. | ||
| 102 | .Pp | ||
| 103 | .Fn tfind , | ||
| 104 | .Fn tsearch , | ||
| 105 | and | ||
| 106 | .Fn tdelete | ||
| 107 | return | ||
| 108 | .Dv NULL | ||
| 109 | if | ||
| 110 | .Fa rootp | ||
| 111 | is | ||
| 112 | .Dv NULL | ||
| 113 | or the datum cannot be found. | ||
| 114 | .Pp | ||
| 115 | The | ||
| 116 | .Fn twalk | ||
| 117 | function returns no value. | ||
| 118 | .Sh SEE ALSO | ||
| 119 | .Xr bsearch 3 , | ||
| 120 | .Xr lsearch 3 | ||
| 121 | .Sh STANDARDS | ||
| 122 | These functions conform to | ||
| 123 | .St -p1003.1-2008 . | ||
| 124 | .Sh CAVEATS | ||
| 125 | The value returned when deleting the root node was unspecified before | ||
| 126 | the | ||
| 127 | .St -p1003.1-2008 | ||
| 128 | standard, so users of the | ||
| 129 | .Fn tdelete | ||
| 130 | function should be wary of relying on a specific behaviour. | ||
diff --git a/src/lib/libc/stdlib/tsearch.c b/src/lib/libc/stdlib/tsearch.c new file mode 100644 index 0000000000..a141085d2b --- /dev/null +++ b/src/lib/libc/stdlib/tsearch.c | |||
| @@ -0,0 +1,119 @@ | |||
| 1 | /* $OpenBSD: tsearch.c,v 1.8 2014/03/16 18:38:30 guenther Exp $ */ | ||
| 2 | |||
| 3 | /* | ||
| 4 | * Tree search generalized from Knuth (6.2.2) Algorithm T just like | ||
| 5 | * the AT&T man page says. | ||
| 6 | * | ||
| 7 | * The node_t structure is for internal use only | ||
| 8 | * | ||
| 9 | * Written by reading the System V Interface Definition, not the code. | ||
| 10 | * | ||
| 11 | * Totally public domain. | ||
| 12 | */ | ||
| 13 | /*LINTLIBRARY*/ | ||
| 14 | |||
| 15 | #include <search.h> | ||
| 16 | #include <stdlib.h> | ||
| 17 | |||
| 18 | typedef struct node_t { | ||
| 19 | char *key; | ||
| 20 | struct node_t *left, *right; | ||
| 21 | } node; | ||
| 22 | |||
| 23 | /* find or insert datum into search tree */ | ||
| 24 | void * | ||
| 25 | tsearch(const void *vkey, void **vrootp, | ||
| 26 | int (*compar)(const void *, const void *)) | ||
| 27 | { | ||
| 28 | 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 */ | ||
| 53 | void * | ||
| 54 | tdelete(const void *vkey, void **vrootp, | ||
| 55 | int (*compar)(const void *, const void *)) | ||
| 56 | { | ||
| 57 | node **rootp = (node **)vrootp; | ||
| 58 | char *key = (char *)vkey; | ||
| 59 | node *p = (node *)1; | ||
| 60 | node *q; | ||
| 61 | node *r; | ||
| 62 | int cmp; | ||
| 63 | |||
| 64 | if (rootp == (struct node_t **)0 || *rootp == (struct node_t *)0) | ||
| 65 | return ((struct node_t *)0); | ||
| 66 | while ((cmp = (*compar)(key, (*rootp)->key)) != 0) { | ||
| 67 | p = *rootp; | ||
| 68 | rootp = (cmp < 0) ? | ||
| 69 | &(*rootp)->left : /* follow left branch */ | ||
| 70 | &(*rootp)->right; /* follow right branch */ | ||
| 71 | if (*rootp == (struct node_t *)0) | ||
| 72 | return ((void *)0); /* key not found */ | ||
| 73 | } | ||
| 74 | r = (*rootp)->right; /* D1: */ | ||
| 75 | if ((q = (*rootp)->left) == (struct node_t *)0) /* Left (struct node_t *)0? */ | ||
| 76 | q = r; | ||
| 77 | else if (r != (struct node_t *)0) { /* Right link is null? */ | ||
| 78 | if (r->left == (struct node_t *)0) { /* D2: Find successor */ | ||
| 79 | r->left = q; | ||
| 80 | q = r; | ||
| 81 | } else { /* D3: Find (struct node_t *)0 link */ | ||
| 82 | for (q = r->left; q->left != (struct node_t *)0; q = r->left) | ||
| 83 | r = q; | ||
| 84 | r->left = q->right; | ||
| 85 | q->left = (*rootp)->left; | ||
| 86 | q->right = (*rootp)->right; | ||
| 87 | } | ||
| 88 | } | ||
| 89 | free((struct node_t *) *rootp); /* D4: Free node */ | ||
| 90 | *rootp = q; /* link parent to new node */ | ||
| 91 | return(p); | ||
| 92 | } | ||
| 93 | |||
| 94 | /* Walk the nodes of a tree */ | ||
| 95 | static void | ||
| 96 | trecurse(node *root, void (*action)(const void *, VISIT, int), int level) | ||
| 97 | { | ||
| 98 | if (root->left == (struct node_t *)0 && root->right == (struct node_t *)0) | ||
| 99 | (*action)(root, leaf, level); | ||
| 100 | else { | ||
| 101 | (*action)(root, preorder, level); | ||
| 102 | if (root->left != (struct node_t *)0) | ||
| 103 | trecurse(root->left, action, level + 1); | ||
| 104 | (*action)(root, postorder, level); | ||
| 105 | if (root->right != (struct node_t *)0) | ||
| 106 | trecurse(root->right, action, level + 1); | ||
| 107 | (*action)(root, endorder, level); | ||
| 108 | } | ||
| 109 | } | ||
| 110 | |||
| 111 | /* Walk the nodes of a tree */ | ||
| 112 | void | ||
| 113 | twalk(const void *vroot, void (*action)(const void *, VISIT, int)) | ||
| 114 | { | ||
| 115 | node *root = (node *)vroot; | ||
| 116 | |||
| 117 | if (root != (node *)0 && action != (void (*)(const void *, VISIT, int))0) | ||
| 118 | trecurse(root, action, 0); | ||
| 119 | } | ||
diff --git a/src/lib/libc/string/Makefile.inc b/src/lib/libc/string/Makefile.inc index 2b7ce63a63..1f6d756182 100644 --- a/src/lib/libc/string/Makefile.inc +++ b/src/lib/libc/string/Makefile.inc | |||
| @@ -1,40 +1,56 @@ | |||
| 1 | # from: @(#)Makefile.inc 5.6 (Berkeley) 3/5/91 | 1 | # $OpenBSD: Makefile.inc,v 1.34 2014/03/23 23:16:48 tedu Exp $ |
| 2 | # $Id: Makefile.inc,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $ | ||
| 3 | 2 | ||
| 4 | # string sources | 3 | # string sources |
| 5 | .PATH: ${.CURDIR}/arch/${MACHINE_ARCH}/string ${.CURDIR}/string | 4 | .PATH: ${LIBCSRCDIR}/arch/${MACHINE_CPU}/string ${LIBCSRCDIR}/string |
| 6 | 5 | ||
| 7 | SRCS+= bm.c memccpy.c strcasecmp.c strcoll.c strdup.c strerror.c \ | 6 | SRCS+= explicit_bzero.c memccpy.c memmem.c memrchr.c stpcpy.c stpncpy.c \ |
| 8 | strftime.c strmode.c strsignal.c strtok.c strxfrm.c \ | 7 | strcasecmp.c strcasestr.c strcoll.c strdup.c \ |
| 9 | __strerror.c __strsignal.c | 8 | strerror.c strerror_r.c strlcat.c strmode.c strndup.c strnlen.c \ |
| 9 | strsignal.c strtok.c strxfrm.c \ | ||
| 10 | wcscat.c wcschr.c wcscmp.c wcscpy.c wcscspn.c wcslcat.c wcslcpy.c \ | ||
| 11 | wcslen.c wcsncat.c wcsncmp.c wcsncpy.c wcspbrk.c wcsrchr.c wcsspn.c \ | ||
| 12 | wcsstr.c wcstok.c wcswcs.c wcswidth.c wmemchr.c wmemcmp.c wmemcpy.c \ | ||
| 13 | wmemmove.c wmemset.c wcsdup.c \ | ||
| 14 | timingsafe_bcmp.c wcscasecmp.c | ||
| 10 | 15 | ||
| 11 | # machine-dependent net sources | 16 | # machine-dependent net sources |
| 12 | # m-d Makefile.inc must include sources for: | 17 | # m-d Makefile.inc must include sources for: |
| 13 | # bcmp() bcopy() bzero() ffs() index() memchr() memcmp() memset() | 18 | # bcmp() bcopy() bzero() ffs() index() memchr() memcmp() memset() |
| 14 | # rindex() strcat() strcmp() strcpy() strcspn() strlen() | 19 | # rindex() strcat() strcmp() strcpy() strcspn() strlen() strlcpy() |
| 15 | # strncat() strncmp() strncpy() strpbrk() strsep() | 20 | # strncat() strncmp() strncpy() strpbrk() strsep() |
| 16 | # strspn() strstr() swav() | 21 | # strspn() strstr() swav() |
| 17 | # m-d Makefile.inc may include sources for: | 22 | # m-d Makefile.inc may include sources for: |
| 18 | # memcpy() memmove() strchr() strrchr() | 23 | # memcpy() memmove() strchr() strrchr() |
| 19 | 24 | ||
| 20 | .include "${.CURDIR}/arch/${MACHINE_ARCH}/string/Makefile.inc" | 25 | .include "${LIBCSRCDIR}/arch/${MACHINE_CPU}/string/Makefile.inc" |
| 21 | 26 | ||
| 22 | # if no machine specific memmove(3), build one out of bcopy(3). | 27 | # if no machine specific memmove(3), build one out of bcopy(3). |
| 23 | .if empty(SRCS:Mmemmove.S) | 28 | .if empty(SRCS:Mmemmove.S) |
| 24 | OBJS+= memmove.o | 29 | OBJS+= memmove.o |
| 25 | memmove.o: bcopy.c | 30 | memmove.o: bcopy.c |
| 26 | ${CC} -DMEMMOVE ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} -o ${.TARGET} | 31 | ${CC} -DMEMMOVE ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} -o ${.TARGET} |
| 27 | @${LD} -x -r ${.TARGET} | 32 | @${LD} -o ${.TARGET}.tmp -x -r ${.TARGET} |
| 28 | @mv a.out ${.TARGET} | 33 | @mv ${.TARGET}.tmp ${.TARGET} |
| 34 | |||
| 35 | memmove.go: bcopy.c | ||
| 36 | ${CC} -g -DMEMMOVE ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} -o ${.TARGET} | ||
| 37 | @${LD} -o ${.TARGET}.tmp -x -r ${.TARGET} | ||
| 38 | @mv ${.TARGET}.tmp ${.TARGET} | ||
| 29 | 39 | ||
| 30 | memmove.po: bcopy.c | 40 | memmove.po: bcopy.c |
| 31 | ${CC} -DMEMMOVE ${CFLAGS} ${CPPFLAGS} -c -p ${.ALLSRC} -o ${.TARGET} | 41 | ${CC} -DMEMMOVE ${CFLAGS} ${CPPFLAGS} -c -p ${.ALLSRC} -o ${.TARGET} |
| 32 | @${LD} -X -r ${.TARGET} | 42 | @${LD} -o ${.TARGET}.tmp -X -r ${.TARGET} |
| 33 | @mv a.out ${.TARGET} | 43 | @mv ${.TARGET}.tmp ${.TARGET} |
| 34 | 44 | ||
| 35 | memmove.so: bcopy.c | 45 | memmove.so: bcopy.c |
| 36 | ${CC} ${PICFLAG} -DPIC -DMEMMOVE ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} \ | 46 | ${CC} ${PICFLAG} -DPIC -DMEMMOVE ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} \ |
| 37 | -o ${.TARGET} | 47 | -o ${.TARGET} |
| 48 | |||
| 49 | memmove.do: bcopy.c | ||
| 50 | ${CC} -DMEMMOVE ${CFLAGS} ${CPPFLAGS} ${DIST_CFLAGS} -c ${.ALLSRC} \ | ||
| 51 | -o ${.TARGET} | ||
| 52 | @${LD} -o ${.TARGET}.tmp -x -r ${.TARGET} | ||
| 53 | @mv ${.TARGET}.tmp ${.TARGET} | ||
| 38 | .endif | 54 | .endif |
| 39 | 55 | ||
| 40 | # if no machine specific memcpy(3), build one out of bcopy(3). | 56 | # if no machine specific memcpy(3), build one out of bcopy(3). |
| @@ -45,17 +61,28 @@ memmove.so: bcopy.c | |||
| 45 | OBJS+= memcpy.o | 61 | OBJS+= memcpy.o |
| 46 | memcpy.o: bcopy.c | 62 | memcpy.o: bcopy.c |
| 47 | ${CC} -DMEMCOPY ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} -o ${.TARGET} | 63 | ${CC} -DMEMCOPY ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} -o ${.TARGET} |
| 48 | @${LD} -x -r ${.TARGET} | 64 | @${LD} -o ${.TARGET}.tmp -x -r ${.TARGET} |
| 49 | @mv a.out ${.TARGET} | 65 | @mv ${.TARGET}.tmp ${.TARGET} |
| 66 | |||
| 67 | memcpy.go: bcopy.c | ||
| 68 | ${CC} -g -DMEMCOPY ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} -o ${.TARGET} | ||
| 69 | @${LD} -o ${.TARGET}.tmp -x -r ${.TARGET} | ||
| 70 | @mv ${.TARGET}.tmp ${.TARGET} | ||
| 50 | 71 | ||
| 51 | memcpy.po: bcopy.c | 72 | memcpy.po: bcopy.c |
| 52 | ${CC} -DMEMCOPY ${CFLAGS} ${CPPFLAGS} -c -p ${.ALLSRC} -o ${.TARGET} | 73 | ${CC} -DMEMCOPY ${CFLAGS} ${CPPFLAGS} -c -p ${.ALLSRC} -o ${.TARGET} |
| 53 | @${LD} -X -r ${.TARGET} | 74 | @${LD} -o ${.TARGET}.tmp -X -r ${.TARGET} |
| 54 | @mv a.out ${.TARGET} | 75 | @mv ${.TARGET}.tmp ${.TARGET} |
| 55 | 76 | ||
| 56 | memcpy.so: bcopy.c | 77 | memcpy.so: bcopy.c |
| 57 | ${CC} ${PICFLAG} -DPIC -DMEMCOPY ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} \ | 78 | ${CC} ${PICFLAG} -DPIC -DMEMCOPY ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} \ |
| 58 | -o ${.TARGET} | 79 | -o ${.TARGET} |
| 80 | |||
| 81 | memcpy.do: bcopy.c | ||
| 82 | ${CC} -DMEMCOPY ${CFLAGS} ${CPPFLAGS} ${DIST_CFLAGS} -c ${.ALLSRC} \ | ||
| 83 | -o ${.TARGET} | ||
| 84 | @${LD} -o ${.TARGET}.tmp -x -r ${.TARGET} | ||
| 85 | @mv ${.TARGET}.tmp ${.TARGET} | ||
| 59 | .endif | 86 | .endif |
| 60 | .endif | 87 | .endif |
| 61 | 88 | ||
| @@ -64,17 +91,28 @@ memcpy.so: bcopy.c | |||
| 64 | OBJS+= strchr.o | 91 | OBJS+= strchr.o |
| 65 | strchr.o: index.c | 92 | strchr.o: index.c |
| 66 | ${CC} -DSTRCHR ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} -o ${.TARGET} | 93 | ${CC} -DSTRCHR ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} -o ${.TARGET} |
| 67 | @${LD} -x -r ${.TARGET} | 94 | @${LD} -o ${.TARGET}.tmp -x -r ${.TARGET} |
| 68 | @mv a.out ${.TARGET} | 95 | @mv ${.TARGET}.tmp ${.TARGET} |
| 96 | |||
| 97 | strchr.go: index.c | ||
| 98 | ${CC} -g -DSTRCHR ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} -o ${.TARGET} | ||
| 99 | @${LD} -o ${.TARGET}.tmp -x -r ${.TARGET} | ||
| 100 | @mv ${.TARGET}.tmp ${.TARGET} | ||
| 69 | 101 | ||
| 70 | strchr.po: index.c | 102 | strchr.po: index.c |
| 71 | ${CC} -DSTRCHR ${CFLAGS} ${CPPFLAGS} -c -p ${.ALLSRC} -o ${.TARGET} | 103 | ${CC} -DSTRCHR ${CFLAGS} ${CPPFLAGS} -c -p ${.ALLSRC} -o ${.TARGET} |
| 72 | @${LD} -X -r ${.TARGET} | 104 | @${LD} -o ${.TARGET}.tmp -X -r ${.TARGET} |
| 73 | @mv a.out ${.TARGET} | 105 | @mv ${.TARGET}.tmp ${.TARGET} |
| 74 | 106 | ||
| 75 | strchr.so: index.c | 107 | strchr.so: index.c |
| 76 | ${CC} ${PICFLAG} -DPIC -DSTRCHR ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} \ | 108 | ${CC} ${PICFLAG} -DPIC -DSTRCHR ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} \ |
| 77 | -o ${.TARGET} | 109 | -o ${.TARGET} |
| 110 | |||
| 111 | strchr.do: index.c | ||
| 112 | ${CC} -DSTRCHR ${CFLAGS} ${CPPFLAGS} ${DIST_CFLAGS} -c ${.ALLSRC} \ | ||
| 113 | -o ${.TARGET} | ||
| 114 | @${LD} -o ${.TARGET}.tmp -x -r ${.TARGET} | ||
| 115 | @mv ${.TARGET}.tmp ${.TARGET} | ||
| 78 | .endif | 116 | .endif |
| 79 | 117 | ||
| 80 | # if no machine specific strrchr(3), build one out of rindex(3). | 118 | # if no machine specific strrchr(3), build one out of rindex(3). |
| @@ -82,27 +120,56 @@ strchr.so: index.c | |||
| 82 | OBJS+= strrchr.o | 120 | OBJS+= strrchr.o |
| 83 | strrchr.o: rindex.c | 121 | strrchr.o: rindex.c |
| 84 | ${CC} -DSTRRCHR ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} -o ${.TARGET} | 122 | ${CC} -DSTRRCHR ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} -o ${.TARGET} |
| 85 | @${LD} -x -r ${.TARGET} | 123 | @${LD} -o ${.TARGET}.tmp -x -r ${.TARGET} |
| 86 | @mv a.out ${.TARGET} | 124 | @mv ${.TARGET}.tmp ${.TARGET} |
| 125 | |||
| 126 | strrchr.go: rindex.c | ||
| 127 | ${CC} -g -DSTRRCHR ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} -o ${.TARGET} | ||
| 128 | @${LD} -o ${.TARGET}.tmp -x -r ${.TARGET} | ||
| 129 | @mv ${.TARGET}.tmp ${.TARGET} | ||
| 87 | 130 | ||
| 88 | strrchr.po: rindex.c | 131 | strrchr.po: rindex.c |
| 89 | ${CC} -DSTRRCHR ${CFLAGS} ${CPPFLAGS} -c -p ${.ALLSRC} -o ${.TARGET} | 132 | ${CC} -DSTRRCHR ${CFLAGS} ${CPPFLAGS} -c -p ${.ALLSRC} -o ${.TARGET} |
| 90 | @${LD} -X -r ${.TARGET} | 133 | @${LD} -o ${.TARGET}.tmp -X -r ${.TARGET} |
| 91 | @mv a.out ${.TARGET} | 134 | @mv ${.TARGET}.tmp ${.TARGET} |
| 92 | 135 | ||
| 93 | strrchr.so: rindex.c | 136 | strrchr.so: rindex.c |
| 94 | ${CC} ${PICFLAG} -DPIC -DSTRRCHR ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} \ | 137 | ${CC} ${PICFLAG} -DPIC -DSTRRCHR ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} \ |
| 95 | -o ${.TARGET} | 138 | -o ${.TARGET} |
| 96 | .endif | ||
| 97 | 139 | ||
| 98 | MAN+= bm.3 bcmp.3 bcopy.3 bstring.3 bzero.3 ffs.3 index.3 memccpy.3 memchr.3 \ | 140 | strrchr.do: rindex.c |
| 99 | memcmp.3 memcpy.3 memmove.3 memset.3 rindex.3 strcasecmp.3 strcat.3 \ | 141 | ${CC} -DSTRRCHR ${CFLAGS} ${CPPFLAGS} ${DIST_CFLAGS} -c ${.ALLSRC} \ |
| 100 | strchr.3 strcmp.3 strcoll.3 strcpy.3 strcspn.3 strerror.3 strftime.3 \ | 142 | -o ${.TARGET} |
| 101 | string.3 strlen.3 strmode.3 strdup.3 strpbrk.3 strrchr.3 strsep.3 \ | 143 | @${LD} -o ${.TARGET}.tmp -x -r ${.TARGET} |
| 102 | strsignal.3 strspn.3 strstr.3 strtok.3 strxfrm.3 swab.3 | 144 | @mv ${.TARGET}.tmp ${.TARGET} |
| 145 | .endif | ||
| 103 | 146 | ||
| 104 | MLINKS+=bm.3 bm_comp.3 bm.3 bm_exec.3 bm.3 bm_free.3 | 147 | MAN+= bcmp.3 bcopy.3 bstring.3 bzero.3 ffs.3 memccpy.3 memchr.3 \ |
| 148 | memcmp.3 memcpy.3 memmem.3 memmove.3 memset.3 stpcpy.3 strcasecmp.3 \ | ||
| 149 | strcat.3 strchr.3 strcmp.3 strcoll.3 strcpy.3 strcspn.3 strdup.3 \ | ||
| 150 | strerror.3 string.3 strlen.3 strmode.3 strncat.3 strncpy.3 strpbrk.3 \ | ||
| 151 | strrchr.3 strsep.3 strsignal.3 strspn.3 strstr.3 strtok.3 strxfrm.3 \ | ||
| 152 | swab.3 strlcpy.3 wcscasecmp.3 wcscat.3 wcschr.3 wcscmp.3 wcscpy.3 \ | ||
| 153 | wcscspn.3 wcsdup.3 wcslcpy.3 wcslen.3 wcspbrk.3 wcsrchr.3 wcsspn.3 \ | ||
| 154 | wcsstr.3 wcstok.3 wcswidth.3 wmemchr.3 wmemcmp.3 wmemcpy.3 wmemmove.3 \ | ||
| 155 | wmemset.3 | ||
| 156 | |||
| 157 | MLINKS+=bzero.3 explicit_bzero.3 | ||
| 158 | MLINKS+=memchr.3 memrchr.3 | ||
| 159 | MLINKS+=stpcpy.3 stpncpy.3 | ||
| 160 | MLINKS+=strchr.3 index.3 | ||
| 161 | MLINKS+=strrchr.3 rindex.3 | ||
| 105 | MLINKS+=strcasecmp.3 strncasecmp.3 | 162 | MLINKS+=strcasecmp.3 strncasecmp.3 |
| 106 | MLINKS+=strcat.3 strncat.3 | ||
| 107 | MLINKS+=strcmp.3 strncmp.3 | 163 | MLINKS+=strcmp.3 strncmp.3 |
| 108 | MLINKS+=strcpy.3 strncpy.3 | 164 | MLINKS+=strdup.3 strndup.3 |
| 165 | MLINKS+=strlcpy.3 strlcat.3 | ||
| 166 | MLINKS+=strlen.3 strnlen.3 | ||
| 167 | MLINKS+=strstr.3 strcasestr.3 | ||
| 168 | MLINKS+=strtok.3 strtok_r.3 | ||
| 169 | MLINKS+=strerror.3 strerror_r.3 | ||
| 170 | MLINKS+=wcscasecmp.3 wcsncasecmp.3 | ||
| 171 | MLINKS+=wcscat.3 wcsncat.3 | ||
| 172 | MLINKS+=wcscmp.3 wcsncmp.3 | ||
| 173 | MLINKS+=wcscpy.3 wcsncpy.3 | ||
| 174 | MLINKS+=wcslcpy.3 wcslcat.3 | ||
| 175 | MLINKS+=bcmp.3 timingsafe_bcmp.3 | ||
diff --git a/src/lib/libc/string/__strerror.c b/src/lib/libc/string/__strerror.c deleted file mode 100644 index cd604906db..0000000000 --- a/src/lib/libc/string/__strerror.c +++ /dev/null | |||
| @@ -1,92 +0,0 @@ | |||
| 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) | ||
| 35 | /*static char *sccsid = "from: @(#)strerror.c 5.6 (Berkeley) 5/4/91";*/ | ||
| 36 | static char *rcsid = "$Id: __strerror.c,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $"; | ||
| 37 | #endif /* LIBC_SCCS and not lint */ | ||
| 38 | |||
| 39 | #ifdef NLS | ||
| 40 | #define catclose _catclose | ||
| 41 | #define catgets _catgets | ||
| 42 | #define catopen _catopen | ||
| 43 | #include <nl_types.h> | ||
| 44 | #endif | ||
| 45 | |||
| 46 | #define sys_errlist _sys_errlist | ||
| 47 | #define sys_nerr _sys_nerr | ||
| 48 | |||
| 49 | #include <stdio.h> | ||
| 50 | #include <string.h> | ||
| 51 | |||
| 52 | /* | ||
| 53 | * Since perror() is not allowed to change the contents of strerror()'s | ||
| 54 | * static buffer, both functions supply their own buffers to the | ||
| 55 | * internal function __strerror(). | ||
| 56 | */ | ||
| 57 | |||
| 58 | char * | ||
| 59 | __strerror(num, buf) | ||
| 60 | int num; | ||
| 61 | char *buf; | ||
| 62 | { | ||
| 63 | #define UPREFIX "Unknown error: %u" | ||
| 64 | register unsigned int errnum; | ||
| 65 | |||
| 66 | #ifdef NLS | ||
| 67 | nl_catd catd ; | ||
| 68 | catd = catopen("libc", 0); | ||
| 69 | #endif | ||
| 70 | |||
| 71 | errnum = num; /* convert to unsigned */ | ||
| 72 | if (errnum < sys_nerr) { | ||
| 73 | #ifdef NLS | ||
| 74 | strcpy(buf, catgets(catd, 1, errnum, | ||
| 75 | (char *)sys_errlist[errnum])); | ||
| 76 | #else | ||
| 77 | return(sys_errlist[errnum]); | ||
| 78 | #endif | ||
| 79 | } else { | ||
| 80 | #ifdef NLS | ||
| 81 | sprintf(buf, catgets(catd, 1, 0xffff, UPREFIX), errnum); | ||
| 82 | #else | ||
| 83 | sprintf(buf, UPREFIX, errnum); | ||
| 84 | #endif | ||
| 85 | } | ||
| 86 | |||
| 87 | #ifdef NLS | ||
| 88 | catclose(catd); | ||
| 89 | #endif | ||
| 90 | |||
| 91 | return buf; | ||
| 92 | } | ||
diff --git a/src/lib/libc/string/bcmp.3 b/src/lib/libc/string/bcmp.3 index 118c55c579..52584b4b83 100644 --- a/src/lib/libc/string/bcmp.3 +++ b/src/lib/libc/string/bcmp.3 | |||
| @@ -11,11 +11,7 @@ | |||
| 11 | .\" 2. Redistributions in binary form must reproduce the above copyright | 11 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 12 | .\" notice, this list of conditions and the following disclaimer in the | 12 | .\" notice, this list of conditions and the following disclaimer in the |
| 13 | .\" documentation and/or other materials provided with the distribution. | 13 | .\" documentation and/or other materials provided with the distribution. |
| 14 | .\" 3. All advertising materials mentioning features or use of this software | 14 | .\" 3. Neither the name of the University nor the names of its contributors |
| 15 | .\" must display the following acknowledgement: | ||
| 16 | .\" This product includes software developed by the University of | ||
| 17 | .\" California, Berkeley and its contributors. | ||
| 18 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 19 | .\" may be used to endorse or promote products derived from this software | 15 | .\" may be used to endorse or promote products derived from this software |
| 20 | .\" without specific prior written permission. | 16 | .\" without specific prior written permission. |
| 21 | .\" | 17 | .\" |
| @@ -31,24 +27,25 @@ | |||
| 31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 27 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 32 | .\" SUCH DAMAGE. | 28 | .\" SUCH DAMAGE. |
| 33 | .\" | 29 | .\" |
| 34 | .\" from: @(#)bcmp.3 5.4 (Berkeley) 4/19/91 | 30 | .\" $OpenBSD: bcmp.3,v 1.10 2013/06/05 03:39:23 tedu Exp $ |
| 35 | .\" $Id: bcmp.3,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $ | ||
| 36 | .\" | 31 | .\" |
| 37 | .Dd April 19, 1991 | 32 | .Dd $Mdocdate: June 5 2013 $ |
| 38 | .Dt BCMP 3 | 33 | .Dt BCMP 3 |
| 39 | .Os BSD 4.2 | 34 | .Os |
| 40 | .Sh NAME | 35 | .Sh NAME |
| 41 | .Nm bcmp | 36 | .Nm bcmp , |
| 37 | .Nm timingsafe_bcmp | ||
| 42 | .Nd compare byte string | 38 | .Nd compare byte string |
| 43 | .Sh SYNOPSIS | 39 | .Sh SYNOPSIS |
| 44 | .Fd #include <string.h> | 40 | .In string.h |
| 45 | .Ft int | 41 | .Ft int |
| 46 | .Fn bcmp "const void *b1" "const void *b2" "size_t len" | 42 | .Fn bcmp "const void *b1" "const void *b2" "size_t len" |
| 43 | .Ft int | ||
| 44 | .Fn timingsafe_bcmp "const void *b1" "const void *b2" "size_t len" | ||
| 47 | .Sh DESCRIPTION | 45 | .Sh DESCRIPTION |
| 48 | The | 46 | The |
| 49 | .Fn bcmp | 47 | .Fn bcmp |
| 50 | function | 48 | function compares byte string |
| 51 | compares byte string | ||
| 52 | .Fa b1 | 49 | .Fa b1 |
| 53 | against byte string | 50 | against byte string |
| 54 | .Fa b2 , | 51 | .Fa b2 , |
| @@ -59,6 +56,20 @@ bytes long. | |||
| 59 | Zero-length strings are always identical. | 56 | Zero-length strings are always identical. |
| 60 | .Pp | 57 | .Pp |
| 61 | The strings may overlap. | 58 | The strings may overlap. |
| 59 | .Pp | ||
| 60 | The | ||
| 61 | .Fn timingsafe_bcmp | ||
| 62 | function has the same semantics as | ||
| 63 | .Fn bcmp , | ||
| 64 | but its running time is independent of the contents of | ||
| 65 | .Fa b1 | ||
| 66 | and | ||
| 67 | .Fa b2 , | ||
| 68 | making it safe to use for comparing secret values such as cryptographic MACs. | ||
| 69 | In contrast, | ||
| 70 | .Fn bcmp | ||
| 71 | returns after finding the first differing byte, | ||
| 72 | making it vulnerable to timing attacks. | ||
| 62 | .Sh SEE ALSO | 73 | .Sh SEE ALSO |
| 63 | .Xr memcmp 3 , | 74 | .Xr memcmp 3 , |
| 64 | .Xr strcasecmp 3 , | 75 | .Xr strcasecmp 3 , |
| @@ -66,7 +77,12 @@ The strings may overlap. | |||
| 66 | .Xr strcoll 3 , | 77 | .Xr strcoll 3 , |
| 67 | .Xr strxfrm 3 | 78 | .Xr strxfrm 3 |
| 68 | .Sh HISTORY | 79 | .Sh HISTORY |
| 69 | A | 80 | The |
| 70 | .Fn bcmp | 81 | .Fn bcmp |
| 71 | function first appeared in | 82 | function first appeared in |
| 72 | .Bx 4.2 . | 83 | .Bx 4.2 . |
| 84 | .Pp | ||
| 85 | The | ||
| 86 | .Fn timingsafe_bcmp | ||
| 87 | function first appeared in | ||
| 88 | .Ox 4.9 . | ||
diff --git a/src/lib/libc/string/bcmp.c b/src/lib/libc/string/bcmp.c index 2cc38baee3..fd5c93121e 100644 --- a/src/lib/libc/string/bcmp.c +++ b/src/lib/libc/string/bcmp.c | |||
| @@ -1,3 +1,5 @@ | |||
| 1 | /* $OpenBSD: bcmp.c,v 1.9 2008/03/19 03:00:23 ray Exp $ */ | ||
| 2 | |||
| 1 | /* | 3 | /* |
| 2 | * Copyright (c) 1987 Regents of the University of California. | 4 | * Copyright (c) 1987 Regents of the University of California. |
| 3 | * All rights reserved. | 5 | * All rights reserved. |
| @@ -10,11 +12,7 @@ | |||
| 10 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the |
| 12 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. All advertising materials mentioning features or use of this software | 15 | * 3. Neither the name of the University nor the names of its contributors |
| 14 | * must display the following acknowledgement: | ||
| 15 | * This product includes software developed by the University of | ||
| 16 | * California, Berkeley and its contributors. | ||
| 17 | * 4. Neither the name of the University nor the names of its contributors | ||
| 18 | * may be used to endorse or promote products derived from this software | 16 | * may be used to endorse or promote products derived from this software |
| 19 | * without specific prior written permission. | 17 | * without specific prior written permission. |
| 20 | * | 18 | * |
| @@ -31,29 +29,27 @@ | |||
| 31 | * SUCH DAMAGE. | 29 | * SUCH DAMAGE. |
| 32 | */ | 30 | */ |
| 33 | 31 | ||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | 32 | #if !defined(_KERNEL) && !defined(_STANDALONE) |
| 35 | /*static char *sccsid = "from: @(#)bcmp.c 5.6 (Berkeley) 2/24/91";*/ | ||
| 36 | static char *rcsid = "$Id: bcmp.c,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $"; | ||
| 37 | #endif /* LIBC_SCCS and not lint */ | ||
| 38 | |||
| 39 | #include <string.h> | 33 | #include <string.h> |
| 34 | #else | ||
| 35 | #include <lib/libkern/libkern.h> | ||
| 36 | #endif | ||
| 40 | 37 | ||
| 41 | /* | 38 | /* |
| 42 | * bcmp -- vax cmpc3 instruction | 39 | * bcmp -- vax cmpc3 instruction |
| 43 | */ | 40 | */ |
| 44 | bcmp(b1, b2, length) | 41 | int |
| 45 | const void *b1, *b2; | 42 | bcmp(const void *b1, const void *b2, size_t length) |
| 46 | register size_t length; | ||
| 47 | { | 43 | { |
| 48 | register char *p1, *p2; | 44 | char *p1, *p2; |
| 49 | 45 | ||
| 50 | if (length == 0) | 46 | if (length == 0) |
| 51 | return(0); | 47 | return (0); |
| 52 | p1 = (char *)b1; | 48 | p1 = (char *)b1; |
| 53 | p2 = (char *)b2; | 49 | p2 = (char *)b2; |
| 54 | do | 50 | do |
| 55 | if (*p1++ != *p2++) | 51 | if (*p1++ != *p2++) |
| 56 | break; | 52 | return (1); |
| 57 | while (--length); | 53 | while (--length); |
| 58 | return(length); | 54 | return (0); |
| 59 | } | 55 | } |
diff --git a/src/lib/libc/string/bcopy.3 b/src/lib/libc/string/bcopy.3 index 6db3812caf..94a8231fcb 100644 --- a/src/lib/libc/string/bcopy.3 +++ b/src/lib/libc/string/bcopy.3 | |||
| @@ -12,11 +12,7 @@ | |||
| 12 | .\" 2. Redistributions in binary form must reproduce the above copyright | 12 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 13 | .\" notice, this list of conditions and the following disclaimer in the | 13 | .\" notice, this list of conditions and the following disclaimer in the |
| 14 | .\" documentation and/or other materials provided with the distribution. | 14 | .\" documentation and/or other materials provided with the distribution. |
| 15 | .\" 3. All advertising materials mentioning features or use of this software | 15 | .\" 3. Neither the name of the University nor the names of its contributors |
| 16 | .\" must display the following acknowledgement: | ||
| 17 | .\" This product includes software developed by the University of | ||
| 18 | .\" California, Berkeley and its contributors. | ||
| 19 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 20 | .\" may be used to endorse or promote products derived from this software | 16 | .\" may be used to endorse or promote products derived from this software |
| 21 | .\" without specific prior written permission. | 17 | .\" without specific prior written permission. |
| 22 | .\" | 18 | .\" |
| @@ -32,30 +28,28 @@ | |||
| 32 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 28 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 33 | .\" SUCH DAMAGE. | 29 | .\" SUCH DAMAGE. |
| 34 | .\" | 30 | .\" |
| 35 | .\" from: @(#)bcopy.3 5.3 (Berkeley) 4/19/91 | 31 | .\" $OpenBSD: bcopy.3,v 1.11 2013/06/05 03:39:23 tedu Exp $ |
| 36 | .\" $Id: bcopy.3,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $ | ||
| 37 | .\" | 32 | .\" |
| 38 | .Dd April 19, 1991 | 33 | .Dd $Mdocdate: June 5 2013 $ |
| 39 | .Dt BCOPY 3 | 34 | .Dt BCOPY 3 |
| 40 | .Os BSD 4.2 | 35 | .Os |
| 41 | .Sh NAME | 36 | .Sh NAME |
| 42 | .Nm bcopy | 37 | .Nm bcopy |
| 43 | .Nd copy byte string | 38 | .Nd copy bytes |
| 44 | .Sh SYNOPSIS | 39 | .Sh SYNOPSIS |
| 45 | .Fd #include <string.h> | 40 | .In string.h |
| 46 | .Ft void | 41 | .Ft void |
| 47 | .Fn bcopy "const void *src" "void *dst" "size_t len" | 42 | .Fn bcopy "const void *src" "void *dst" "size_t len" |
| 48 | .Sh DESCRIPTION | 43 | .Sh DESCRIPTION |
| 49 | The | 44 | The |
| 50 | .Fn bcopy | 45 | .Fn bcopy |
| 51 | function | 46 | function copies |
| 52 | copies | ||
| 53 | .Fa len | 47 | .Fa len |
| 54 | bytes from string | 48 | bytes from buffer |
| 55 | .Fa src | 49 | .Fa src |
| 56 | to string | 50 | to buffer |
| 57 | .Fa dst . | 51 | .Fa dst . |
| 58 | The two strings may overlap. | 52 | The two buffers may overlap. |
| 59 | If | 53 | If |
| 60 | .Fa len | 54 | .Fa len |
| 61 | is zero, no bytes are copied. | 55 | is zero, no bytes are copied. |
| @@ -64,9 +58,10 @@ is zero, no bytes are copied. | |||
| 64 | .Xr memcpy 3 , | 58 | .Xr memcpy 3 , |
| 65 | .Xr memmove 3 , | 59 | .Xr memmove 3 , |
| 66 | .Xr strcpy 3 , | 60 | .Xr strcpy 3 , |
| 61 | .Xr strlcpy 3 , | ||
| 67 | .Xr strncpy 3 | 62 | .Xr strncpy 3 |
| 68 | .Sh HISTORY | 63 | .Sh HISTORY |
| 69 | A | 64 | The |
| 70 | .Fn bcopy | 65 | .Fn bcopy |
| 71 | function appeared in | 66 | function first appeared in |
| 72 | .Bx 4.2 . | 67 | .Bx 4.2 . |
diff --git a/src/lib/libc/string/bcopy.c b/src/lib/libc/string/bcopy.c index 92feed66ea..4308c6484a 100644 --- a/src/lib/libc/string/bcopy.c +++ b/src/lib/libc/string/bcopy.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: bcopy.c,v 1.5 2005/08/08 08:05:37 espie Exp $ */ | ||
| 1 | /*- | 2 | /*- |
| 2 | * Copyright (c) 1990 The Regents of the University of California. | 3 | * Copyright (c) 1990 The Regents of the University of California. |
| 3 | * All rights reserved. | 4 | * All rights reserved. |
| @@ -13,11 +14,7 @@ | |||
| 13 | * 2. Redistributions in binary form must reproduce the above copyright | 14 | * 2. Redistributions in binary form must reproduce the above copyright |
| 14 | * notice, this list of conditions and the following disclaimer in the | 15 | * notice, this list of conditions and the following disclaimer in the |
| 15 | * documentation and/or other materials provided with the distribution. | 16 | * documentation and/or other materials provided with the distribution. |
| 16 | * 3. All advertising materials mentioning features or use of this software | 17 | * 3. Neither the name of the University nor the names of its contributors |
| 17 | * must display the following acknowledgement: | ||
| 18 | * This product includes software developed by the University of | ||
| 19 | * California, Berkeley and its contributors. | ||
| 20 | * 4. Neither the name of the University nor the names of its contributors | ||
| 21 | * may be used to endorse or promote products derived from this software | 18 | * may be used to endorse or promote products derived from this software |
| 22 | * without specific prior written permission. | 19 | * without specific prior written permission. |
| 23 | * | 20 | * |
| @@ -34,11 +31,6 @@ | |||
| 34 | * SUCH DAMAGE. | 31 | * SUCH DAMAGE. |
| 35 | */ | 32 | */ |
| 36 | 33 | ||
| 37 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 38 | /*static char *sccsid = "from: @(#)bcopy.c 5.11 (Berkeley) 6/21/91";*/ | ||
| 39 | static char *rcsid = "$Id: bcopy.c,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $"; | ||
| 40 | #endif /* LIBC_SCCS and not lint */ | ||
| 41 | |||
| 42 | #include <string.h> | 34 | #include <string.h> |
| 43 | 35 | ||
| 44 | /* | 36 | /* |
| @@ -57,23 +49,20 @@ typedef long word; /* "word" used for optimal copy speed */ | |||
| 57 | */ | 49 | */ |
| 58 | #ifdef MEMCOPY | 50 | #ifdef MEMCOPY |
| 59 | void * | 51 | void * |
| 60 | memcpy(dst0, src0, length) | 52 | memcpy(void *dst0, const void *src0, size_t length) |
| 61 | #else | 53 | #else |
| 62 | #ifdef MEMMOVE | 54 | #ifdef MEMMOVE |
| 63 | void * | 55 | void * |
| 64 | memmove(dst0, src0, length) | 56 | memmove(void *dst0, const void *src0, size_t length) |
| 65 | #else | 57 | #else |
| 66 | void | 58 | void |
| 67 | bcopy(src0, dst0, length) | 59 | bcopy(const void *src0, void *dst0, size_t length) |
| 68 | #endif | 60 | #endif |
| 69 | #endif | 61 | #endif |
| 70 | void *dst0; | ||
| 71 | const void *src0; | ||
| 72 | register size_t length; | ||
| 73 | { | 62 | { |
| 74 | register char *dst = dst0; | 63 | char *dst = dst0; |
| 75 | register const char *src = src0; | 64 | const char *src = src0; |
| 76 | register size_t t; | 65 | size_t t; |
| 77 | 66 | ||
| 78 | if (length == 0 || dst == src) /* nothing to do */ | 67 | if (length == 0 || dst == src) /* nothing to do */ |
| 79 | goto done; | 68 | goto done; |
diff --git a/src/lib/libc/string/bm.3 b/src/lib/libc/string/bm.3 deleted file mode 100644 index 2264a6a1c4..0000000000 --- a/src/lib/libc/string/bm.3 +++ /dev/null | |||
| @@ -1,114 +0,0 @@ | |||
| 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 | .\" from: @(#)bm.3 8.4 (Berkeley) 6/21/94 | ||
| 36 | .\" $Id: bm.3,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $ | ||
| 37 | .\" | ||
| 38 | .TH BM 3 | ||
| 39 | .SH NAME | ||
| 40 | bm_comp, bm_exec, bm_free \- Boyer-Moore string search | ||
| 41 | .SH SYNOPSIS | ||
| 42 | .ft B | ||
| 43 | #include <sys/types.h> | ||
| 44 | .br | ||
| 45 | #include <bm.h> | ||
| 46 | .sp | ||
| 47 | bm_pat * | ||
| 48 | .br | ||
| 49 | bm_comp(u_char *pattern, size_t patlen, u_char freq[256]); | ||
| 50 | .sp | ||
| 51 | u_char * | ||
| 52 | .br | ||
| 53 | bm_exec(bm_pat *pdesc, u_char *text, size_t len); | ||
| 54 | .sp | ||
| 55 | void | ||
| 56 | .br | ||
| 57 | bm_free(bm_pat *pdesc); | ||
| 58 | .SH DESCRIPTION | ||
| 59 | These routines implement an efficient mechanism to find an | ||
| 60 | occurrence of a byte string within another byte string. | ||
| 61 | .PP | ||
| 62 | .I Bm_comp | ||
| 63 | evaluates the | ||
| 64 | .I patlen | ||
| 65 | bytes starting at | ||
| 66 | .IR pattern , | ||
| 67 | and returns a pointer to a structure describing them. | ||
| 68 | The bytes referenced by | ||
| 69 | .I pattern | ||
| 70 | may be of any value. | ||
| 71 | .PP | ||
| 72 | The search takes advantage of the frequency distribution of the | ||
| 73 | bytes in the text to be searched. | ||
| 74 | If specified, | ||
| 75 | .I freq | ||
| 76 | should be an array of 256 values, | ||
| 77 | with higher values indicating that the corresponding character occurs | ||
| 78 | more frequently. | ||
| 79 | (A less than optimal frequency distribution can only result in less | ||
| 80 | than optimal performance, not incorrect results.) | ||
| 81 | If | ||
| 82 | .I freq | ||
| 83 | is NULL, | ||
| 84 | a system default table is used. | ||
| 85 | .PP | ||
| 86 | .I Bm_exec | ||
| 87 | returns a pointer to the leftmost occurrence of the string given to | ||
| 88 | .I bm_comp | ||
| 89 | within | ||
| 90 | .IR text , | ||
| 91 | or NULL if none occurs. | ||
| 92 | The number of bytes in | ||
| 93 | .I text | ||
| 94 | must be specified by | ||
| 95 | .IR len . | ||
| 96 | .PP | ||
| 97 | Space allocated for the returned description is discarded | ||
| 98 | by calling | ||
| 99 | .I bm_free | ||
| 100 | with the returned description as an argument. | ||
| 101 | .PP | ||
| 102 | The asymptotic speed of | ||
| 103 | .I bm_exec | ||
| 104 | is | ||
| 105 | .RI O( len / patlen ). | ||
| 106 | .PP | ||
| 107 | .SH "SEE ALSO" | ||
| 108 | .IR regexp (3), | ||
| 109 | .IR strstr (3) | ||
| 110 | .sp | ||
| 111 | .IR "Fast String Searching" , | ||
| 112 | Hume and Sunday, | ||
| 113 | Software Practice and Experience, | ||
| 114 | Vol. 21, 11 (November 1991) pp. 1221-48. | ||
diff --git a/src/lib/libc/string/bm.c b/src/lib/libc/string/bm.c deleted file mode 100644 index 68eac22ecc..0000000000 --- a/src/lib/libc/string/bm.c +++ /dev/null | |||
| @@ -1,220 +0,0 @@ | |||
| 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 | #ifndef lint | ||
| 38 | /* from: static char sccsid[] = "@(#)bm.c 8.7 (Berkeley) 6/21/94"; */ | ||
| 39 | static char *rcsid = "$Id: bm.c,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $"; | ||
| 40 | #endif /* not lint */ | ||
| 41 | |||
| 42 | #include <sys/types.h> | ||
| 43 | |||
| 44 | #include <bm.h> | ||
| 45 | #include <errno.h> | ||
| 46 | #include <stdlib.h> | ||
| 47 | #include <string.h> | ||
| 48 | |||
| 49 | /* | ||
| 50 | * XXX | ||
| 51 | * The default frequency table starts at 99 and counts down. The default | ||
| 52 | * table should probably be oriented toward text, and will necessarily be | ||
| 53 | * locale specific. This one is for English. It was derived from the | ||
| 54 | * OSF/1 and 4.4BSD formatted and unformatted manual pages, and about 100Mb | ||
| 55 | * of email and random text. Change it if you can find something better. | ||
| 56 | */ | ||
| 57 | static u_char const freq_def[256] = { | ||
| 58 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 59 | 0, 77, 90, 0, 0, 0, 0, 0, | ||
| 60 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 61 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 62 | 99, 28, 42, 27, 16, 14, 20, 51, | ||
| 63 | 66, 65, 59, 24, 75, 76, 84, 56, | ||
| 64 | 72, 74, 64, 55, 54, 47, 41, 37, | ||
| 65 | 44, 61, 70, 43, 23, 53, 49, 22, | ||
| 66 | 33, 58, 40, 46, 45, 57, 60, 26, | ||
| 67 | 30, 63, 21, 12, 32, 50, 38, 39, | ||
| 68 | 34, 11, 48, 67, 62, 35, 15, 29, | ||
| 69 | 71, 18, 9, 17, 25, 13, 10, 52, | ||
| 70 | 36, 95, 78, 86, 87, 98, 82, 80, | ||
| 71 | 88, 94, 19, 68, 89, 83, 93, 96, | ||
| 72 | 81, 7, 91, 92, 97, 85, 69, 73, | ||
| 73 | 31, 79, 8, 5, 4, 6, 3, 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 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 90 | }; | ||
| 91 | |||
| 92 | bm_pat * | ||
| 93 | bm_comp(pb, len, freq) | ||
| 94 | u_char const *pb; | ||
| 95 | size_t len; | ||
| 96 | u_char const *freq; | ||
| 97 | { | ||
| 98 | register u_char const *pe, *p; | ||
| 99 | register size_t *d, r; | ||
| 100 | register int j; | ||
| 101 | int sv_errno; | ||
| 102 | bm_pat *pat; | ||
| 103 | |||
| 104 | if (len == 0) { | ||
| 105 | errno = EINVAL; | ||
| 106 | return (NULL); | ||
| 107 | } | ||
| 108 | if ((pat = malloc(sizeof(*pat))) == NULL) | ||
| 109 | return (NULL); | ||
| 110 | pat->pat = NULL; | ||
| 111 | pat->delta = NULL; | ||
| 112 | |||
| 113 | pat->patlen = len; /* copy pattern */ | ||
| 114 | if ((pat->pat = malloc(pat->patlen)) == NULL) | ||
| 115 | goto mem; | ||
| 116 | memcpy(pat->pat, pb, pat->patlen); | ||
| 117 | /* get skip delta */ | ||
| 118 | if ((pat->delta = malloc(256 * sizeof(*d))) == NULL) | ||
| 119 | goto mem; | ||
| 120 | for (j = 0, d = pat->delta; j < 256; j++) | ||
| 121 | d[j] = pat->patlen; | ||
| 122 | for (pe = pb + pat->patlen - 1; pb <= pe; pb++) | ||
| 123 | d[*pb] = pe - pb; | ||
| 124 | |||
| 125 | if (freq == NULL) /* default freq table */ | ||
| 126 | freq = freq_def; | ||
| 127 | r = 0; /* get guard */ | ||
| 128 | for (pb = pat->pat, pe = pb + pat->patlen - 1; pb < pe; pb++) | ||
| 129 | if (freq[*pb] < freq[pat->pat[r]]) | ||
| 130 | r = pb - pat->pat; | ||
| 131 | pat->rarec = pat->pat[r]; | ||
| 132 | pat->rareoff = r - (pat->patlen - 1); | ||
| 133 | |||
| 134 | /* get md2 shift */ | ||
| 135 | for (pe = pat->pat + pat->patlen - 1, p = pe - 1; p >= pat->pat; p--) | ||
| 136 | if (*p == *pe) | ||
| 137 | break; | ||
| 138 | |||
| 139 | /* *p is first leftward reoccurrence of *pe */ | ||
| 140 | pat->md2 = pe - p; | ||
| 141 | return (pat); | ||
| 142 | |||
| 143 | mem: sv_errno = errno; | ||
| 144 | bm_free(pat); | ||
| 145 | errno = sv_errno; | ||
| 146 | return (NULL); | ||
| 147 | } | ||
| 148 | |||
| 149 | void | ||
| 150 | bm_free(pat) | ||
| 151 | bm_pat *pat; | ||
| 152 | { | ||
| 153 | if (pat->pat != NULL) | ||
| 154 | free(pat->pat); | ||
| 155 | if (pat->delta != NULL) | ||
| 156 | free(pat->delta); | ||
| 157 | free(pat); | ||
| 158 | } | ||
| 159 | |||
| 160 | u_char * | ||
| 161 | bm_exec(pat, base, n) | ||
| 162 | bm_pat *pat; | ||
| 163 | u_char *base; | ||
| 164 | size_t n; | ||
| 165 | { | ||
| 166 | register u_char *e, *ep, *p, *q, *s; | ||
| 167 | register size_t *d0, k, md2, n1, ro; | ||
| 168 | register int rc; | ||
| 169 | |||
| 170 | if (n == 0) | ||
| 171 | return (NULL); | ||
| 172 | |||
| 173 | d0 = pat->delta; | ||
| 174 | n1 = pat->patlen - 1; | ||
| 175 | md2 = pat->md2; | ||
| 176 | ro = pat->rareoff; | ||
| 177 | rc = pat->rarec; | ||
| 178 | ep = pat->pat + pat->patlen - 1; | ||
| 179 | s = base + (pat->patlen - 1); | ||
| 180 | |||
| 181 | /* fast loop up to n - 3 * patlen */ | ||
| 182 | e = base + n - 3 * pat->patlen; | ||
| 183 | while (s < e) { | ||
| 184 | k = d0[*s]; /* ufast skip loop */ | ||
| 185 | while (k) { | ||
| 186 | k = d0[*(s += k)]; | ||
| 187 | k = d0[*(s += k)]; | ||
| 188 | } | ||
| 189 | if (s >= e) | ||
| 190 | break; | ||
| 191 | if (s[ro] != rc) /* guard test */ | ||
| 192 | goto mismatch1; | ||
| 193 | /* fwd match */ | ||
| 194 | for (p = pat->pat, q = s - n1; p < ep;) | ||
| 195 | if (*q++ != *p++) | ||
| 196 | goto mismatch1; | ||
| 197 | return (s - n1); | ||
| 198 | |||
| 199 | mismatch1: s += md2; /* md2 shift */ | ||
| 200 | } | ||
| 201 | |||
| 202 | /* slow loop up to end */ | ||
| 203 | e = base + n; | ||
| 204 | while (s < e) { | ||
| 205 | s += d0[*s]; /* step */ | ||
| 206 | if (s >= e) | ||
| 207 | break; | ||
| 208 | if (s[ro] != rc) /* guard test */ | ||
| 209 | goto mismatch2; | ||
| 210 | /* fwd match */ | ||
| 211 | for (p = pat->pat, q = s - n1; p <= ep;) | ||
| 212 | if (*q++ != *p++) | ||
| 213 | goto mismatch2; | ||
| 214 | return (s - n1); | ||
| 215 | |||
| 216 | mismatch2: s += md2; /* md2 shift */ | ||
| 217 | } | ||
| 218 | |||
| 219 | return (NULL); | ||
| 220 | } | ||
diff --git a/src/lib/libc/string/bstring.3 b/src/lib/libc/string/bstring.3 index 12fcfb0cc1..d88b78f504 100644 --- a/src/lib/libc/string/bstring.3 +++ b/src/lib/libc/string/bstring.3 | |||
| @@ -11,11 +11,7 @@ | |||
| 11 | .\" 2. Redistributions in binary form must reproduce the above copyright | 11 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 12 | .\" notice, this list of conditions and the following disclaimer in the | 12 | .\" notice, this list of conditions and the following disclaimer in the |
| 13 | .\" documentation and/or other materials provided with the distribution. | 13 | .\" documentation and/or other materials provided with the distribution. |
| 14 | .\" 3. All advertising materials mentioning features or use of this software | 14 | .\" 3. Neither the name of the University nor the names of its contributors |
| 15 | .\" must display the following acknowledgement: | ||
| 16 | .\" This product includes software developed by the University of | ||
| 17 | .\" California, Berkeley and its contributors. | ||
| 18 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 19 | .\" may be used to endorse or promote products derived from this software | 15 | .\" may be used to endorse or promote products derived from this software |
| 20 | .\" without specific prior written permission. | 16 | .\" without specific prior written permission. |
| 21 | .\" | 17 | .\" |
| @@ -31,25 +27,16 @@ | |||
| 31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 27 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 32 | .\" SUCH DAMAGE. | 28 | .\" SUCH DAMAGE. |
| 33 | .\" | 29 | .\" |
| 34 | .\" from: @(#)bstring.3 6.8 (Berkeley) 4/19/91 | 30 | .\" $OpenBSD: bstring.3,v 1.10 2013/06/05 03:39:23 tedu Exp $ |
| 35 | .\" $Id: bstring.3,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $ | ||
| 36 | .\" | 31 | .\" |
| 37 | .Dd April 19, 1991 | 32 | .Dd $Mdocdate: June 5 2013 $ |
| 38 | .Dt BSTRING 3 | 33 | .Dt BSTRING 3 |
| 39 | .Os | 34 | .Os |
| 40 | .Sh NAME | 35 | .Sh NAME |
| 41 | .Nm bcmp , | 36 | .Nm bstring |
| 42 | .Nm bcopy , | ||
| 43 | .Nm bzero , | ||
| 44 | .Nm memccpy , | ||
| 45 | .Nm memchr , | ||
| 46 | .Nm memcmp , | ||
| 47 | .Nm memcpy , | ||
| 48 | .Nm memmove, | ||
| 49 | .Nm memset | ||
| 50 | .Nd byte string operations | 37 | .Nd byte string operations |
| 51 | .Sh SYNOPSIS | 38 | .Sh SYNOPSIS |
| 52 | .Fd #include <string.h> | 39 | .In string.h |
| 53 | .Ft int | 40 | .Ft int |
| 54 | .Fn bcmp "const void *b1" "const void *b2" "size_t len" | 41 | .Fn bcmp "const void *b1" "const void *b2" "size_t len" |
| 55 | .Ft void | 42 | .Ft void |
| @@ -70,7 +57,7 @@ | |||
| 70 | .Fn memset "void *b" "int c" "size_t len" | 57 | .Fn memset "void *b" "int c" "size_t len" |
| 71 | .Sh DESCRIPTION | 58 | .Sh DESCRIPTION |
| 72 | These functions operate on variable length strings of bytes. | 59 | These functions operate on variable length strings of bytes. |
| 73 | They do not check for terminating null bytes as the routines | 60 | They do not check for terminating NUL bytes as the routines |
| 74 | listed in | 61 | listed in |
| 75 | .Xr string 3 | 62 | .Xr string 3 |
| 76 | do. | 63 | do. |
| @@ -97,14 +84,25 @@ and | |||
| 97 | conform to | 84 | conform to |
| 98 | .St -ansiC . | 85 | .St -ansiC . |
| 99 | .Sh HISTORY | 86 | .Sh HISTORY |
| 100 | The functions | 87 | The |
| 101 | .Fn bzero | ||
| 102 | and | ||
| 103 | .Fn memccpy | ||
| 104 | appeared in | ||
| 105 | .Bx 4.3 ; | ||
| 106 | the functions | ||
| 107 | .Fn bcmp , | 88 | .Fn bcmp , |
| 108 | .Fn bcopy , | 89 | .Fn bcopy , |
| 109 | appeared in | 90 | and |
| 91 | .Fn bzero | ||
| 92 | functions first appeared in | ||
| 110 | .Bx 4.2 . | 93 | .Bx 4.2 . |
| 94 | The | ||
| 95 | .Fn memchr , | ||
| 96 | .Fn memcmp , | ||
| 97 | .Fn memccpy , | ||
| 98 | .Fn memcpy , | ||
| 99 | and | ||
| 100 | .Fn memset | ||
| 101 | functions first appeared in | ||
| 102 | .At V | ||
| 103 | and were reimplemented for | ||
| 104 | .Bx 4.3 Tahoe . | ||
| 105 | The | ||
| 106 | .Fn memmove | ||
| 107 | function first appeared in | ||
| 108 | .Bx 4.3 Reno . | ||
diff --git a/src/lib/libc/string/bzero.3 b/src/lib/libc/string/bzero.3 index 4f0141e051..3e21c4241f 100644 --- a/src/lib/libc/string/bzero.3 +++ b/src/lib/libc/string/bzero.3 | |||
| @@ -11,11 +11,7 @@ | |||
| 11 | .\" 2. Redistributions in binary form must reproduce the above copyright | 11 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 12 | .\" notice, this list of conditions and the following disclaimer in the | 12 | .\" notice, this list of conditions and the following disclaimer in the |
| 13 | .\" documentation and/or other materials provided with the distribution. | 13 | .\" documentation and/or other materials provided with the distribution. |
| 14 | .\" 3. All advertising materials mentioning features or use of this software | 14 | .\" 3. Neither the name of the University nor the names of its contributors |
| 15 | .\" must display the following acknowledgement: | ||
| 16 | .\" This product includes software developed by the University of | ||
| 17 | .\" California, Berkeley and its contributors. | ||
| 18 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 19 | .\" may be used to endorse or promote products derived from this software | 15 | .\" may be used to endorse or promote products derived from this software |
| 20 | .\" without specific prior written permission. | 16 | .\" without specific prior written permission. |
| 21 | .\" | 17 | .\" |
| @@ -31,24 +27,25 @@ | |||
| 31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 27 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 32 | .\" SUCH DAMAGE. | 28 | .\" SUCH DAMAGE. |
| 33 | .\" | 29 | .\" |
| 34 | .\" from: @(#)bzero.3 5.3 (Berkeley) 4/19/91 | 30 | .\" $OpenBSD: bzero.3,v 1.11 2014/01/22 22:21:25 jmc Exp $ |
| 35 | .\" $Id: bzero.3,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $ | ||
| 36 | .\" | 31 | .\" |
| 37 | .Dd April 19, 1991 | 32 | .Dd $Mdocdate: January 22 2014 $ |
| 38 | .Dt BZERO 3 | 33 | .Dt BZERO 3 |
| 39 | .Os BSD 4.3 | 34 | .Os |
| 40 | .Sh NAME | 35 | .Sh NAME |
| 41 | .Nm bzero | 36 | .Nm bzero , |
| 37 | .Nm explicit_bzero | ||
| 42 | .Nd write zeroes to a byte string | 38 | .Nd write zeroes to a byte string |
| 43 | .Sh SYNOPSIS | 39 | .Sh SYNOPSIS |
| 44 | .Fd #include <string.h> | 40 | .In string.h |
| 45 | .Ft void | 41 | .Ft void |
| 46 | .Fn bzero "void *b" "size_t len" | 42 | .Fn bzero "void *b" "size_t len" |
| 43 | .Ft void | ||
| 44 | .Fn explicit_bzero "void *b" "size_t len" | ||
| 47 | .Sh DESCRIPTION | 45 | .Sh DESCRIPTION |
| 48 | The | 46 | The |
| 49 | .Fn bzero | 47 | .Fn bzero |
| 50 | function | 48 | function writes |
| 51 | writes | ||
| 52 | .Fa len | 49 | .Fa len |
| 53 | zero bytes to the string | 50 | zero bytes to the string |
| 54 | .Fa b . | 51 | .Fa b . |
| @@ -57,12 +54,21 @@ If | |||
| 57 | is zero, | 54 | is zero, |
| 58 | .Fn bzero | 55 | .Fn bzero |
| 59 | does nothing. | 56 | does nothing. |
| 57 | .Pp | ||
| 58 | The | ||
| 59 | .Fn explicit_bzero | ||
| 60 | variant behaves the same, but will not be removed by a compiler's dead store | ||
| 61 | optimization pass, making it useful for clearing sensitive memory such as a | ||
| 62 | password. | ||
| 60 | .Sh SEE ALSO | 63 | .Sh SEE ALSO |
| 61 | .Xr memset 3 , | 64 | .Xr memset 3 , |
| 62 | .Xr swab 3 | 65 | .Xr swab 3 |
| 63 | .Sh HISTORY | 66 | .Sh HISTORY |
| 64 | A | 67 | The |
| 65 | .Fn bzero | 68 | .Fn bzero |
| 66 | function | 69 | function first appeared in |
| 67 | appeared in | 70 | .Bx 4.2 . |
| 68 | .Bx 4.3 . | 71 | The |
| 72 | .Fn explicit_bzero | ||
| 73 | function first appeared in | ||
| 74 | .Ox 5.5 . | ||
diff --git a/src/lib/libc/string/bzero.c b/src/lib/libc/string/bzero.c index 4865e396ef..4d267d4f40 100644 --- a/src/lib/libc/string/bzero.c +++ b/src/lib/libc/string/bzero.c | |||
| @@ -1,3 +1,5 @@ | |||
| 1 | /* $OpenBSD: bzero.c,v 1.7 2005/08/08 08:05:37 espie Exp $ */ | ||
| 2 | |||
| 1 | /* | 3 | /* |
| 2 | * Copyright (c) 1987 Regents of the University of California. | 4 | * Copyright (c) 1987 Regents of the University of California. |
| 3 | * All rights reserved. | 5 | * All rights reserved. |
| @@ -10,11 +12,7 @@ | |||
| 10 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the |
| 12 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. All advertising materials mentioning features or use of this software | 15 | * 3. Neither the name of the University nor the names of its contributors |
| 14 | * must display the following acknowledgement: | ||
| 15 | * This product includes software developed by the University of | ||
| 16 | * California, Berkeley and its contributors. | ||
| 17 | * 4. Neither the name of the University nor the names of its contributors | ||
| 18 | * may be used to endorse or promote products derived from this software | 16 | * may be used to endorse or promote products derived from this software |
| 19 | * without specific prior written permission. | 17 | * without specific prior written permission. |
| 20 | * | 18 | * |
| @@ -31,22 +29,19 @@ | |||
| 31 | * SUCH DAMAGE. | 29 | * SUCH DAMAGE. |
| 32 | */ | 30 | */ |
| 33 | 31 | ||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | 32 | #if !defined(_KERNEL) && !defined(_STANDALONE) |
| 35 | /*static char *sccsid = "from: @(#)bzero.c 5.7 (Berkeley) 2/24/91";*/ | ||
| 36 | static char *rcsid = "$Id: bzero.c,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $"; | ||
| 37 | #endif /* LIBC_SCCS and not lint */ | ||
| 38 | |||
| 39 | #include <string.h> | 33 | #include <string.h> |
| 34 | #else | ||
| 35 | #include <lib/libkern/libkern.h> | ||
| 36 | #endif | ||
| 40 | 37 | ||
| 41 | /* | 38 | /* |
| 42 | * bzero -- vax movc5 instruction | 39 | * bzero -- vax movc5 instruction |
| 43 | */ | 40 | */ |
| 44 | void | 41 | void |
| 45 | bzero(b, length) | 42 | bzero(void *b, size_t length) |
| 46 | void *b; | ||
| 47 | register size_t length; | ||
| 48 | { | 43 | { |
| 49 | register char *p; | 44 | char *p; |
| 50 | 45 | ||
| 51 | for (p = b; length--;) | 46 | for (p = b; length--;) |
| 52 | *p++ = '\0'; | 47 | *p++ = '\0'; |
diff --git a/src/lib/libc/string/explicit_bzero.c b/src/lib/libc/string/explicit_bzero.c new file mode 100644 index 0000000000..fd2948ca44 --- /dev/null +++ b/src/lib/libc/string/explicit_bzero.c | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | /* $OpenBSD: explicit_bzero.c,v 1.1 2014/01/22 21:06:45 tedu Exp $ */ | ||
| 2 | /* | ||
| 3 | * Public domain. | ||
| 4 | * Written by Ted Unangst | ||
| 5 | */ | ||
| 6 | |||
| 7 | #if !defined(_KERNEL) && !defined(_STANDALONE) | ||
| 8 | #include <string.h> | ||
| 9 | #else | ||
| 10 | #include <lib/libkern/libkern.h> | ||
| 11 | #endif | ||
| 12 | |||
| 13 | /* | ||
| 14 | * explicit_bzero - don't let the compiler optimize away bzero | ||
| 15 | */ | ||
| 16 | void | ||
| 17 | explicit_bzero(void *p, size_t n) | ||
| 18 | { | ||
| 19 | bzero(p, n); | ||
| 20 | } | ||
diff --git a/src/lib/libc/string/ffs.3 b/src/lib/libc/string/ffs.3 index 6464bea2b1..c0ed7baa9e 100644 --- a/src/lib/libc/string/ffs.3 +++ b/src/lib/libc/string/ffs.3 | |||
| @@ -11,11 +11,7 @@ | |||
| 11 | .\" 2. Redistributions in binary form must reproduce the above copyright | 11 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 12 | .\" notice, this list of conditions and the following disclaimer in the | 12 | .\" notice, this list of conditions and the following disclaimer in the |
| 13 | .\" documentation and/or other materials provided with the distribution. | 13 | .\" documentation and/or other materials provided with the distribution. |
| 14 | .\" 3. All advertising materials mentioning features or use of this software | 14 | .\" 3. Neither the name of the University nor the names of its contributors |
| 15 | .\" must display the following acknowledgement: | ||
| 16 | .\" This product includes software developed by the University of | ||
| 17 | .\" California, Berkeley and its contributors. | ||
| 18 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 19 | .\" may be used to endorse or promote products derived from this software | 15 | .\" may be used to endorse or promote products derived from this software |
| 20 | .\" without specific prior written permission. | 16 | .\" without specific prior written permission. |
| 21 | .\" | 17 | .\" |
| @@ -31,33 +27,35 @@ | |||
| 31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 27 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 32 | .\" SUCH DAMAGE. | 28 | .\" SUCH DAMAGE. |
| 33 | .\" | 29 | .\" |
| 34 | .\" from: @(#)ffs.3 5.3 (Berkeley) 4/19/91 | 30 | .\" $OpenBSD: ffs.3,v 1.9 2013/06/05 03:39:23 tedu Exp $ |
| 35 | .\" $Id: ffs.3,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $ | ||
| 36 | .\" | 31 | .\" |
| 37 | .Dd April 19, 1991 | 32 | .Dd $Mdocdate: June 5 2013 $ |
| 38 | .Dt FFS 3 | 33 | .Dt FFS 3 |
| 39 | .Os | 34 | .Os |
| 40 | .Sh NAME | 35 | .Sh NAME |
| 41 | .Nm ffs | 36 | .Nm ffs |
| 42 | .Nd find first bit set in a bit string | 37 | .Nd find first bit set in a bit string |
| 43 | .Sh SYNOPSIS | 38 | .Sh SYNOPSIS |
| 44 | .Fd #include <string.h> | 39 | .In string.h |
| 45 | .Ft int | 40 | .Ft int |
| 46 | .Fn ffs "int value" | 41 | .Fn ffs "int value" |
| 47 | .Sh DESCRIPTION | 42 | .Sh DESCRIPTION |
| 48 | The | 43 | The |
| 49 | .Fn ffs | 44 | .Fn ffs |
| 50 | function | 45 | function finds the first bit set in |
| 51 | finds the first bit set in | ||
| 52 | .Fa value | 46 | .Fa value |
| 53 | and returns the index of that bit. | 47 | and returns the index of that bit. |
| 54 | Bits are numbered starting from 1, starting at the right-most | 48 | Bits are numbered starting from 1, starting at the rightmost bit. |
| 55 | bit. | ||
| 56 | A return value of 0 means that the argument was zero. | 49 | A return value of 0 means that the argument was zero. |
| 57 | .Sh SEE ALSO | 50 | .Sh SEE ALSO |
| 58 | .Xr bitstring 3 | 51 | .Xr bitstring 3 |
| 52 | .Sh STANDARDS | ||
| 53 | The | ||
| 54 | .Fn ffs | ||
| 55 | function conforms to | ||
| 56 | .St -p1003.1-2008 . | ||
| 59 | .Sh HISTORY | 57 | .Sh HISTORY |
| 60 | The | 58 | The |
| 61 | .Fn ffs | 59 | .Fn ffs |
| 62 | function appeared in | 60 | function first appeared in |
| 63 | .Bx 4.3 . | 61 | .Bx 4.2 . |
diff --git a/src/lib/libc/string/ffs.c b/src/lib/libc/string/ffs.c index 42bc87ddea..7dec1613a8 100644 --- a/src/lib/libc/string/ffs.c +++ b/src/lib/libc/string/ffs.c | |||
| @@ -1,55 +1,44 @@ | |||
| 1 | /*- | 1 | /* $OpenBSD: ffs.c,v 1.7 2005/08/08 08:05:37 espie Exp $ */ |
| 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 | 2 | ||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | 3 | /* |
| 35 | /*static char *sccsid = "from: @(#)ffs.c 5.4 (Berkeley) 5/17/90";*/ | 4 | * Public domain. |
| 36 | static char *rcsid = "$Id: ffs.c,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $"; | 5 | * Written by Dale Rahn. |
| 37 | #endif /* LIBC_SCCS and not lint */ | 6 | */ |
| 38 | 7 | ||
| 8 | #if !defined(_KERNEL) && !defined(_STANDALONE) | ||
| 39 | #include <string.h> | 9 | #include <string.h> |
| 10 | #else | ||
| 11 | #include <lib/libkern/libkern.h> | ||
| 12 | #endif | ||
| 40 | 13 | ||
| 41 | /* | 14 | /* |
| 42 | * ffs -- vax ffs instruction | 15 | * ffs -- vax ffs instruction |
| 43 | */ | 16 | */ |
| 44 | int | 17 | int |
| 45 | ffs(mask) | 18 | ffs(int mask) |
| 46 | register int mask; | ||
| 47 | { | 19 | { |
| 48 | register int bit; | 20 | int bit; |
| 21 | unsigned int r = mask; | ||
| 22 | static const signed char t[16] = { | ||
| 23 | -28, 1, 2, 1, | ||
| 24 | 3, 1, 2, 1, | ||
| 25 | 4, 1, 2, 1, | ||
| 26 | 3, 1, 2, 1 | ||
| 27 | }; | ||
| 28 | |||
| 29 | bit = 0; | ||
| 30 | if (!(r & 0xffff)) { | ||
| 31 | bit += 16; | ||
| 32 | r >>= 16; | ||
| 33 | } | ||
| 34 | if (!(r & 0xff)) { | ||
| 35 | bit += 8; | ||
| 36 | r >>= 8; | ||
| 37 | } | ||
| 38 | if (!(r & 0xf)) { | ||
| 39 | bit += 4; | ||
| 40 | r >>= 4; | ||
| 41 | } | ||
| 49 | 42 | ||
| 50 | if (mask == 0) | 43 | return (bit + t[ r & 0xf ]); |
| 51 | return(0); | ||
| 52 | for (bit = 1; !(mask & 1); bit++) | ||
| 53 | mask >>= 1; | ||
| 54 | return(bit); | ||
| 55 | } | 44 | } |
diff --git a/src/lib/libc/string/index.c b/src/lib/libc/string/index.c index 3d9c05f961..50e9ca35ab 100644 --- a/src/lib/libc/string/index.c +++ b/src/lib/libc/string/index.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: index.c,v 1.5 2005/08/08 08:05:37 espie Exp $ */ | ||
| 1 | /*- | 2 | /*- |
| 2 | * Copyright (c) 1990 The Regents of the University of California. | 3 | * Copyright (c) 1990 The Regents of the University of California. |
| 3 | * All rights reserved. | 4 | * All rights reserved. |
| @@ -10,11 +11,7 @@ | |||
| 10 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the |
| 12 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. Neither the name of the University nor the names of its contributors |
| 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 | 15 | * may be used to endorse or promote products derived from this software |
| 19 | * without specific prior written permission. | 16 | * without specific prior written permission. |
| 20 | * | 17 | * |
| @@ -31,20 +28,14 @@ | |||
| 31 | * SUCH DAMAGE. | 28 | * SUCH DAMAGE. |
| 32 | */ | 29 | */ |
| 33 | 30 | ||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 35 | /*static char *sccsid = "from: @(#)index.c 5.7 (Berkeley) 2/24/91";*/ | ||
| 36 | static char *rcsid = "$Id: index.c,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $"; | ||
| 37 | #endif /* LIBC_SCCS and not lint */ | ||
| 38 | |||
| 39 | #include <string.h> | 31 | #include <string.h> |
| 40 | 32 | ||
| 41 | char * | 33 | char * |
| 42 | #ifdef STRCHR | 34 | #ifdef STRCHR |
| 43 | strchr(p, ch) | 35 | strchr(const char *p, int ch) |
| 44 | #else | 36 | #else |
| 45 | index(p, ch) | 37 | index(const char *p, int ch) |
| 46 | #endif | 38 | #endif |
| 47 | register const char *p, ch; | ||
| 48 | { | 39 | { |
| 49 | for (;; ++p) { | 40 | for (;; ++p) { |
| 50 | if (*p == ch) | 41 | if (*p == ch) |
diff --git a/src/lib/libc/string/memccpy.3 b/src/lib/libc/string/memccpy.3 index 61df704028..98326d6871 100644 --- a/src/lib/libc/string/memccpy.3 +++ b/src/lib/libc/string/memccpy.3 | |||
| @@ -1,5 +1,7 @@ | |||
| 1 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. | 1 | .\" $OpenBSD: memccpy.3,v 1.12 2013/09/25 21:49:30 millert Exp $ |
| 2 | .\" All rights reserved. | 2 | .\" |
| 3 | .\" Copyright (c) 1990, 1991, 1993 | ||
| 4 | .\" The Regents of the University of California. All rights reserved. | ||
| 3 | .\" | 5 | .\" |
| 4 | .\" Redistribution and use in source and binary forms, with or without | 6 | .\" Redistribution and use in source and binary forms, with or without |
| 5 | .\" modification, are permitted provided that the following conditions | 7 | .\" modification, are permitted provided that the following conditions |
| @@ -9,11 +11,7 @@ | |||
| 9 | .\" 2. Redistributions in binary form must reproduce the above copyright | 11 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 10 | .\" notice, this list of conditions and the following disclaimer in the | 12 | .\" notice, this list of conditions and the following disclaimer in the |
| 11 | .\" documentation and/or other materials provided with the distribution. | 13 | .\" documentation and/or other materials provided with the distribution. |
| 12 | .\" 3. All advertising materials mentioning features or use of this software | 14 | .\" 3. Neither the name of the University nor the names of its contributors |
| 13 | .\" must display the following acknowledgement: | ||
| 14 | .\" This product includes software developed by the University of | ||
| 15 | .\" California, Berkeley and its contributors. | ||
| 16 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 17 | .\" may be used to endorse or promote products derived from this software | 15 | .\" may be used to endorse or promote products derived from this software |
| 18 | .\" without specific prior written permission. | 16 | .\" without specific prior written permission. |
| 19 | .\" | 17 | .\" |
| @@ -29,29 +27,30 @@ | |||
| 29 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 27 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 30 | .\" SUCH DAMAGE. | 28 | .\" SUCH DAMAGE. |
| 31 | .\" | 29 | .\" |
| 32 | .\" from: @(#)memccpy.3 5.4 (Berkeley) 4/19/91 | 30 | .\" @(#)memccpy.3 8.1 (Berkeley) 6/9/93 |
| 33 | .\" $Id: memccpy.3,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $ | ||
| 34 | .\" | 31 | .\" |
| 35 | .Dd April 19, 1991 | 32 | .Dd $Mdocdate: September 25 2013 $ |
| 36 | .Dt MEMCCPY 3 | 33 | .Dt MEMCCPY 3 |
| 37 | .Os | 34 | .Os |
| 38 | .Sh NAME | 35 | .Sh NAME |
| 39 | .Nm memccpy | 36 | .Nm memccpy |
| 37 | .Nd copy string until character found | ||
| 40 | .Sh SYNOPSIS | 38 | .Sh SYNOPSIS |
| 41 | .Fd #include <string.h> | 39 | .In string.h |
| 42 | .Ft void * | 40 | .Ft void * |
| 43 | .Fn memccpy "void *dst" "const void *src" "int c" "size_t len" | 41 | .Fn memccpy "void *dst" "const void *src" "int c" "size_t len" |
| 44 | .Sh DESCRIPTION | 42 | .Sh DESCRIPTION |
| 45 | The | 43 | The |
| 46 | .Fn memccpy | 44 | .Fn memccpy |
| 47 | function | 45 | function copies bytes from string |
| 48 | copies bytes from string | ||
| 49 | .Fa src | 46 | .Fa src |
| 50 | to string | 47 | to string |
| 51 | .Fa dst . | 48 | .Fa dst . |
| 52 | If the character | 49 | If the character |
| 53 | .Fa c | 50 | .Fa c |
| 54 | (as converted to an unsigned char) occurs in the string | 51 | (as converted to an |
| 52 | .Li unsigned char ) | ||
| 53 | occurs in the string | ||
| 55 | .Fa src , | 54 | .Fa src , |
| 56 | the copy stops and a pointer to the byte after the copy of | 55 | the copy stops and a pointer to the byte after the copy of |
| 57 | .Fa c | 56 | .Fa c |
| @@ -60,14 +59,23 @@ in the string | |||
| 60 | is returned. | 59 | is returned. |
| 61 | Otherwise, | 60 | Otherwise, |
| 62 | .Fa len | 61 | .Fa len |
| 63 | bytes are copied, and a NULL pointer is returned. | 62 | bytes are copied, and a null pointer is returned. |
| 63 | .Pp | ||
| 64 | If the | ||
| 65 | .Fa src | ||
| 66 | and | ||
| 67 | .Fa dst | ||
| 68 | strings overlap, the behavior is undefined. | ||
| 64 | .Sh SEE ALSO | 69 | .Sh SEE ALSO |
| 65 | .Xr bcopy 3 , | 70 | .Xr bcopy 3 , |
| 66 | .Xr memcpy 3 , | 71 | .Xr memcpy 3 , |
| 67 | .Xr memmove 3 , | 72 | .Xr memmove 3 , |
| 68 | .Xr strcpy 3 | 73 | .Xr strcpy 3 , |
| 74 | .Xr strlcpy 3 | ||
| 69 | .Sh HISTORY | 75 | .Sh HISTORY |
| 70 | The | 76 | The |
| 71 | .Fn memccpy | 77 | .Fn memccpy |
| 72 | function is | 78 | function first appeared in |
| 73 | .Ud . | 79 | .At V |
| 80 | and was reimplemented for | ||
| 81 | .Bx 4.3 Tahoe . | ||
diff --git a/src/lib/libc/string/memccpy.c b/src/lib/libc/string/memccpy.c index 3a1d7bcca1..485c55fcab 100644 --- a/src/lib/libc/string/memccpy.c +++ b/src/lib/libc/string/memccpy.c | |||
| @@ -1,6 +1,8 @@ | |||
| 1 | /* $OpenBSD: memccpy.c,v 1.6 2005/08/08 08:05:37 espie Exp $ */ | ||
| 2 | |||
| 1 | /*- | 3 | /*- |
| 2 | * Copyright (c) 1990 The Regents of the University of California. | 4 | * Copyright (c) 1990, 1993 |
| 3 | * All rights reserved. | 5 | * The Regents of the University of California. All rights reserved. |
| 4 | * | 6 | * |
| 5 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without |
| 6 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions |
| @@ -10,11 +12,7 @@ | |||
| 10 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the |
| 12 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. All advertising materials mentioning features or use of this software | 15 | * 3. Neither the name of the University nor the names of its contributors |
| 14 | * must display the following acknowledgement: | ||
| 15 | * This product includes software developed by the University of | ||
| 16 | * California, Berkeley and its contributors. | ||
| 17 | * 4. Neither the name of the University nor the names of its contributors | ||
| 18 | * may be used to endorse or promote products derived from this software | 16 | * may be used to endorse or promote products derived from this software |
| 19 | * without specific prior written permission. | 17 | * without specific prior written permission. |
| 20 | * | 18 | * |
| @@ -31,25 +29,16 @@ | |||
| 31 | * SUCH DAMAGE. | 29 | * SUCH DAMAGE. |
| 32 | */ | 30 | */ |
| 33 | 31 | ||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 35 | /*static char *sccsid = "from: @(#)memccpy.c 5.8 (Berkeley) 5/30/91";*/ | ||
| 36 | static char *rcsid = "$Id: memccpy.c,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $"; | ||
| 37 | #endif /* LIBC_SCCS and not lint */ | ||
| 38 | |||
| 39 | #include <string.h> | 32 | #include <string.h> |
| 40 | 33 | ||
| 41 | void * | 34 | void * |
| 42 | memccpy(t, f, c, n) | 35 | memccpy(void *t, const void *f, int c, size_t n) |
| 43 | void *t; | ||
| 44 | const void *f; | ||
| 45 | int c; | ||
| 46 | register size_t n; | ||
| 47 | { | 36 | { |
| 48 | 37 | ||
| 49 | if (n) { | 38 | if (n) { |
| 50 | register unsigned char *tp = t; | 39 | unsigned char *tp = t; |
| 51 | register const unsigned char *fp = f; | 40 | const unsigned char *fp = f; |
| 52 | register unsigned char uc = c; | 41 | unsigned char uc = c; |
| 53 | do { | 42 | do { |
| 54 | if ((*tp++ = *fp++) == uc) | 43 | if ((*tp++ = *fp++) == uc) |
| 55 | return (tp); | 44 | return (tp); |
diff --git a/src/lib/libc/string/memchr.3 b/src/lib/libc/string/memchr.3 index 265711e3b5..8d8a9ddf9c 100644 --- a/src/lib/libc/string/memchr.3 +++ b/src/lib/libc/string/memchr.3 | |||
| @@ -1,3 +1,5 @@ | |||
| 1 | .\" $OpenBSD: memchr.3,v 1.12 2014/04/07 17:57:56 schwarze Exp $ | ||
| 2 | .\" | ||
| 1 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. | 3 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. |
| 2 | .\" All rights reserved. | 4 | .\" All rights reserved. |
| 3 | .\" | 5 | .\" |
| @@ -13,11 +15,7 @@ | |||
| 13 | .\" 2. Redistributions in binary form must reproduce the above copyright | 15 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 14 | .\" notice, this list of conditions and the following disclaimer in the | 16 | .\" notice, this list of conditions and the following disclaimer in the |
| 15 | .\" documentation and/or other materials provided with the distribution. | 17 | .\" documentation and/or other materials provided with the distribution. |
| 16 | .\" 3. All advertising materials mentioning features or use of this software | 18 | .\" 3. Neither the name of the University nor the names of its contributors |
| 17 | .\" must display the following acknowledgement: | ||
| 18 | .\" This product includes software developed by the University of | ||
| 19 | .\" California, Berkeley and its contributors. | ||
| 20 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 21 | .\" may be used to endorse or promote products derived from this software | 19 | .\" may be used to endorse or promote products derived from this software |
| 22 | .\" without specific prior written permission. | 20 | .\" without specific prior written permission. |
| 23 | .\" | 21 | .\" |
| @@ -33,39 +31,48 @@ | |||
| 33 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 34 | .\" SUCH DAMAGE. | 32 | .\" SUCH DAMAGE. |
| 35 | .\" | 33 | .\" |
| 36 | .\" from: @(#)memchr.3 5.4 (Berkeley) 6/29/91 | 34 | .Dd $Mdocdate: April 7 2014 $ |
| 37 | .\" $Id: memchr.3,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $ | ||
| 38 | .\" | ||
| 39 | .Dd June 29, 1991 | ||
| 40 | .Dt MEMCHR 3 | 35 | .Dt MEMCHR 3 |
| 41 | .Os | 36 | .Os |
| 42 | .Sh NAME | 37 | .Sh NAME |
| 43 | .Nm memchr | 38 | .Nm memchr , |
| 39 | .Nm memrchr | ||
| 44 | .Nd locate byte in byte string | 40 | .Nd locate byte in byte string |
| 45 | .Sh SYNOPSIS | 41 | .Sh SYNOPSIS |
| 46 | .Fd #include <string.h> | 42 | .In string.h |
| 47 | .Ft void * | 43 | .Ft void * |
| 48 | .Fn memchr "const void *b" "int c" "size_t len" | 44 | .Fn memchr "const void *b" "int c" "size_t len" |
| 45 | .Ft void * | ||
| 46 | .Fn memrchr "const void *b" "int c" "size_t len" | ||
| 49 | .Sh DESCRIPTION | 47 | .Sh DESCRIPTION |
| 50 | The | 48 | The |
| 51 | .Fn memchr | 49 | .Fn memchr |
| 52 | function | 50 | function locates the first occurrence of |
| 53 | locates the first occurrence of | 51 | .Fa c |
| 52 | (converted to an | ||
| 53 | .Li unsigned char ) | ||
| 54 | in string | ||
| 55 | .Fa b . | ||
| 56 | .Pp | ||
| 57 | The | ||
| 58 | .Fn memrchr | ||
| 59 | function behaves like | ||
| 60 | .Fn memchr , | ||
| 61 | except that it locates the last occurrence of | ||
| 54 | .Fa c | 62 | .Fa c |
| 55 | (converted to an unsigned char) | ||
| 56 | in string | 63 | in string |
| 57 | .Fa b . | 64 | .Fa b . |
| 58 | .Sh RETURN VALUES | 65 | .Sh RETURN VALUES |
| 59 | The | 66 | The |
| 60 | .Fn memchr | 67 | .Fn memchr |
| 61 | function | 68 | and |
| 62 | returns a pointer to the byte located, | 69 | .Fn memrchr |
| 63 | or NULL if no such byte exists within | 70 | functions return a pointer to the byte located, or |
| 71 | .Dv NULL | ||
| 72 | if no such byte exists within | ||
| 64 | .Fa len | 73 | .Fa len |
| 65 | bytes. | 74 | bytes. |
| 66 | .Sh SEE ALSO | 75 | .Sh SEE ALSO |
| 67 | .Xr index 3 , | ||
| 68 | .Xr rindex 3 , | ||
| 69 | .Xr strchr 3 , | 76 | .Xr strchr 3 , |
| 70 | .Xr strcspn 3 , | 77 | .Xr strcspn 3 , |
| 71 | .Xr strpbrk 3 , | 78 | .Xr strpbrk 3 , |
| @@ -73,10 +80,23 @@ bytes. | |||
| 73 | .Xr strsep 3 , | 80 | .Xr strsep 3 , |
| 74 | .Xr strspn 3 , | 81 | .Xr strspn 3 , |
| 75 | .Xr strstr 3 , | 82 | .Xr strstr 3 , |
| 76 | .Xr strtok 3 | 83 | .Xr strtok 3 , |
| 84 | .Xr wmemchr 3 | ||
| 77 | .Sh STANDARDS | 85 | .Sh STANDARDS |
| 78 | The | 86 | The |
| 79 | .Fn memchr | 87 | .Fn memchr |
| 80 | function | 88 | function conforms to |
| 81 | conforms to | ||
| 82 | .St -ansiC . | 89 | .St -ansiC . |
| 90 | .Pp | ||
| 91 | The | ||
| 92 | .Fn memrchr | ||
| 93 | function is an | ||
| 94 | .Ox | ||
| 95 | extension. | ||
| 96 | .Sh HISTORY | ||
| 97 | The | ||
| 98 | .Fn memchr | ||
| 99 | function first appeared in | ||
| 100 | .At V | ||
| 101 | and was reimplemented for | ||
| 102 | .Bx 4.3 Tahoe . | ||
diff --git a/src/lib/libc/string/memchr.c b/src/lib/libc/string/memchr.c index 61652c6bb1..4573e3ceb1 100644 --- a/src/lib/libc/string/memchr.c +++ b/src/lib/libc/string/memchr.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: memchr.c,v 1.7 2005/08/08 08:05:37 espie Exp $ */ | ||
| 1 | /*- | 2 | /*- |
| 2 | * Copyright (c) 1990 The Regents of the University of California. | 3 | * Copyright (c) 1990 The Regents of the University of California. |
| 3 | * All rights reserved. | 4 | * All rights reserved. |
| @@ -13,11 +14,7 @@ | |||
| 13 | * 2. Redistributions in binary form must reproduce the above copyright | 14 | * 2. Redistributions in binary form must reproduce the above copyright |
| 14 | * notice, this list of conditions and the following disclaimer in the | 15 | * notice, this list of conditions and the following disclaimer in the |
| 15 | * documentation and/or other materials provided with the distribution. | 16 | * documentation and/or other materials provided with the distribution. |
| 16 | * 3. All advertising materials mentioning features or use of this software | 17 | * 3. Neither the name of the University nor the names of its contributors |
| 17 | * must display the following acknowledgement: | ||
| 18 | * This product includes software developed by the University of | ||
| 19 | * California, Berkeley and its contributors. | ||
| 20 | * 4. Neither the name of the University nor the names of its contributors | ||
| 21 | * may be used to endorse or promote products derived from this software | 18 | * may be used to endorse or promote products derived from this software |
| 22 | * without specific prior written permission. | 19 | * without specific prior written permission. |
| 23 | * | 20 | * |
| @@ -34,24 +31,16 @@ | |||
| 34 | * SUCH DAMAGE. | 31 | * SUCH DAMAGE. |
| 35 | */ | 32 | */ |
| 36 | 33 | ||
| 37 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 38 | /*static char *sccsid = "from: @(#)memchr.c 5.6 (Berkeley) 1/26/91";*/ | ||
| 39 | static char *rcsid = "$Id: memchr.c,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $"; | ||
| 40 | #endif /* LIBC_SCCS and not lint */ | ||
| 41 | |||
| 42 | #include <string.h> | 34 | #include <string.h> |
| 43 | 35 | ||
| 44 | void * | 36 | void * |
| 45 | memchr(s, c, n) | 37 | memchr(const void *s, int c, size_t n) |
| 46 | const void *s; | ||
| 47 | register unsigned char c; | ||
| 48 | register size_t n; | ||
| 49 | { | 38 | { |
| 50 | if (n != 0) { | 39 | if (n != 0) { |
| 51 | register const unsigned char *p = s; | 40 | const unsigned char *p = s; |
| 52 | 41 | ||
| 53 | do { | 42 | do { |
| 54 | if (*p++ == c) | 43 | if (*p++ == (unsigned char)c) |
| 55 | return ((void *)(p - 1)); | 44 | return ((void *)(p - 1)); |
| 56 | } while (--n != 0); | 45 | } while (--n != 0); |
| 57 | } | 46 | } |
diff --git a/src/lib/libc/string/memcmp.3 b/src/lib/libc/string/memcmp.3 index 13901c1009..ebd838825a 100644 --- a/src/lib/libc/string/memcmp.3 +++ b/src/lib/libc/string/memcmp.3 | |||
| @@ -1,3 +1,5 @@ | |||
| 1 | .\" $OpenBSD: memcmp.3,v 1.8 2013/06/05 03:39:23 tedu Exp $ | ||
| 2 | .\" | ||
| 1 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. | 3 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. |
| 2 | .\" All rights reserved. | 4 | .\" All rights reserved. |
| 3 | .\" | 5 | .\" |
| @@ -13,11 +15,7 @@ | |||
| 13 | .\" 2. Redistributions in binary form must reproduce the above copyright | 15 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 14 | .\" notice, this list of conditions and the following disclaimer in the | 16 | .\" notice, this list of conditions and the following disclaimer in the |
| 15 | .\" documentation and/or other materials provided with the distribution. | 17 | .\" documentation and/or other materials provided with the distribution. |
| 16 | .\" 3. All advertising materials mentioning features or use of this software | 18 | .\" 3. Neither the name of the University nor the names of its contributors |
| 17 | .\" must display the following acknowledgement: | ||
| 18 | .\" This product includes software developed by the University of | ||
| 19 | .\" California, Berkeley and its contributors. | ||
| 20 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 21 | .\" may be used to endorse or promote products derived from this software | 19 | .\" may be used to endorse or promote products derived from this software |
| 22 | .\" without specific prior written permission. | 20 | .\" without specific prior written permission. |
| 23 | .\" | 21 | .\" |
| @@ -33,24 +31,20 @@ | |||
| 33 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 34 | .\" SUCH DAMAGE. | 32 | .\" SUCH DAMAGE. |
| 35 | .\" | 33 | .\" |
| 36 | .\" from: @(#)memcmp.3 5.5 (Berkeley) 6/29/91 | 34 | .Dd $Mdocdate: June 5 2013 $ |
| 37 | .\" $Id: memcmp.3,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $ | ||
| 38 | .\" | ||
| 39 | .Dd June 29, 1991 | ||
| 40 | .Dt MEMCMP 3 | 35 | .Dt MEMCMP 3 |
| 41 | .Os | 36 | .Os |
| 42 | .Sh NAME | 37 | .Sh NAME |
| 43 | .Nm memcmp | 38 | .Nm memcmp |
| 44 | .Nd compare byte string | 39 | .Nd compare byte string |
| 45 | .Sh SYNOPSIS | 40 | .Sh SYNOPSIS |
| 46 | .Fd #include <string.h> | 41 | .In string.h |
| 47 | .Ft int | 42 | .Ft int |
| 48 | .Fn memcmp "const void *b1" "const void *b2" "size_t len" | 43 | .Fn memcmp "const void *b1" "const void *b2" "size_t len" |
| 49 | .Sh DESCRIPTION | 44 | .Sh DESCRIPTION |
| 50 | The | 45 | The |
| 51 | .Fn memcmp | 46 | .Fn memcmp |
| 52 | function | 47 | function compares byte string |
| 53 | compares byte string | ||
| 54 | .Fa b1 | 48 | .Fa b1 |
| 55 | against byte string | 49 | against byte string |
| 56 | .Fa b2 . | 50 | .Fa b2 . |
| @@ -60,10 +54,11 @@ bytes long. | |||
| 60 | .Sh RETURN VALUES | 54 | .Sh RETURN VALUES |
| 61 | The | 55 | The |
| 62 | .Fn memcmp | 56 | .Fn memcmp |
| 63 | function | 57 | function returns zero if the two strings are identical, |
| 64 | returns zero if the the two strings are identical, | ||
| 65 | otherwise returns the difference between the first two differing bytes | 58 | otherwise returns the difference between the first two differing bytes |
| 66 | (treated as unsigned char values, so that | 59 | (treated as |
| 60 | .Li unsigned char | ||
| 61 | values, so that | ||
| 67 | .Sq Li \e200 | 62 | .Sq Li \e200 |
| 68 | is greater than | 63 | is greater than |
| 69 | .Sq Li \&\e0 , | 64 | .Sq Li \&\e0 , |
| @@ -74,10 +69,17 @@ Zero-length strings are always identical. | |||
| 74 | .Xr strcasecmp 3 , | 69 | .Xr strcasecmp 3 , |
| 75 | .Xr strcmp 3 , | 70 | .Xr strcmp 3 , |
| 76 | .Xr strcoll 3 , | 71 | .Xr strcoll 3 , |
| 77 | .Xr strxfrm 3 | 72 | .Xr strxfrm 3 , |
| 73 | .Xr wmemcmp 3 | ||
| 78 | .Sh STANDARDS | 74 | .Sh STANDARDS |
| 79 | The | 75 | The |
| 80 | .Fn memcmp | 76 | .Fn memcmp |
| 81 | function | 77 | function conforms to |
| 82 | conforms to | ||
| 83 | .St -ansiC . | 78 | .St -ansiC . |
| 79 | .Sh HISTORY | ||
| 80 | The | ||
| 81 | .Fn memcmp | ||
| 82 | function first appeared in | ||
| 83 | .At V | ||
| 84 | and was reimplemented for | ||
| 85 | .Bx 4.3 Tahoe . | ||
diff --git a/src/lib/libc/string/memcmp.c b/src/lib/libc/string/memcmp.c index 23d2ab2393..49384a6fb9 100644 --- a/src/lib/libc/string/memcmp.c +++ b/src/lib/libc/string/memcmp.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: memcmp.c,v 1.5 2005/08/08 08:05:37 espie Exp $ */ | ||
| 1 | /*- | 2 | /*- |
| 2 | * Copyright (c) 1990 The Regents of the University of California. | 3 | * Copyright (c) 1990 The Regents of the University of California. |
| 3 | * All rights reserved. | 4 | * All rights reserved. |
| @@ -13,11 +14,7 @@ | |||
| 13 | * 2. Redistributions in binary form must reproduce the above copyright | 14 | * 2. Redistributions in binary form must reproduce the above copyright |
| 14 | * notice, this list of conditions and the following disclaimer in the | 15 | * notice, this list of conditions and the following disclaimer in the |
| 15 | * documentation and/or other materials provided with the distribution. | 16 | * documentation and/or other materials provided with the distribution. |
| 16 | * 3. All advertising materials mentioning features or use of this software | 17 | * 3. Neither the name of the University nor the names of its contributors |
| 17 | * must display the following acknowledgement: | ||
| 18 | * This product includes software developed by the University of | ||
| 19 | * California, Berkeley and its contributors. | ||
| 20 | * 4. Neither the name of the University nor the names of its contributors | ||
| 21 | * may be used to endorse or promote products derived from this software | 18 | * may be used to endorse or promote products derived from this software |
| 22 | * without specific prior written permission. | 19 | * without specific prior written permission. |
| 23 | * | 20 | * |
| @@ -34,23 +31,16 @@ | |||
| 34 | * SUCH DAMAGE. | 31 | * SUCH DAMAGE. |
| 35 | */ | 32 | */ |
| 36 | 33 | ||
| 37 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 38 | /*static char *sccsid = "from: @(#)memcmp.c 5.6 (Berkeley) 1/26/91";*/ | ||
| 39 | static char *rcsid = "$Id: memcmp.c,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $"; | ||
| 40 | #endif /* LIBC_SCCS and not lint */ | ||
| 41 | |||
| 42 | #include <string.h> | 34 | #include <string.h> |
| 43 | 35 | ||
| 44 | /* | 36 | /* |
| 45 | * Compare memory regions. | 37 | * Compare memory regions. |
| 46 | */ | 38 | */ |
| 47 | int | 39 | int |
| 48 | memcmp(s1, s2, n) | 40 | memcmp(const void *s1, const void *s2, size_t n) |
| 49 | const void *s1, *s2; | ||
| 50 | size_t n; | ||
| 51 | { | 41 | { |
| 52 | if (n != 0) { | 42 | if (n != 0) { |
| 53 | register const unsigned char *p1 = s1, *p2 = s2; | 43 | const unsigned char *p1 = s1, *p2 = s2; |
| 54 | 44 | ||
| 55 | do { | 45 | do { |
| 56 | if (*p1++ != *p2++) | 46 | if (*p1++ != *p2++) |
diff --git a/src/lib/libc/string/memcpy.3 b/src/lib/libc/string/memcpy.3 index 3f4bb643c9..8df2a785b9 100644 --- a/src/lib/libc/string/memcpy.3 +++ b/src/lib/libc/string/memcpy.3 | |||
| @@ -1,3 +1,5 @@ | |||
| 1 | .\" $OpenBSD: memcpy.3,v 1.10 2013/06/05 03:39:23 tedu Exp $ | ||
| 2 | .\" | ||
| 1 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. | 3 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. |
| 2 | .\" All rights reserved. | 4 | .\" All rights reserved. |
| 3 | .\" | 5 | .\" |
| @@ -13,11 +15,7 @@ | |||
| 13 | .\" 2. Redistributions in binary form must reproduce the above copyright | 15 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 14 | .\" notice, this list of conditions and the following disclaimer in the | 16 | .\" notice, this list of conditions and the following disclaimer in the |
| 15 | .\" documentation and/or other materials provided with the distribution. | 17 | .\" documentation and/or other materials provided with the distribution. |
| 16 | .\" 3. All advertising materials mentioning features or use of this software | 18 | .\" 3. Neither the name of the University nor the names of its contributors |
| 17 | .\" must display the following acknowledgement: | ||
| 18 | .\" This product includes software developed by the University of | ||
| 19 | .\" California, Berkeley and its contributors. | ||
| 20 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 21 | .\" may be used to endorse or promote products derived from this software | 19 | .\" may be used to endorse or promote products derived from this software |
| 22 | .\" without specific prior written permission. | 20 | .\" without specific prior written permission. |
| 23 | .\" | 21 | .\" |
| @@ -33,52 +31,49 @@ | |||
| 33 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 34 | .\" SUCH DAMAGE. | 32 | .\" SUCH DAMAGE. |
| 35 | .\" | 33 | .\" |
| 36 | .\" from: @(#)memcpy.3 5.5 (Berkeley) 6/29/91 | 34 | .Dd $Mdocdate: June 5 2013 $ |
| 37 | .\" $Id: memcpy.3,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $ | ||
| 38 | .\" | ||
| 39 | .Dd June 29, 1991 | ||
| 40 | .Dt MEMCPY 3 | 35 | .Dt MEMCPY 3 |
| 41 | .Os | 36 | .Os |
| 42 | .Sh NAME | 37 | .Sh NAME |
| 43 | .Nm memcpy | 38 | .Nm memcpy |
| 44 | .Nd copy byte string | 39 | .Nd copy bytes |
| 45 | .Sh SYNOPSIS | 40 | .Sh SYNOPSIS |
| 46 | .Fd #include <string.h> | 41 | .In string.h |
| 47 | .Ft void * | 42 | .Ft void * |
| 48 | .Fn memcpy "void *dst" "const void *src" "size_t len" | 43 | .Fn memcpy "void *dst" "const void *src" "size_t len" |
| 49 | .Sh DESCRIPTION | 44 | .Sh DESCRIPTION |
| 50 | The | 45 | The |
| 51 | .Fn memcpy | 46 | .Fn memcpy |
| 52 | function | 47 | function copies |
| 53 | copies | ||
| 54 | .Fa len | 48 | .Fa len |
| 55 | bytes from string | 49 | bytes from buffer |
| 56 | .Fa src | 50 | .Fa src |
| 57 | to string | 51 | to buffer |
| 58 | .Fa dst . | 52 | .Fa dst . |
| 53 | If the two buffers may overlap, | ||
| 54 | .Xr memmove 3 | ||
| 55 | must be used instead. | ||
| 59 | .Sh RETURN VALUES | 56 | .Sh RETURN VALUES |
| 60 | The | 57 | The |
| 61 | .Fn memcpy | 58 | .Fn memcpy |
| 62 | function | 59 | function returns the original value of |
| 63 | returns the original value of | ||
| 64 | .Fa dst . | 60 | .Fa dst . |
| 65 | .Sh SEE ALSO | 61 | .Sh SEE ALSO |
| 66 | .Xr bcopy 3 , | 62 | .Xr bcopy 3 , |
| 67 | .Xr memccpy 3 , | 63 | .Xr memccpy 3 , |
| 68 | .Xr memmove 3 , | 64 | .Xr memmove 3 , |
| 69 | .Xr strcpy 3 | 65 | .Xr strcpy 3 , |
| 66 | .Xr strlcpy 3 , | ||
| 67 | .Xr wmemcpy 3 | ||
| 70 | .Sh STANDARDS | 68 | .Sh STANDARDS |
| 71 | The | 69 | The |
| 72 | .Fn memcpy | 70 | .Fn memcpy |
| 73 | function | 71 | function conforms to |
| 74 | conforms to | ||
| 75 | .St -ansiC . | 72 | .St -ansiC . |
| 76 | .Sh BUGS | 73 | .Sh HISTORY |
| 77 | In this implementation | 74 | The |
| 78 | .Fn memcpy | 75 | .Fn memcpy |
| 79 | is implemented using | 76 | function first appeared in |
| 80 | .Xr bcopy 3 , | 77 | .At V |
| 81 | and therefore the strings may overlap. | 78 | and was reimplemented for |
| 82 | On other systems, copying overlapping strings may produce surprises. | 79 | .Bx 4.3 Tahoe . |
| 83 | A simpler solution is to not use | ||
| 84 | .Fn memcpy . | ||
diff --git a/src/lib/libc/string/memmem.3 b/src/lib/libc/string/memmem.3 new file mode 100644 index 0000000000..b0b0bb966b --- /dev/null +++ b/src/lib/libc/string/memmem.3 | |||
| @@ -0,0 +1,77 @@ | |||
| 1 | .\" $OpenBSD: memmem.3,v 1.2 2013/07/16 15:21:11 schwarze Exp $ | ||
| 2 | .\" | ||
| 3 | .\" Copyright (c) 2005 Pascal Gloor <pascal.gloor@spale.com> | ||
| 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 | ||
| 14 | .\" products derived from this software without specific prior written | ||
| 15 | .\" permission. | ||
| 16 | .\" | ||
| 17 | .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | ||
| 18 | .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 19 | .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 20 | .\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
| 21 | .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 22 | .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 23 | .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 24 | .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 25 | .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 26 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 27 | .\" SUCH DAMAGE. | ||
| 28 | .\" | ||
| 29 | .Dd $Mdocdate: July 16 2013 $ | ||
| 30 | .Dt MEMMEM 3 | ||
| 31 | .Os | ||
| 32 | .Sh NAME | ||
| 33 | .Nm memmem | ||
| 34 | .Nd locate a byte substring in a byte string | ||
| 35 | .Sh SYNOPSIS | ||
| 36 | .In string.h | ||
| 37 | .Ft "void *" | ||
| 38 | .Fo memmem | ||
| 39 | .Fa "const void *big" "size_t big_len" | ||
| 40 | .Fa "const void *little" "size_t little_len" | ||
| 41 | .Fc | ||
| 42 | .Sh DESCRIPTION | ||
| 43 | The | ||
| 44 | .Fn memmem | ||
| 45 | function | ||
| 46 | locates the first occurrence of the byte string | ||
| 47 | .Fa little | ||
| 48 | in the byte string | ||
| 49 | .Fa big . | ||
| 50 | .Sh RETURN VALUES | ||
| 51 | If | ||
| 52 | .Fa little | ||
| 53 | is zero length, | ||
| 54 | .Fa big | ||
| 55 | is returned; if | ||
| 56 | .Fa little | ||
| 57 | occurs nowhere in | ||
| 58 | .Fa big , | ||
| 59 | .Dv NULL | ||
| 60 | is returned; | ||
| 61 | otherwise a pointer to the first character of the first occurrence of | ||
| 62 | .Fa little | ||
| 63 | is returned. | ||
| 64 | .Sh SEE ALSO | ||
| 65 | .Xr memchr 3 , | ||
| 66 | .Xr strchr 3 , | ||
| 67 | .Xr strstr 3 | ||
| 68 | .Sh STANDARDS | ||
| 69 | .Fn memmem | ||
| 70 | is a GNU extension. | ||
| 71 | .Sh HISTORY | ||
| 72 | The | ||
| 73 | .Fn memmem | ||
| 74 | function first appeared in | ||
| 75 | .Ox 5.4 . | ||
| 76 | .Sh AUTHORS | ||
| 77 | .An Pascal Gloor Aq Mt pascal.gloor@spale.com | ||
diff --git a/src/lib/libc/string/memmem.c b/src/lib/libc/string/memmem.c new file mode 100644 index 0000000000..5793a7dfd7 --- /dev/null +++ b/src/lib/libc/string/memmem.c | |||
| @@ -0,0 +1,63 @@ | |||
| 1 | /* $OpenBSD: memmem.c,v 1.3 2013/05/30 01:10:45 ajacoutot Exp $ */ | ||
| 2 | /*- | ||
| 3 | * Copyright (c) 2005 Pascal Gloor <pascal.gloor@spale.com> | ||
| 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 | ||
| 14 | * products derived from this software without specific prior written | ||
| 15 | * permission. | ||
| 16 | * | ||
| 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | ||
| 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
| 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 27 | * SUCH DAMAGE. | ||
| 28 | */ | ||
| 29 | |||
| 30 | #include <string.h> | ||
| 31 | |||
| 32 | /* | ||
| 33 | * Find the first occurrence of the byte string s in byte string l. | ||
| 34 | */ | ||
| 35 | |||
| 36 | void * | ||
| 37 | memmem(const void *l, size_t l_len, const void *s, size_t s_len) | ||
| 38 | { | ||
| 39 | const char *cur, *last; | ||
| 40 | const char *cl = l; | ||
| 41 | const char *cs = s; | ||
| 42 | |||
| 43 | /* a zero length needle should just return the haystack */ | ||
| 44 | if (s_len == 0) | ||
| 45 | return (void *)cl; | ||
| 46 | |||
| 47 | /* "s" must be smaller or equal to "l" */ | ||
| 48 | if (l_len < s_len) | ||
| 49 | return NULL; | ||
| 50 | |||
| 51 | /* special case where s_len == 1 */ | ||
| 52 | if (s_len == 1) | ||
| 53 | return memchr(l, *cs, l_len); | ||
| 54 | |||
| 55 | /* the last position where its possible to find "s" in "l" */ | ||
| 56 | last = cl + l_len - s_len; | ||
| 57 | |||
| 58 | for (cur = cl; cur <= last; cur++) | ||
| 59 | if (cur[0] == cs[0] && memcmp(cur, cs, s_len) == 0) | ||
| 60 | return (void *)cur; | ||
| 61 | |||
| 62 | return NULL; | ||
| 63 | } | ||
diff --git a/src/lib/libc/string/memmove.3 b/src/lib/libc/string/memmove.3 index 24422e7971..8665e4abcf 100644 --- a/src/lib/libc/string/memmove.3 +++ b/src/lib/libc/string/memmove.3 | |||
| @@ -1,3 +1,5 @@ | |||
| 1 | .\" $OpenBSD: memmove.3,v 1.9 2013/06/05 03:39:23 tedu Exp $ | ||
| 2 | .\" | ||
| 1 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. | 3 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. |
| 2 | .\" All rights reserved. | 4 | .\" All rights reserved. |
| 3 | .\" | 5 | .\" |
| @@ -13,11 +15,7 @@ | |||
| 13 | .\" 2. Redistributions in binary form must reproduce the above copyright | 15 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 14 | .\" notice, this list of conditions and the following disclaimer in the | 16 | .\" notice, this list of conditions and the following disclaimer in the |
| 15 | .\" documentation and/or other materials provided with the distribution. | 17 | .\" documentation and/or other materials provided with the distribution. |
| 16 | .\" 3. All advertising materials mentioning features or use of this software | 18 | .\" 3. Neither the name of the University nor the names of its contributors |
| 17 | .\" must display the following acknowledgement: | ||
| 18 | .\" This product includes software developed by the University of | ||
| 19 | .\" California, Berkeley and its contributors. | ||
| 20 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 21 | .\" may be used to endorse or promote products derived from this software | 19 | .\" may be used to endorse or promote products derived from this software |
| 22 | .\" without specific prior written permission. | 20 | .\" without specific prior written permission. |
| 23 | .\" | 21 | .\" |
| @@ -33,30 +31,26 @@ | |||
| 33 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 34 | .\" SUCH DAMAGE. | 32 | .\" SUCH DAMAGE. |
| 35 | .\" | 33 | .\" |
| 36 | .\" from: @(#)memmove.3 5.5 (Berkeley) 6/29/91 | 34 | .Dd $Mdocdate: June 5 2013 $ |
| 37 | .\" $Id: memmove.3,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $ | ||
| 38 | .\" | ||
| 39 | .Dd June 29, 1991 | ||
| 40 | .Dt MEMMOVE 3 | 35 | .Dt MEMMOVE 3 |
| 41 | .Os | 36 | .Os |
| 42 | .Sh NAME | 37 | .Sh NAME |
| 43 | .Nm memmove | 38 | .Nm memmove |
| 44 | .Nd copy byte string | 39 | .Nd copy bytes |
| 45 | .Sh SYNOPSIS | 40 | .Sh SYNOPSIS |
| 46 | .Fd #include <string.h> | 41 | .In string.h |
| 47 | .Ft void * | 42 | .Ft void * |
| 48 | .Fn memmove "void *dst" "const void *src" "size_t len" | 43 | .Fn memmove "void *dst" "const void *src" "size_t len" |
| 49 | .Sh DESCRIPTION | 44 | .Sh DESCRIPTION |
| 50 | The | 45 | The |
| 51 | .Fn memmove | 46 | .Fn memmove |
| 52 | function | 47 | function copies |
| 53 | copies | ||
| 54 | .Fa len | 48 | .Fa len |
| 55 | bytes from string | 49 | bytes from buffer |
| 56 | .Fa src | 50 | .Fa src |
| 57 | to string | 51 | to buffer |
| 58 | .Fa dst . | 52 | .Fa dst . |
| 59 | The two strings may overlap; | 53 | The two buffers may overlap; |
| 60 | the copy is always done in a non-destructive manner. | 54 | the copy is always done in a non-destructive manner. |
| 61 | .Sh RETURN VALUES | 55 | .Sh RETURN VALUES |
| 62 | The | 56 | The |
| @@ -67,10 +61,16 @@ function returns the original value of | |||
| 67 | .Xr bcopy 3 , | 61 | .Xr bcopy 3 , |
| 68 | .Xr memccpy 3 , | 62 | .Xr memccpy 3 , |
| 69 | .Xr memcpy 3 , | 63 | .Xr memcpy 3 , |
| 70 | .Xr strcpy 3 | 64 | .Xr strcpy 3 , |
| 65 | .Xr strlcpy 3 , | ||
| 66 | .Xr wmemmove 3 | ||
| 71 | .Sh STANDARDS | 67 | .Sh STANDARDS |
| 72 | The | 68 | The |
| 73 | .Fn memmove | 69 | .Fn memmove |
| 74 | function | 70 | function conforms to |
| 75 | conforms to | ||
| 76 | .St -ansiC . | 71 | .St -ansiC . |
| 72 | .Sh HISTORY | ||
| 73 | The | ||
| 74 | .Fn memmove | ||
| 75 | function first appeared in | ||
| 76 | .Bx 4.3 Reno . | ||
diff --git a/src/lib/libc/string/memrchr.c b/src/lib/libc/string/memrchr.c new file mode 100644 index 0000000000..bd27ebc620 --- /dev/null +++ b/src/lib/libc/string/memrchr.c | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | /* $OpenBSD: memrchr.c,v 1.2 2007/11/27 16:22:12 martynas Exp $ */ | ||
| 2 | |||
| 3 | /* | ||
| 4 | * Copyright (c) 2007 Todd C. Miller <Todd.Miller@courtesan.com> | ||
| 5 | * | ||
| 6 | * Permission to use, copy, modify, and distribute this software for any | ||
| 7 | * purpose with or without fee is hereby granted, provided that the above | ||
| 8 | * copyright notice and this permission notice appear in all copies. | ||
| 9 | * | ||
| 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <string.h> | ||
| 20 | |||
| 21 | /* | ||
| 22 | * Reverse memchr() | ||
| 23 | * Find the last occurrence of 'c' in the buffer 's' of size 'n'. | ||
| 24 | */ | ||
| 25 | void * | ||
| 26 | memrchr(const void *s, int c, size_t n) | ||
| 27 | { | ||
| 28 | const unsigned char *cp; | ||
| 29 | |||
| 30 | if (n != 0) { | ||
| 31 | cp = (unsigned char *)s + n; | ||
| 32 | do { | ||
| 33 | if (*(--cp) == (unsigned char)c) | ||
| 34 | return((void *)cp); | ||
| 35 | } while (--n != 0); | ||
| 36 | } | ||
| 37 | return(NULL); | ||
| 38 | } | ||
diff --git a/src/lib/libc/string/memset.3 b/src/lib/libc/string/memset.3 index 1afc052182..ac5b7e90ad 100644 --- a/src/lib/libc/string/memset.3 +++ b/src/lib/libc/string/memset.3 | |||
| @@ -1,3 +1,5 @@ | |||
| 1 | .\" $OpenBSD: memset.3,v 1.8 2013/06/05 03:39:23 tedu Exp $ | ||
| 2 | .\" | ||
| 1 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. | 3 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. |
| 2 | .\" All rights reserved. | 4 | .\" All rights reserved. |
| 3 | .\" | 5 | .\" |
| @@ -13,11 +15,7 @@ | |||
| 13 | .\" 2. Redistributions in binary form must reproduce the above copyright | 15 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 14 | .\" notice, this list of conditions and the following disclaimer in the | 16 | .\" notice, this list of conditions and the following disclaimer in the |
| 15 | .\" documentation and/or other materials provided with the distribution. | 17 | .\" documentation and/or other materials provided with the distribution. |
| 16 | .\" 3. All advertising materials mentioning features or use of this software | 18 | .\" 3. Neither the name of the University nor the names of its contributors |
| 17 | .\" must display the following acknowledgement: | ||
| 18 | .\" This product includes software developed by the University of | ||
| 19 | .\" California, Berkeley and its contributors. | ||
| 20 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 21 | .\" may be used to endorse or promote products derived from this software | 19 | .\" may be used to endorse or promote products derived from this software |
| 22 | .\" without specific prior written permission. | 20 | .\" without specific prior written permission. |
| 23 | .\" | 21 | .\" |
| @@ -33,35 +31,45 @@ | |||
| 33 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 34 | .\" SUCH DAMAGE. | 32 | .\" SUCH DAMAGE. |
| 35 | .\" | 33 | .\" |
| 36 | .\" from: @(#)memset.3 5.4 (Berkeley) 6/29/91 | 34 | .Dd $Mdocdate: June 5 2013 $ |
| 37 | .\" $Id: memset.3,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $ | ||
| 38 | .\" | ||
| 39 | .Dd June 29, 1991 | ||
| 40 | .Dt MEMSET 3 | 35 | .Dt MEMSET 3 |
| 41 | .Os | 36 | .Os |
| 42 | .Sh NAME | 37 | .Sh NAME |
| 43 | .Nm memset | 38 | .Nm memset |
| 44 | .Nd write a byte to byte string | 39 | .Nd write a byte to byte string |
| 45 | .Sh SYNOPSIS | 40 | .Sh SYNOPSIS |
| 46 | .Fd #include <string.h> | 41 | .In string.h |
| 47 | .Ft void * | 42 | .Ft void * |
| 48 | .Fn memset "void *b" "int c" "size_t len" | 43 | .Fn memset "void *b" "int c" "size_t len" |
| 49 | .Sh DESCRIPTION | 44 | .Sh DESCRIPTION |
| 50 | The | 45 | The |
| 51 | .Fn memset | 46 | .Fn memset |
| 52 | function | 47 | function writes |
| 53 | writes | ||
| 54 | .Fa len | 48 | .Fa len |
| 55 | bytes of value | 49 | bytes of value |
| 56 | .Fa c | 50 | .Fa c |
| 57 | (converted to an unsigned char) to the string | 51 | (converted to an |
| 52 | .Li unsigned char ) | ||
| 53 | to the string | ||
| 54 | .Fa b . | ||
| 55 | .Sh RETURN VALUES | ||
| 56 | The | ||
| 57 | .Fn memset | ||
| 58 | function returns the original value of | ||
| 58 | .Fa b . | 59 | .Fa b . |
| 59 | .Sh SEE ALSO | 60 | .Sh SEE ALSO |
| 60 | .Xr bzero 3 , | 61 | .Xr bzero 3 , |
| 61 | .Xr swab 3 | 62 | .Xr swab 3 , |
| 63 | .Xr wmemset 3 | ||
| 62 | .Sh STANDARDS | 64 | .Sh STANDARDS |
| 63 | The | 65 | The |
| 64 | .Fn memset | 66 | .Fn memset |
| 65 | function | 67 | function conforms to |
| 66 | conforms to | ||
| 67 | .St -ansiC . | 68 | .St -ansiC . |
| 69 | .Sh HISTORY | ||
| 70 | The | ||
| 71 | .Fn memset | ||
| 72 | function first appeared in | ||
| 73 | .At V | ||
| 74 | and was reimplemented for | ||
| 75 | .Bx 4.3 Tahoe . | ||
diff --git a/src/lib/libc/string/memset.c b/src/lib/libc/string/memset.c index 117de2e80b..61709c139d 100644 --- a/src/lib/libc/string/memset.c +++ b/src/lib/libc/string/memset.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: memset.c,v 1.6 2008/03/15 21:40:39 ray Exp $ */ | ||
| 1 | /*- | 2 | /*- |
| 2 | * Copyright (c) 1990 The Regents of the University of California. | 3 | * Copyright (c) 1990 The Regents of the University of California. |
| 3 | * All rights reserved. | 4 | * All rights reserved. |
| @@ -13,11 +14,7 @@ | |||
| 13 | * 2. Redistributions in binary form must reproduce the above copyright | 14 | * 2. Redistributions in binary form must reproduce the above copyright |
| 14 | * notice, this list of conditions and the following disclaimer in the | 15 | * notice, this list of conditions and the following disclaimer in the |
| 15 | * documentation and/or other materials provided with the distribution. | 16 | * documentation and/or other materials provided with the distribution. |
| 16 | * 3. All advertising materials mentioning features or use of this software | 17 | * 3. Neither the name of the University nor the names of its contributors |
| 17 | * must display the following acknowledgement: | ||
| 18 | * This product includes software developed by the University of | ||
| 19 | * California, Berkeley and its contributors. | ||
| 20 | * 4. Neither the name of the University nor the names of its contributors | ||
| 21 | * may be used to endorse or promote products derived from this software | 18 | * may be used to endorse or promote products derived from this software |
| 22 | * without specific prior written permission. | 19 | * without specific prior written permission. |
| 23 | * | 20 | * |
| @@ -34,25 +31,16 @@ | |||
| 34 | * SUCH DAMAGE. | 31 | * SUCH DAMAGE. |
| 35 | */ | 32 | */ |
| 36 | 33 | ||
| 37 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 38 | /*static char *sccsid = "from: @(#)memset.c 5.6 (Berkeley) 1/26/91";*/ | ||
| 39 | static char *rcsid = "$Id: memset.c,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $"; | ||
| 40 | #endif /* LIBC_SCCS and not lint */ | ||
| 41 | |||
| 42 | #include <string.h> | 34 | #include <string.h> |
| 43 | 35 | ||
| 44 | void * | 36 | void * |
| 45 | memset(dst, c, n) | 37 | memset(void *dst, int c, size_t n) |
| 46 | void *dst; | ||
| 47 | register int c; | ||
| 48 | register size_t n; | ||
| 49 | { | 38 | { |
| 50 | |||
| 51 | if (n != 0) { | 39 | if (n != 0) { |
| 52 | register char *d = dst; | 40 | unsigned char *d = dst; |
| 53 | 41 | ||
| 54 | do | 42 | do |
| 55 | *d++ = c; | 43 | *d++ = (unsigned char)c; |
| 56 | while (--n != 0); | 44 | while (--n != 0); |
| 57 | } | 45 | } |
| 58 | return (dst); | 46 | return (dst); |
diff --git a/src/lib/libc/string/rindex.c b/src/lib/libc/string/rindex.c index 1b84c92072..bf9d6f7cf1 100644 --- a/src/lib/libc/string/rindex.c +++ b/src/lib/libc/string/rindex.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: rindex.c,v 1.6 2005/08/08 08:05:37 espie Exp $ */ | ||
| 1 | /* | 2 | /* |
| 2 | * Copyright (c) 1988 Regents of the University of California. | 3 | * Copyright (c) 1988 Regents of the University of California. |
| 3 | * All rights reserved. | 4 | * All rights reserved. |
| @@ -10,11 +11,7 @@ | |||
| 10 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the |
| 12 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. Neither the name of the University nor the names of its contributors |
| 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 | 15 | * may be used to endorse or promote products derived from this software |
| 19 | * without specific prior written permission. | 16 | * without specific prior written permission. |
| 20 | * | 17 | * |
| @@ -31,22 +28,16 @@ | |||
| 31 | * SUCH DAMAGE. | 28 | * SUCH DAMAGE. |
| 32 | */ | 29 | */ |
| 33 | 30 | ||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 35 | /*static char *sccsid = "from: @(#)rindex.c 5.9 (Berkeley) 2/24/91";*/ | ||
| 36 | static char *rcsid = "$Id: rindex.c,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $"; | ||
| 37 | #endif /* LIBC_SCCS and not lint */ | ||
| 38 | |||
| 39 | #include <string.h> | 31 | #include <string.h> |
| 40 | 32 | ||
| 41 | char * | 33 | char * |
| 42 | #ifdef STRRCHR | 34 | #ifdef STRRCHR |
| 43 | strrchr(p, ch) | 35 | strrchr(const char *p, int ch) |
| 44 | #else | 36 | #else |
| 45 | rindex(p, ch) | 37 | rindex(const char *p, int ch) |
| 46 | #endif | 38 | #endif |
| 47 | register const char *p, ch; | ||
| 48 | { | 39 | { |
| 49 | register char *save; | 40 | char *save; |
| 50 | 41 | ||
| 51 | for (save = NULL;; ++p) { | 42 | for (save = NULL;; ++p) { |
| 52 | if (*p == ch) | 43 | if (*p == ch) |
diff --git a/src/lib/libc/string/stpcpy.3 b/src/lib/libc/string/stpcpy.3 new file mode 100644 index 0000000000..973eebecdd --- /dev/null +++ b/src/lib/libc/string/stpcpy.3 | |||
| @@ -0,0 +1,184 @@ | |||
| 1 | .\" $OpenBSD: stpcpy.3,v 1.6 2014/02/23 23:09:34 schwarze Exp $ | ||
| 2 | .\" | ||
| 3 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. | ||
| 4 | .\" All rights reserved. | ||
| 5 | .\" | ||
| 6 | .\" This code is derived from software contributed to Berkeley by | ||
| 7 | .\" Chris Torek and the American National Standards Committee X3, | ||
| 8 | .\" on Information Processing Systems. | ||
| 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. 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 $Mdocdate: February 23 2014 $ | ||
| 35 | .Dt STPCPY 3 | ||
| 36 | .Os | ||
| 37 | .Sh NAME | ||
| 38 | .Nm stpcpy , | ||
| 39 | .Nm stpncpy | ||
| 40 | .Nd copy strings | ||
| 41 | .Sh SYNOPSIS | ||
| 42 | .In string.h | ||
| 43 | .Ft char * | ||
| 44 | .Fn stpcpy "char *dst" "const char *src" | ||
| 45 | .Ft char * | ||
| 46 | .Fn stpncpy "char *dst" "const char *src" "size_t len" | ||
| 47 | .Sh DESCRIPTION | ||
| 48 | The | ||
| 49 | .Fn stpcpy | ||
| 50 | and | ||
| 51 | .Fn stpncpy | ||
| 52 | functions copy the string | ||
| 53 | .Fa src | ||
| 54 | to | ||
| 55 | .Fa dst | ||
| 56 | (including the terminating | ||
| 57 | .Ql \e0 | ||
| 58 | character). | ||
| 59 | .Pp | ||
| 60 | The | ||
| 61 | .Fn stpncpy | ||
| 62 | function copies not more than | ||
| 63 | .Fa len | ||
| 64 | characters into | ||
| 65 | .Fa dst , | ||
| 66 | appending | ||
| 67 | .Ql \e0 | ||
| 68 | characters if | ||
| 69 | .Fa src | ||
| 70 | is less than | ||
| 71 | .Fa len | ||
| 72 | characters long, and | ||
| 73 | .Em not | ||
| 74 | terminating | ||
| 75 | .Fa dst | ||
| 76 | if the length of | ||
| 77 | .Fa src | ||
| 78 | is greater than or equal to | ||
| 79 | .Fa len . | ||
| 80 | .Pp | ||
| 81 | If the | ||
| 82 | .Fa src | ||
| 83 | and | ||
| 84 | .Fa dst | ||
| 85 | strings overlap, the behavior is undefined. | ||
| 86 | .Sh RETURN VALUES | ||
| 87 | The | ||
| 88 | .Fn stpcpy | ||
| 89 | function returns a pointer to the terminating | ||
| 90 | .Ql \e0 | ||
| 91 | character written into | ||
| 92 | .Fa dst . | ||
| 93 | .Pp | ||
| 94 | The | ||
| 95 | .Fn stpncpy | ||
| 96 | function returns a pointer to the first | ||
| 97 | .Ql \e0 | ||
| 98 | character written into | ||
| 99 | .Fa dst , | ||
| 100 | or to | ||
| 101 | .Fa &dst[len] | ||
| 102 | if the length of | ||
| 103 | .Fa src | ||
| 104 | is greater than or equal to | ||
| 105 | .Fa len . | ||
| 106 | .Sh EXAMPLES | ||
| 107 | The most common use of | ||
| 108 | .Fn stpcpy | ||
| 109 | is to build up a string from multiple elements. | ||
| 110 | The following example builds up a pathname from | ||
| 111 | directory and file components using | ||
| 112 | .Fn stpcpy : | ||
| 113 | .Bd -literal -offset indent | ||
| 114 | char *dir, *file, pname[PATH_MAX]; | ||
| 115 | |||
| 116 | \&... | ||
| 117 | |||
| 118 | if (strlen(dir) + strlen("/") + strlen(file) >= sizeof(pname)) | ||
| 119 | goto toolong; | ||
| 120 | stpcpy(stpcpy(stpcpy(pname, dir), "/"), file); | ||
| 121 | .Ed | ||
| 122 | .Pp | ||
| 123 | However, the size check required to avoid a buffer overflow is error | ||
| 124 | prone since the check can become out of sync with the code that | ||
| 125 | performs the copy. | ||
| 126 | .Pp | ||
| 127 | One might expect that | ||
| 128 | .Fn stpncpy | ||
| 129 | could be safely used instead, but it suffers from the same defects as | ||
| 130 | .Fn strncpy . | ||
| 131 | The example below using | ||
| 132 | .Fn stpncpy | ||
| 133 | is even more prone to error and will not detect when truncation occurs: | ||
| 134 | .Bd -literal -offset indent | ||
| 135 | char *dir, *file, pname[PATH_MAX]; | ||
| 136 | char *p1, *p2; | ||
| 137 | |||
| 138 | \&... | ||
| 139 | |||
| 140 | p1 = stpncpy(pname, dir, sizeof(pname) - 1); | ||
| 141 | p2 = stpncpy(p1, "/", sizeof(pname) - 1 - (p1 - pname)); | ||
| 142 | stpncpy(p2, file, sizeof(pname) - 1 - (p2 - pname)); | ||
| 143 | pname[sizeof(pname) - 1] = '\e0'; | ||
| 144 | .Ed | ||
| 145 | .Pp | ||
| 146 | A safer (and simpler) approach is to use | ||
| 147 | .Fn snprintf : | ||
| 148 | .Bd -literal -offset indent | ||
| 149 | char *dir, *file, pname[PATH_MAX]; | ||
| 150 | int len; | ||
| 151 | |||
| 152 | \&... | ||
| 153 | |||
| 154 | len = snprintf(pname, sizeof(pname), "%s/%s", dir, file); | ||
| 155 | if (len >= sizeof(pname)) | ||
| 156 | goto toolong; | ||
| 157 | .Ed | ||
| 158 | .Pp | ||
| 159 | In most cases, it is better to use | ||
| 160 | .Fn snprintf , | ||
| 161 | .Fn strlcpy , | ||
| 162 | or | ||
| 163 | .Fn strlcat . | ||
| 164 | .Sh SEE ALSO | ||
| 165 | .Xr snprintf 3 , | ||
| 166 | .Xr strcpy 3 , | ||
| 167 | .Xr strlcpy 3 , | ||
| 168 | .Xr strncpy 3 | ||
| 169 | .Sh STANDARDS | ||
| 170 | The | ||
| 171 | .Fn stpcpy | ||
| 172 | and | ||
| 173 | .Fn stpncpy | ||
| 174 | functions conform to | ||
| 175 | .St -p1003.1-2008 . | ||
| 176 | .Sh HISTORY | ||
| 177 | The function | ||
| 178 | .Fn stpcpy | ||
| 179 | first appeared in the Lattice C AmigaDOS compiler (1986 or earlier). | ||
| 180 | The function | ||
| 181 | .Fn stpncpy | ||
| 182 | first appeared in the GNU C library version 1.07 (1993). | ||
| 183 | Both functions have been available since | ||
| 184 | .Ox 5.1 . | ||
diff --git a/src/lib/libc/string/__strsignal.c b/src/lib/libc/string/stpcpy.c index 1937e2d608..d3d61e0f14 100644 --- a/src/lib/libc/string/__strsignal.c +++ b/src/lib/libc/string/stpcpy.c | |||
| @@ -1,3 +1,5 @@ | |||
| 1 | /* $OpenBSD: stpcpy.c,v 1.1 2012/01/17 02:48:01 guenther Exp $ */ | ||
| 2 | |||
| 1 | /* | 3 | /* |
| 2 | * Copyright (c) 1988 Regents of the University of California. | 4 | * Copyright (c) 1988 Regents of the University of California. |
| 3 | * All rights reserved. | 5 | * All rights reserved. |
| @@ -10,11 +12,7 @@ | |||
| 10 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the |
| 12 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. All advertising materials mentioning features or use of this software | 15 | * 3. Neither the name of the University nor the names of its contributors |
| 14 | * must display the following acknowledgement: | ||
| 15 | * This product includes software developed by the University of | ||
| 16 | * California, Berkeley and its contributors. | ||
| 17 | * 4. Neither the name of the University nor the names of its contributors | ||
| 18 | * may be used to endorse or promote products derived from this software | 16 | * may be used to endorse or promote products derived from this software |
| 19 | * without specific prior written permission. | 17 | * without specific prior written permission. |
| 20 | * | 18 | * |
| @@ -31,56 +29,16 @@ | |||
| 31 | * SUCH DAMAGE. | 29 | * SUCH DAMAGE. |
| 32 | */ | 30 | */ |
| 33 | 31 | ||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | 32 | #include <string.h> |
| 35 | /*static char *sccsid = "from: @(#)strerror.c 5.6 (Berkeley) 5/4/91";*/ | ||
| 36 | static char *rcsid = "$Id: __strsignal.c,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $"; | ||
| 37 | #endif /* LIBC_SCCS and not lint */ | ||
| 38 | 33 | ||
| 39 | #ifdef NLS | 34 | #if defined(APIWARN) |
| 40 | #define catclose _catclose | 35 | __warn_references(stpcpy, |
| 41 | #define catgets _catgets | 36 | "warning: stpcpy() is dangerous GNU crap; don't use it"); |
| 42 | #define catopen _catopen | ||
| 43 | #include <nl_types.h> | ||
| 44 | #endif | 37 | #endif |
| 45 | 38 | ||
| 46 | #define sys_siglist _sys_siglist | ||
| 47 | |||
| 48 | #include <stdio.h> | ||
| 49 | #include <signal.h> | ||
| 50 | #include <string.h> | ||
| 51 | |||
| 52 | char * | 39 | char * |
| 53 | __strsignal(num, buf) | 40 | stpcpy(char *to, const char *from) |
| 54 | int num; | ||
| 55 | char *buf; | ||
| 56 | { | 41 | { |
| 57 | #define UPREFIX "Unknown signal: %u" | 42 | for (; (*to = *from) != '\0'; ++from, ++to); |
| 58 | register unsigned int signum; | 43 | return(to); |
| 59 | |||
| 60 | #ifdef NLS | ||
| 61 | nl_catd catd ; | ||
| 62 | catd = catopen("libc", 0); | ||
| 63 | #endif | ||
| 64 | |||
| 65 | signum = num; /* convert to unsigned */ | ||
| 66 | if (signum < NSIG) { | ||
| 67 | #ifdef NLS | ||
| 68 | strcpy(buf, catgets(catd, 2, signum, | ||
| 69 | (char *)sys_siglist[signum])); | ||
| 70 | #else | ||
| 71 | return((char *)sys_siglist[signum]); | ||
| 72 | #endif | ||
| 73 | } else { | ||
| 74 | #ifdef NLS | ||
| 75 | sprintf(buf, catgets(catd, 1, 0xffff, UPREFIX), signum); | ||
| 76 | #else | ||
| 77 | sprintf(buf, UPREFIX, signum); | ||
| 78 | #endif | ||
| 79 | } | ||
| 80 | |||
| 81 | #ifdef NLS | ||
| 82 | catclose(catd); | ||
| 83 | #endif | ||
| 84 | |||
| 85 | return buf; | ||
| 86 | } | 44 | } |
diff --git a/src/lib/libc/string/stpncpy.c b/src/lib/libc/string/stpncpy.c new file mode 100644 index 0000000000..c7c2a57c4c --- /dev/null +++ b/src/lib/libc/string/stpncpy.c | |||
| @@ -0,0 +1,56 @@ | |||
| 1 | /* $OpenBSD: stpncpy.c,v 1.2 2012/07/11 10:44:59 naddy Exp $ */ | ||
| 2 | |||
| 3 | /*- | ||
| 4 | * Copyright (c) 1990 The Regents of the University of California. | ||
| 5 | * All rights reserved. | ||
| 6 | * | ||
| 7 | * This code is derived from software contributed to Berkeley by | ||
| 8 | * Chris Torek. | ||
| 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. 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 | |||
| 35 | #include <string.h> | ||
| 36 | |||
| 37 | char * | ||
| 38 | stpncpy(char *dst, const char *src, size_t n) | ||
| 39 | { | ||
| 40 | if (n != 0) { | ||
| 41 | char *d = dst; | ||
| 42 | const char *s = src; | ||
| 43 | |||
| 44 | dst = &dst[n]; | ||
| 45 | do { | ||
| 46 | if ((*d++ = *s++) == 0) { | ||
| 47 | dst = d - 1; | ||
| 48 | /* NUL pad the remaining n-1 bytes */ | ||
| 49 | while (--n != 0) | ||
| 50 | *d++ = 0; | ||
| 51 | break; | ||
| 52 | } | ||
| 53 | } while (--n != 0); | ||
| 54 | } | ||
| 55 | return (dst); | ||
| 56 | } | ||
diff --git a/src/lib/libc/string/strcasecmp.3 b/src/lib/libc/string/strcasecmp.3 index 46e9010e4f..8bd7387dc5 100644 --- a/src/lib/libc/string/strcasecmp.3 +++ b/src/lib/libc/string/strcasecmp.3 | |||
| @@ -1,5 +1,7 @@ | |||
| 1 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. | 1 | .\" $OpenBSD: strcasecmp.3,v 1.12 2013/06/05 03:39:23 tedu Exp $ |
| 2 | .\" All rights reserved. | 2 | .\" |
| 3 | .\" Copyright (c) 1990, 1991, 1993 | ||
| 4 | .\" The Regents of the University of California. All rights reserved. | ||
| 3 | .\" | 5 | .\" |
| 4 | .\" This code is derived from software contributed to Berkeley by | 6 | .\" This code is derived from software contributed to Berkeley by |
| 5 | .\" Chris Torek. | 7 | .\" Chris Torek. |
| @@ -11,11 +13,7 @@ | |||
| 11 | .\" 2. Redistributions in binary form must reproduce the above copyright | 13 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 12 | .\" notice, this list of conditions and the following disclaimer in the | 14 | .\" notice, this list of conditions and the following disclaimer in the |
| 13 | .\" documentation and/or other materials provided with the distribution. | 15 | .\" documentation and/or other materials provided with the distribution. |
| 14 | .\" 3. All advertising materials mentioning features or use of this software | 16 | .\" 3. Neither the name of the University nor the names of its contributors |
| 15 | .\" must display the following acknowledgement: | ||
| 16 | .\" This product includes software developed by the University of | ||
| 17 | .\" California, Berkeley and its contributors. | ||
| 18 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 19 | .\" may be used to endorse or promote products derived from this software | 17 | .\" may be used to endorse or promote products derived from this software |
| 20 | .\" without specific prior written permission. | 18 | .\" without specific prior written permission. |
| 21 | .\" | 19 | .\" |
| @@ -31,17 +29,17 @@ | |||
| 31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 29 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 32 | .\" SUCH DAMAGE. | 30 | .\" SUCH DAMAGE. |
| 33 | .\" | 31 | .\" |
| 34 | .\" from: @(#)strcasecmp.3 5.4 (Berkeley) 4/19/91 | 32 | .\" @(#)strcasecmp.3 8.1 (Berkeley) 6/9/93 |
| 35 | .\" $Id: strcasecmp.3,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $ | ||
| 36 | .\" | 33 | .\" |
| 37 | .Dd April 19, 1991 | 34 | .Dd $Mdocdate: June 5 2013 $ |
| 38 | .Dt STRCASECMP 3 | 35 | .Dt STRCASECMP 3 |
| 39 | .Os | 36 | .Os |
| 40 | .Sh NAME | 37 | .Sh NAME |
| 41 | .Nm strcasecmp | 38 | .Nm strcasecmp , |
| 39 | .Nm strncasecmp | ||
| 42 | .Nd compare strings, ignoring case | 40 | .Nd compare strings, ignoring case |
| 43 | .Sh SYNOPSIS | 41 | .Sh SYNOPSIS |
| 44 | .Fd #include <string.h> | 42 | .In string.h |
| 45 | .Ft int | 43 | .Ft int |
| 46 | .Fn strcasecmp "const char *s1" "const char *s2" | 44 | .Fn strcasecmp "const char *s1" "const char *s2" |
| 47 | .Ft int | 45 | .Ft int |
| @@ -51,13 +49,12 @@ The | |||
| 51 | .Fn strcasecmp | 49 | .Fn strcasecmp |
| 52 | and | 50 | and |
| 53 | .Fn strncasecmp | 51 | .Fn strncasecmp |
| 54 | functions | 52 | functions compare the NUL-terminated strings |
| 55 | compare the null-terminated strings | ||
| 56 | .Fa s1 | 53 | .Fa s1 |
| 57 | and | 54 | and |
| 58 | .Fa s2 | 55 | .Fa s2 |
| 59 | and return an integer greater than, equal to, or less than 0, | 56 | and return an integer greater than, equal to, or less than 0, |
| 60 | according as | 57 | according to whether |
| 61 | .Fa s1 | 58 | .Fa s1 |
| 62 | is lexicographically greater than, equal to, or less than | 59 | is lexicographically greater than, equal to, or less than |
| 63 | .Fa s2 | 60 | .Fa s2 |
| @@ -68,7 +65,6 @@ The comparison is done using unsigned characters, so that | |||
| 68 | is greater than | 65 | is greater than |
| 69 | .Ql \e0 . | 66 | .Ql \e0 . |
| 70 | .Pp | 67 | .Pp |
| 71 | The | ||
| 72 | .Fn strncasecmp | 68 | .Fn strncasecmp |
| 73 | compares at most | 69 | compares at most |
| 74 | .Fa len | 70 | .Fa len |
| @@ -78,11 +74,19 @@ characters. | |||
| 78 | .Xr memcmp 3 , | 74 | .Xr memcmp 3 , |
| 79 | .Xr strcmp 3 , | 75 | .Xr strcmp 3 , |
| 80 | .Xr strcoll 3 , | 76 | .Xr strcoll 3 , |
| 81 | .Xr strxfrm 3 | 77 | .Xr strxfrm 3 , |
| 78 | .Xr wcscasecmp 3 | ||
| 79 | .Sh STANDARDS | ||
| 80 | The | ||
| 81 | .Fn strcasecmp | ||
| 82 | and | ||
| 83 | .Fn strncasecmp | ||
| 84 | functions conform to | ||
| 85 | .St -p1003.1-2008 . | ||
| 82 | .Sh HISTORY | 86 | .Sh HISTORY |
| 83 | The | 87 | The |
| 84 | .Fn strcasecmp | 88 | .Fn strcasecmp |
| 85 | and | 89 | and |
| 86 | .Fn strncasecmp | 90 | .Fn strncasecmp |
| 87 | functions are | 91 | functions first appeared in |
| 88 | .Ud . | 92 | .Bx 4.3 Tahoe . |
diff --git a/src/lib/libc/string/strcasecmp.c b/src/lib/libc/string/strcasecmp.c index 79bd0081e3..2be09136c0 100644 --- a/src/lib/libc/string/strcasecmp.c +++ b/src/lib/libc/string/strcasecmp.c | |||
| @@ -1,6 +1,8 @@ | |||
| 1 | /* $OpenBSD: strcasecmp.c,v 1.6 2005/08/08 08:05:37 espie Exp $ */ | ||
| 2 | |||
| 1 | /* | 3 | /* |
| 2 | * Copyright (c) 1987 Regents of the University of California. | 4 | * Copyright (c) 1987, 1993 |
| 3 | * All rights reserved. | 5 | * The Regents of the University of California. All rights reserved. |
| 4 | * | 6 | * |
| 5 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without |
| 6 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions |
| @@ -10,11 +12,7 @@ | |||
| 10 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the |
| 12 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. All advertising materials mentioning features or use of this software | 15 | * 3. Neither the name of the University nor the names of its contributors |
| 14 | * must display the following acknowledgement: | ||
| 15 | * This product includes software developed by the University of | ||
| 16 | * California, Berkeley and its contributors. | ||
| 17 | * 4. Neither the name of the University nor the names of its contributors | ||
| 18 | * may be used to endorse or promote products derived from this software | 16 | * may be used to endorse or promote products derived from this software |
| 19 | * without specific prior written permission. | 17 | * without specific prior written permission. |
| 20 | * | 18 | * |
| @@ -31,11 +29,6 @@ | |||
| 31 | * SUCH DAMAGE. | 29 | * SUCH DAMAGE. |
| 32 | */ | 30 | */ |
| 33 | 31 | ||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 35 | /*static const char sccsid[] = "from: @(#)strcasecmp.c 5.10 (Berkeley) 1/26/91";*/ | ||
| 36 | static char *rcsid = "$Id: strcasecmp.c,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $"; | ||
| 37 | #endif /* LIBC_SCCS and not lint */ | ||
| 38 | |||
| 39 | #include <string.h> | 32 | #include <string.h> |
| 40 | 33 | ||
| 41 | typedef unsigned char u_char; | 34 | typedef unsigned char u_char; |
| @@ -81,12 +74,11 @@ static const u_char charmap[] = { | |||
| 81 | }; | 74 | }; |
| 82 | 75 | ||
| 83 | int | 76 | int |
| 84 | strcasecmp(s1, s2) | 77 | strcasecmp(const char *s1, const char *s2) |
| 85 | const char *s1, *s2; | ||
| 86 | { | 78 | { |
| 87 | register const u_char *cm = charmap, | 79 | const u_char *cm = charmap; |
| 88 | *us1 = (const u_char *)s1, | 80 | const u_char *us1 = (const u_char *)s1; |
| 89 | *us2 = (const u_char *)s2; | 81 | const u_char *us2 = (const u_char *)s2; |
| 90 | 82 | ||
| 91 | while (cm[*us1] == cm[*us2++]) | 83 | while (cm[*us1] == cm[*us2++]) |
| 92 | if (*us1++ == '\0') | 84 | if (*us1++ == '\0') |
| @@ -95,14 +87,12 @@ strcasecmp(s1, s2) | |||
| 95 | } | 87 | } |
| 96 | 88 | ||
| 97 | int | 89 | int |
| 98 | strncasecmp(s1, s2, n) | 90 | strncasecmp(const char *s1, const char *s2, size_t n) |
| 99 | const char *s1, *s2; | ||
| 100 | register size_t n; | ||
| 101 | { | 91 | { |
| 102 | if (n != 0) { | 92 | if (n != 0) { |
| 103 | register const u_char *cm = charmap, | 93 | const u_char *cm = charmap; |
| 104 | *us1 = (const u_char *)s1, | 94 | const u_char *us1 = (const u_char *)s1; |
| 105 | *us2 = (const u_char *)s2; | 95 | const u_char *us2 = (const u_char *)s2; |
| 106 | 96 | ||
| 107 | do { | 97 | do { |
| 108 | if (cm[*us1] != cm[*us2++]) | 98 | if (cm[*us1] != cm[*us2++]) |
diff --git a/src/lib/libc/net/sethostent.c b/src/lib/libc/string/strcasestr.c index 00f6499695..aa74c0176d 100644 --- a/src/lib/libc/net/sethostent.c +++ b/src/lib/libc/string/strcasestr.c | |||
| @@ -1,9 +1,13 @@ | |||
| 1 | /* $NetBSD: sethostent.c,v 1.4 1995/02/25 06:21:03 cgd Exp $ */ | 1 | /* $OpenBSD: strcasestr.c,v 1.3 2006/03/31 05:34:55 deraadt Exp $ */ |
| 2 | /* $NetBSD: strcasestr.c,v 1.2 2005/02/09 21:35:47 kleink Exp $ */ | ||
| 2 | 3 | ||
| 3 | /* | 4 | /*- |
| 4 | * Copyright (c) 1985, 1993 | 5 | * Copyright (c) 1990, 1993 |
| 5 | * The Regents of the University of California. All rights reserved. | 6 | * The Regents of the University of California. All rights reserved. |
| 6 | * | 7 | * |
| 8 | * This code is derived from software contributed to Berkeley by | ||
| 9 | * Chris Torek. | ||
| 10 | * | ||
| 7 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
| 8 | * modification, are permitted provided that the following conditions | 12 | * modification, are permitted provided that the following conditions |
| 9 | * are met: | 13 | * are met: |
| @@ -12,11 +16,7 @@ | |||
| 12 | * 2. Redistributions in binary form must reproduce the above copyright | 16 | * 2. Redistributions in binary form must reproduce the above copyright |
| 13 | * notice, this list of conditions and the following disclaimer in the | 17 | * notice, this list of conditions and the following disclaimer in the |
| 14 | * documentation and/or other materials provided with the distribution. | 18 | * documentation and/or other materials provided with the distribution. |
| 15 | * 3. All advertising materials mentioning features or use of this software | 19 | * 3. Neither the name of the University nor the names of its contributors |
| 16 | * must display the following acknowledgement: | ||
| 17 | * This product includes software developed by the University of | ||
| 18 | * California, Berkeley and its contributors. | ||
| 19 | * 4. Neither the name of the University nor the names of its contributors | ||
| 20 | * may be used to endorse or promote products derived from this software | 20 | * may be used to endorse or promote products derived from this software |
| 21 | * without specific prior written permission. | 21 | * without specific prior written permission. |
| 22 | * | 22 | * |
| @@ -33,30 +33,28 @@ | |||
| 33 | * SUCH DAMAGE. | 33 | * SUCH DAMAGE. |
| 34 | */ | 34 | */ |
| 35 | 35 | ||
| 36 | #if defined(LIBC_SCCS) && !defined(lint) | 36 | #include <ctype.h> |
| 37 | #if 0 | 37 | #include <string.h> |
| 38 | static char sccsid[] = "@(#)sethostent.c 8.1 (Berkeley) 6/4/93"; | ||
| 39 | #else | ||
| 40 | static char rcsid[] = "$NetBSD: sethostent.c,v 1.4 1995/02/25 06:21:03 cgd Exp $"; | ||
| 41 | #endif | ||
| 42 | #endif /* LIBC_SCCS and not lint */ | ||
| 43 | 38 | ||
| 44 | #include <sys/param.h> | 39 | /* |
| 45 | #include <netinet/in.h> | 40 | * Find the first occurrence of find in s, ignore case. |
| 46 | #include <arpa/nameser.h> | 41 | */ |
| 47 | #include <netdb.h> | 42 | char * |
| 48 | #include <resolv.h> | 43 | strcasestr(const char *s, const char *find) |
| 49 | |||
| 50 | void | ||
| 51 | sethostent(stayopen) | ||
| 52 | { | 44 | { |
| 53 | if (stayopen) | 45 | char c, sc; |
| 54 | _res.options |= RES_STAYOPEN | RES_USEVC; | 46 | size_t len; |
| 55 | } | ||
| 56 | 47 | ||
| 57 | void | 48 | if ((c = *find++) != 0) { |
| 58 | endhostent() | 49 | c = (char)tolower((unsigned char)c); |
| 59 | { | 50 | len = strlen(find); |
| 60 | _res.options &= ~(RES_STAYOPEN | RES_USEVC); | 51 | do { |
| 61 | _res_close(); | 52 | do { |
| 53 | if ((sc = *s++) == 0) | ||
| 54 | return (NULL); | ||
| 55 | } while ((char)tolower((unsigned char)sc) != c); | ||
| 56 | } while (strncasecmp(s, find, len) != 0); | ||
| 57 | s--; | ||
| 58 | } | ||
| 59 | return ((char *)s); | ||
| 62 | } | 60 | } |
diff --git a/src/lib/libc/string/strcat.3 b/src/lib/libc/string/strcat.3 index 5357d65754..fba992edd9 100644 --- a/src/lib/libc/string/strcat.3 +++ b/src/lib/libc/string/strcat.3 | |||
| @@ -1,3 +1,5 @@ | |||
| 1 | .\" $OpenBSD: strcat.3,v 1.16 2013/12/19 20:52:37 millert Exp $ | ||
| 2 | .\" | ||
| 1 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. | 3 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. |
| 2 | .\" All rights reserved. | 4 | .\" All rights reserved. |
| 3 | .\" | 5 | .\" |
| @@ -13,11 +15,7 @@ | |||
| 13 | .\" 2. Redistributions in binary form must reproduce the above copyright | 15 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 14 | .\" notice, this list of conditions and the following disclaimer in the | 16 | .\" notice, this list of conditions and the following disclaimer in the |
| 15 | .\" documentation and/or other materials provided with the distribution. | 17 | .\" documentation and/or other materials provided with the distribution. |
| 16 | .\" 3. All advertising materials mentioning features or use of this software | 18 | .\" 3. Neither the name of the University nor the names of its contributors |
| 17 | .\" must display the following acknowledgement: | ||
| 18 | .\" This product includes software developed by the University of | ||
| 19 | .\" California, Berkeley and its contributors. | ||
| 20 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 21 | .\" may be used to endorse or promote products derived from this software | 19 | .\" may be used to endorse or promote products derived from this software |
| 22 | .\" without specific prior written permission. | 20 | .\" without specific prior written permission. |
| 23 | .\" | 21 | .\" |
| @@ -33,62 +31,51 @@ | |||
| 33 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 34 | .\" SUCH DAMAGE. | 32 | .\" SUCH DAMAGE. |
| 35 | .\" | 33 | .\" |
| 36 | .\" from: @(#)strcat.3 5.6 (Berkeley) 6/29/91 | 34 | .Dd $Mdocdate: December 19 2013 $ |
| 37 | .\" $Id: strcat.3,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $ | ||
| 38 | .\" | ||
| 39 | .Dd June 29, 1991 | ||
| 40 | .Dt STRCAT 3 | 35 | .Dt STRCAT 3 |
| 41 | .Os | 36 | .Os |
| 42 | .Sh NAME | 37 | .Sh NAME |
| 43 | .Nm strcat | 38 | .Nm strcat |
| 44 | .Nd concatenate strings | 39 | .Nd concatenate two strings |
| 45 | .Sh SYNOPSIS | 40 | .Sh SYNOPSIS |
| 46 | .Fd #include <string.h> | 41 | .In string.h |
| 47 | .Ft char * | 42 | .Ft char * |
| 48 | .Fn strcat "char *s" "const char *append" | 43 | .Fn strcat "char *s" "const char *append" |
| 49 | .Ft char * | ||
| 50 | .Fn strncat "char *s" "const char *append" "size_t count" | ||
| 51 | .Sh DESCRIPTION | 44 | .Sh DESCRIPTION |
| 52 | The | 45 | The |
| 53 | .Fn strcat | 46 | .Fn strcat |
| 54 | and | 47 | function appends a copy of the NUL-terminated string |
| 55 | .Fn strncat | ||
| 56 | functions | ||
| 57 | append a copy of the null-terminated string | ||
| 58 | .Fa append | 48 | .Fa append |
| 59 | to the end of the null-terminated string | 49 | to the end of the NUL-terminated string |
| 60 | .Fa s , | 50 | .Fa s , |
| 61 | then add a terminating | 51 | then adds a terminating |
| 62 | .Ql \e0 . | 52 | .Ql \e0 . |
| 63 | The string | 53 | The string |
| 64 | .Fa s | 54 | .Fa s |
| 65 | must have sufficient space to hold the result. | 55 | must have sufficient space to hold the result. |
| 66 | .Pp | ||
| 67 | The | ||
| 68 | .Fn strncat | ||
| 69 | function | ||
| 70 | appends not more than | ||
| 71 | .Fa count | ||
| 72 | characters. | ||
| 73 | .Sh RETURN VALUES | 56 | .Sh RETURN VALUES |
| 74 | The | 57 | The |
| 75 | .Fn strcat | 58 | .Fn strcat |
| 76 | and | 59 | function return the pointer |
| 77 | .Fn strncat | ||
| 78 | functions | ||
| 79 | return the pointer | ||
| 80 | .Fa s . | 60 | .Fa s . |
| 81 | .Sh SEE ALSO | 61 | .Sh SEE ALSO |
| 82 | .Xr bcopy 3 , | 62 | .Xr bcopy 3 , |
| 83 | .Xr memccpy 3 , | 63 | .Xr memccpy 3 , |
| 84 | .Xr memcpy 3 , | 64 | .Xr memcpy 3 , |
| 85 | .Xr memmove 3 , | 65 | .Xr memmove 3 , |
| 86 | .Xr strcpy 3 | 66 | .Xr strcpy 3 , |
| 67 | .Xr strlcpy 3 , | ||
| 68 | .Xr strncat 3 , | ||
| 69 | .Xr wcscat 3 , | ||
| 70 | .Xr wcslcpy 3 | ||
| 87 | .Sh STANDARDS | 71 | .Sh STANDARDS |
| 88 | The | 72 | The |
| 89 | .Fn strcat | 73 | .Fn strcat |
| 90 | and | 74 | function conforms to |
| 91 | .Fn strncat | ||
| 92 | functions | ||
| 93 | conform to | ||
| 94 | .St -ansiC . | 75 | .St -ansiC . |
| 76 | .Sh HISTORY | ||
| 77 | The | ||
| 78 | .Fn strcat | ||
| 79 | function first appeared in the Programmer's Workbench (PWB/UNIX) | ||
| 80 | and was ported to | ||
| 81 | .At v7 . | ||
diff --git a/src/lib/libc/string/strcat.c b/src/lib/libc/string/strcat.c index e741b84f03..7cea5229fb 100644 --- a/src/lib/libc/string/strcat.c +++ b/src/lib/libc/string/strcat.c | |||
| @@ -1,3 +1,5 @@ | |||
| 1 | /* $OpenBSD: strcat.c,v 1.8 2005/08/08 08:05:37 espie Exp $ */ | ||
| 2 | |||
| 1 | /* | 3 | /* |
| 2 | * Copyright (c) 1988 Regents of the University of California. | 4 | * Copyright (c) 1988 Regents of the University of California. |
| 3 | * All rights reserved. | 5 | * All rights reserved. |
| @@ -10,11 +12,7 @@ | |||
| 10 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the |
| 12 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. All advertising materials mentioning features or use of this software | 15 | * 3. Neither the name of the University nor the names of its contributors |
| 14 | * must display the following acknowledgement: | ||
| 15 | * This product includes software developed by the University of | ||
| 16 | * California, Berkeley and its contributors. | ||
| 17 | * 4. Neither the name of the University nor the names of its contributors | ||
| 18 | * may be used to endorse or promote products derived from this software | 16 | * may be used to endorse or promote products derived from this software |
| 19 | * without specific prior written permission. | 17 | * without specific prior written permission. |
| 20 | * | 18 | * |
| @@ -31,21 +29,23 @@ | |||
| 31 | * SUCH DAMAGE. | 29 | * SUCH DAMAGE. |
| 32 | */ | 30 | */ |
| 33 | 31 | ||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | 32 | #if !defined(_KERNEL) && !defined(_STANDALONE) |
| 35 | /*static char *sccsid = "from: @(#)strcat.c 5.6 (Berkeley) 2/24/91";*/ | ||
| 36 | static char *rcsid = "$Id: strcat.c,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $"; | ||
| 37 | #endif /* LIBC_SCCS and not lint */ | ||
| 38 | |||
| 39 | #include <string.h> | 33 | #include <string.h> |
| 34 | #else | ||
| 35 | #include <lib/libkern/libkern.h> | ||
| 36 | #endif | ||
| 37 | |||
| 38 | #if defined(APIWARN) | ||
| 39 | __warn_references(strcat, | ||
| 40 | "warning: strcat() is almost always misused, please use strlcat()"); | ||
| 41 | #endif | ||
| 40 | 42 | ||
| 41 | char * | 43 | char * |
| 42 | strcat(s, append) | 44 | strcat(char *s, const char *append) |
| 43 | register char *s; | ||
| 44 | register const char *append; | ||
| 45 | { | 45 | { |
| 46 | char *save = s; | 46 | char *save = s; |
| 47 | 47 | ||
| 48 | for (; *s; ++s); | 48 | for (; *s; ++s); |
| 49 | while (*s++ = *append++); | 49 | while ((*s++ = *append++) != '\0'); |
| 50 | return(save); | 50 | return(save); |
| 51 | } | 51 | } |
diff --git a/src/lib/libc/string/strchr.3 b/src/lib/libc/string/strchr.3 index 18b50301f3..eb9ac8e833 100644 --- a/src/lib/libc/string/strchr.3 +++ b/src/lib/libc/string/strchr.3 | |||
| @@ -1,3 +1,5 @@ | |||
| 1 | .\" $OpenBSD: strchr.3,v 1.11 2013/06/05 03:39:23 tedu Exp $ | ||
| 2 | .\" | ||
| 1 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. | 3 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. |
| 2 | .\" All rights reserved. | 4 | .\" All rights reserved. |
| 3 | .\" | 5 | .\" |
| @@ -13,11 +15,7 @@ | |||
| 13 | .\" 2. Redistributions in binary form must reproduce the above copyright | 15 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 14 | .\" notice, this list of conditions and the following disclaimer in the | 16 | .\" notice, this list of conditions and the following disclaimer in the |
| 15 | .\" documentation and/or other materials provided with the distribution. | 17 | .\" documentation and/or other materials provided with the distribution. |
| 16 | .\" 3. All advertising materials mentioning features or use of this software | 18 | .\" 3. Neither the name of the University nor the names of its contributors |
| 17 | .\" must display the following acknowledgement: | ||
| 18 | .\" This product includes software developed by the University of | ||
| 19 | .\" California, Berkeley and its contributors. | ||
| 20 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 21 | .\" may be used to endorse or promote products derived from this software | 19 | .\" may be used to endorse or promote products derived from this software |
| 22 | .\" without specific prior written permission. | 20 | .\" without specific prior written permission. |
| 23 | .\" | 21 | .\" |
| @@ -33,29 +31,27 @@ | |||
| 33 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 34 | .\" SUCH DAMAGE. | 32 | .\" SUCH DAMAGE. |
| 35 | .\" | 33 | .\" |
| 36 | .\" from: @(#)strchr.3 5.4 (Berkeley) 6/29/91 | 34 | .Dd $Mdocdate: June 5 2013 $ |
| 37 | .\" $Id: strchr.3,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $ | ||
| 38 | .\" | ||
| 39 | .Dd June 29, 1991 | ||
| 40 | .Dt STRCHR 3 | 35 | .Dt STRCHR 3 |
| 41 | .Os | 36 | .Os |
| 42 | .Sh NAME | 37 | .Sh NAME |
| 43 | .Nm strchr | 38 | .Nm strchr , |
| 44 | .Nd locate character in string | 39 | .Nm index |
| 40 | .Nd locate first occurrence of a character in a string | ||
| 45 | .Sh SYNOPSIS | 41 | .Sh SYNOPSIS |
| 46 | .Fd #include <string.h> | 42 | .In string.h |
| 47 | .Ft char * | 43 | .Ft char * |
| 48 | .Fn strchr "const char *s" "int c" | 44 | .Fn strchr "const char *s" "int c" |
| 45 | .Ft char * | ||
| 46 | .Fn index "const char *s" "int c" | ||
| 49 | .Sh DESCRIPTION | 47 | .Sh DESCRIPTION |
| 50 | The | 48 | The |
| 51 | .Fn strchr | 49 | .Fn strchr |
| 52 | function locates the first occurrence of | 50 | function locates the first occurrence of the character |
| 53 | .Ar c | 51 | .Fa c |
| 54 | in the string pointed to by | 52 | in the string |
| 55 | .Ar s . | 53 | .Fa s . |
| 56 | The terminating | 54 | The terminating NUL character is considered part of the string. |
| 57 | .Dv NULL | ||
| 58 | character is considered part of the string. | ||
| 59 | If | 55 | If |
| 60 | .Fa c | 56 | .Fa c |
| 61 | is | 57 | is |
| @@ -63,26 +59,56 @@ is | |||
| 63 | .Fn strchr | 59 | .Fn strchr |
| 64 | locates the terminating | 60 | locates the terminating |
| 65 | .Ql \e0 . | 61 | .Ql \e0 . |
| 62 | .Pp | ||
| 63 | The | ||
| 64 | .Fn index | ||
| 65 | function is an old synonym for | ||
| 66 | .Fn strchr . | ||
| 66 | .Sh RETURN VALUES | 67 | .Sh RETURN VALUES |
| 67 | The function | 68 | The |
| 68 | .Fn strchr | 69 | .Fn strchr |
| 69 | returns a pointer to the located character, or | 70 | function returns a pointer to the located character or |
| 70 | .Dv NULL | 71 | .Dv NULL |
| 71 | if the character does not appear in the string. | 72 | if the character does not appear in the string. |
| 73 | .Sh EXAMPLES | ||
| 74 | After the following call to | ||
| 75 | .Fn strchr , | ||
| 76 | .Va p | ||
| 77 | will point to the string | ||
| 78 | .Qq oobar : | ||
| 79 | .Bd -literal -offset indent | ||
| 80 | char *p; | ||
| 81 | char *s = "foobar"; | ||
| 82 | |||
| 83 | p = strchr(s, 'o'); | ||
| 84 | .Ed | ||
| 72 | .Sh SEE ALSO | 85 | .Sh SEE ALSO |
| 73 | .Xr index 3 , | ||
| 74 | .Xr memchr 3 , | 86 | .Xr memchr 3 , |
| 75 | .Xr rindex 3 , | ||
| 76 | .Xr strcspn 3 , | 87 | .Xr strcspn 3 , |
| 77 | .Xr strpbrk 3 , | 88 | .Xr strpbrk 3 , |
| 78 | .Xr strrchr 3 , | 89 | .Xr strrchr 3 , |
| 79 | .Xr strsep 3 , | 90 | .Xr strsep 3 , |
| 80 | .Xr strspn 3 , | 91 | .Xr strspn 3 , |
| 81 | .Xr strstr 3 , | 92 | .Xr strstr 3 , |
| 82 | .Xr strtok 3 | 93 | .Xr strtok 3 , |
| 94 | .Xr wcschr 3 | ||
| 83 | .Sh STANDARDS | 95 | .Sh STANDARDS |
| 84 | The | 96 | The |
| 85 | .Fn strchr | 97 | .Fn strchr |
| 86 | function | 98 | function conforms to |
| 87 | conforms to | ||
| 88 | .St -ansiC . | 99 | .St -ansiC . |
| 100 | .Pp | ||
| 101 | The | ||
| 102 | .Fn index | ||
| 103 | function is deprecated and shouldn't be used in new code. | ||
| 104 | .Sh HISTORY | ||
| 105 | The | ||
| 106 | .Fn index | ||
| 107 | function first appeared in | ||
| 108 | .At v7 . | ||
| 109 | The | ||
| 110 | .Fn strchr | ||
| 111 | function first appeared in | ||
| 112 | .At III | ||
| 113 | and was reimplemented for | ||
| 114 | .Bx 4.3 Tahoe . | ||
diff --git a/src/lib/libc/string/strcmp.3 b/src/lib/libc/string/strcmp.3 index fecaa85410..63dc7fed2d 100644 --- a/src/lib/libc/string/strcmp.3 +++ b/src/lib/libc/string/strcmp.3 | |||
| @@ -1,3 +1,5 @@ | |||
| 1 | .\" $OpenBSD: strcmp.3,v 1.14 2013/07/17 05:42:11 schwarze Exp $ | ||
| 2 | .\" | ||
| 1 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. | 3 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. |
| 2 | .\" All rights reserved. | 4 | .\" All rights reserved. |
| 3 | .\" | 5 | .\" |
| @@ -13,11 +15,7 @@ | |||
| 13 | .\" 2. Redistributions in binary form must reproduce the above copyright | 15 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 14 | .\" notice, this list of conditions and the following disclaimer in the | 16 | .\" notice, this list of conditions and the following disclaimer in the |
| 15 | .\" documentation and/or other materials provided with the distribution. | 17 | .\" documentation and/or other materials provided with the distribution. |
| 16 | .\" 3. All advertising materials mentioning features or use of this software | 18 | .\" 3. Neither the name of the University nor the names of its contributors |
| 17 | .\" must display the following acknowledgement: | ||
| 18 | .\" This product includes software developed by the University of | ||
| 19 | .\" California, Berkeley and its contributors. | ||
| 20 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 21 | .\" may be used to endorse or promote products derived from this software | 19 | .\" may be used to endorse or promote products derived from this software |
| 22 | .\" without specific prior written permission. | 20 | .\" without specific prior written permission. |
| 23 | .\" | 21 | .\" |
| @@ -33,17 +31,15 @@ | |||
| 33 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 34 | .\" SUCH DAMAGE. | 32 | .\" SUCH DAMAGE. |
| 35 | .\" | 33 | .\" |
| 36 | .\" from: @(#)strcmp.3 5.6 (Berkeley) 6/29/91 | 34 | .Dd $Mdocdate: July 17 2013 $ |
| 37 | .\" $Id: strcmp.3,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $ | ||
| 38 | .\" | ||
| 39 | .Dd June 29, 1991 | ||
| 40 | .Dt STRCMP 3 | 35 | .Dt STRCMP 3 |
| 41 | .Os | 36 | .Os |
| 42 | .Sh NAME | 37 | .Sh NAME |
| 43 | .Nm strcmp | 38 | .Nm strcmp , |
| 39 | .Nm strncmp | ||
| 44 | .Nd compare strings | 40 | .Nd compare strings |
| 45 | .Sh SYNOPSIS | 41 | .Sh SYNOPSIS |
| 46 | .Fd #include <string.h> | 42 | .In string.h |
| 47 | .Ft int | 43 | .Ft int |
| 48 | .Fn strcmp "const char *s1" "const char *s2" | 44 | .Fn strcmp "const char *s1" "const char *s2" |
| 49 | .Ft int | 45 | .Ft int |
| @@ -53,18 +49,22 @@ The | |||
| 53 | .Fn strcmp | 49 | .Fn strcmp |
| 54 | and | 50 | and |
| 55 | .Fn strncmp | 51 | .Fn strncmp |
| 56 | functions | 52 | functions lexicographically compare the NUL-terminated strings |
| 57 | lexicographically compare the null-terminated strings | ||
| 58 | .Fa s1 | 53 | .Fa s1 |
| 59 | and | 54 | and |
| 60 | .Fa s2 . | 55 | .Fa s2 . |
| 56 | The | ||
| 57 | .Fn strncmp | ||
| 58 | function compares at most | ||
| 59 | .Fa len | ||
| 60 | characters. | ||
| 61 | .Sh RETURN VALUES | 61 | .Sh RETURN VALUES |
| 62 | The | 62 | The |
| 63 | .Fn strcmp | 63 | .Fn strcmp |
| 64 | and | 64 | and |
| 65 | .Fn strncmp | 65 | .Fn strncmp |
| 66 | return an integer greater than, equal to, or less than 0, according | 66 | functions return an integer greater than, equal to, or less than 0, according |
| 67 | as the string | 67 | to whether the string |
| 68 | .Fa s1 | 68 | .Fa s1 |
| 69 | is greater than, equal to, or less than the string | 69 | is greater than, equal to, or less than the string |
| 70 | .Fa s2 . | 70 | .Fa s2 . |
| @@ -72,23 +72,26 @@ The comparison is done using unsigned characters, so that | |||
| 72 | .Ql \e200 | 72 | .Ql \e200 |
| 73 | is greater than | 73 | is greater than |
| 74 | .Ql \e0 . | 74 | .Ql \e0 . |
| 75 | .Pp | ||
| 76 | The | ||
| 77 | .Fn strncmp | ||
| 78 | compares not more than | ||
| 79 | .Fa len | ||
| 80 | characters. | ||
| 81 | .Sh SEE ALSO | 75 | .Sh SEE ALSO |
| 82 | .Xr bcmp 3 , | 76 | .Xr bcmp 3 , |
| 83 | .Xr memcmp 3 , | 77 | .Xr memcmp 3 , |
| 84 | .Xr strcasecmp 3 , | 78 | .Xr strcasecmp 3 , |
| 85 | .Xr strcoll 3 , | 79 | .Xr strcoll 3 , |
| 86 | .Xr strxfrm 3 | 80 | .Xr strxfrm 3 , |
| 81 | .Xr wcscmp 3 | ||
| 87 | .Sh STANDARDS | 82 | .Sh STANDARDS |
| 88 | The | 83 | The |
| 89 | .Fn strcmp | 84 | .Fn strcmp |
| 90 | and | 85 | and |
| 91 | .Fn strncmp | 86 | .Fn strncmp |
| 92 | functions | 87 | functions conform to |
| 93 | conform to | ||
| 94 | .St -ansiC . | 88 | .St -ansiC . |
| 89 | .Sh HISTORY | ||
| 90 | The | ||
| 91 | .Fn strcmp | ||
| 92 | function first appeared in the Programmer's Workbench (PWB/UNIX) | ||
| 93 | and was ported to | ||
| 94 | .At v7 ; | ||
| 95 | .Fn strncmp | ||
| 96 | first appeared in | ||
| 97 | .At v7 . | ||
diff --git a/src/lib/libc/string/strcmp.c b/src/lib/libc/string/strcmp.c index ae19e2e26e..816fd111ac 100644 --- a/src/lib/libc/string/strcmp.c +++ b/src/lib/libc/string/strcmp.c | |||
| @@ -1,3 +1,5 @@ | |||
| 1 | /* $OpenBSD: strcmp.c,v 1.7 2005/08/08 08:05:37 espie Exp $ */ | ||
| 2 | |||
| 1 | /*- | 3 | /*- |
| 2 | * Copyright (c) 1990 The Regents of the University of California. | 4 | * Copyright (c) 1990 The Regents of the University of California. |
| 3 | * All rights reserved. | 5 | * All rights reserved. |
| @@ -13,11 +15,7 @@ | |||
| 13 | * 2. Redistributions in binary form must reproduce the above copyright | 15 | * 2. Redistributions in binary form must reproduce the above copyright |
| 14 | * notice, this list of conditions and the following disclaimer in the | 16 | * notice, this list of conditions and the following disclaimer in the |
| 15 | * documentation and/or other materials provided with the distribution. | 17 | * documentation and/or other materials provided with the distribution. |
| 16 | * 3. All advertising materials mentioning features or use of this software | 18 | * 3. Neither the name of the University nor the names of its contributors |
| 17 | * must display the following acknowledgement: | ||
| 18 | * This product includes software developed by the University of | ||
| 19 | * California, Berkeley and its contributors. | ||
| 20 | * 4. Neither the name of the University nor the names of its contributors | ||
| 21 | * may be used to endorse or promote products derived from this software | 19 | * may be used to endorse or promote products derived from this software |
| 22 | * without specific prior written permission. | 20 | * without specific prior written permission. |
| 23 | * | 21 | * |
| @@ -34,19 +32,17 @@ | |||
| 34 | * SUCH DAMAGE. | 32 | * SUCH DAMAGE. |
| 35 | */ | 33 | */ |
| 36 | 34 | ||
| 37 | #if defined(LIBC_SCCS) && !defined(lint) | 35 | #if !defined(_KERNEL) && !defined(_STANDALONE) |
| 38 | /*static char *sccsid = "from: @(#)strcmp.c 5.5 (Berkeley) 1/26/91";*/ | ||
| 39 | static char *rcsid = "$Id: strcmp.c,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $"; | ||
| 40 | #endif /* LIBC_SCCS and not lint */ | ||
| 41 | |||
| 42 | #include <string.h> | 36 | #include <string.h> |
| 37 | #else | ||
| 38 | #include <lib/libkern/libkern.h> | ||
| 39 | #endif | ||
| 43 | 40 | ||
| 44 | /* | 41 | /* |
| 45 | * Compare strings. | 42 | * Compare strings. |
| 46 | */ | 43 | */ |
| 47 | int | 44 | int |
| 48 | strcmp(s1, s2) | 45 | strcmp(const char *s1, const char *s2) |
| 49 | register const char *s1, *s2; | ||
| 50 | { | 46 | { |
| 51 | while (*s1 == *s2++) | 47 | while (*s1 == *s2++) |
| 52 | if (*s1++ == 0) | 48 | if (*s1++ == 0) |
diff --git a/src/lib/libc/string/strcoll.3 b/src/lib/libc/string/strcoll.3 index 12f73f98f2..d421200b62 100644 --- a/src/lib/libc/string/strcoll.3 +++ b/src/lib/libc/string/strcoll.3 | |||
| @@ -13,11 +13,7 @@ | |||
| 13 | .\" 2. Redistributions in binary form must reproduce the above copyright | 13 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 14 | .\" notice, this list of conditions and the following disclaimer in the | 14 | .\" notice, this list of conditions and the following disclaimer in the |
| 15 | .\" documentation and/or other materials provided with the distribution. | 15 | .\" documentation and/or other materials provided with the distribution. |
| 16 | .\" 3. All advertising materials mentioning features or use of this software | 16 | .\" 3. Neither the name of the University nor the names of its contributors |
| 17 | .\" must display the following acknowledgement: | ||
| 18 | .\" This product includes software developed by the University of | ||
| 19 | .\" California, Berkeley and its contributors. | ||
| 20 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 21 | .\" may be used to endorse or promote products derived from this software | 17 | .\" may be used to endorse or promote products derived from this software |
| 22 | .\" without specific prior written permission. | 18 | .\" without specific prior written permission. |
| 23 | .\" | 19 | .\" |
| @@ -33,30 +29,28 @@ | |||
| 33 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 29 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 34 | .\" SUCH DAMAGE. | 30 | .\" SUCH DAMAGE. |
| 35 | .\" | 31 | .\" |
| 36 | .\" from: @(#)strcoll.3 5.6 (Berkeley) 6/29/91 | 32 | .\" $OpenBSD: strcoll.3,v 1.9 2013/06/05 03:39:23 tedu Exp $ |
| 37 | .\" $Id: strcoll.3,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $ | ||
| 38 | .\" | 33 | .\" |
| 39 | .Dd June 29, 1991 | 34 | .Dd $Mdocdate: June 5 2013 $ |
| 40 | .Dt STRCOLL 3 | 35 | .Dt STRCOLL 3 |
| 41 | .Os | 36 | .Os |
| 42 | .Sh NAME | 37 | .Sh NAME |
| 43 | .Nm strcoll | 38 | .Nm strcoll |
| 44 | .Nd compare strings according to current collation | 39 | .Nd compare strings according to current collation |
| 45 | .Sh SYNOPSIS | 40 | .Sh SYNOPSIS |
| 46 | .Fd #include <string.h> | 41 | .In string.h |
| 47 | .Ft int | 42 | .Ft int |
| 48 | .Fn strcoll "const char *s1" "const char *s2" | 43 | .Fn strcoll "const char *s1" "const char *s2" |
| 49 | .Sh DESCRIPTION | 44 | .Sh DESCRIPTION |
| 50 | The | 45 | The |
| 51 | .Fn strcoll | 46 | .Fn strcoll |
| 52 | function | 47 | function lexicographically compares the NUL-terminated strings |
| 53 | lexicographically compares the null-terminated strings | ||
| 54 | .Fa s1 | 48 | .Fa s1 |
| 55 | and | 49 | and |
| 56 | .Fa s2 | 50 | .Fa s2 |
| 57 | according to the current locale collation | 51 | according to the current locale collation |
| 58 | and returns an integer greater than, equal to, or less than 0, | 52 | and returns an integer greater than, equal to, or less than 0, |
| 59 | according as | 53 | according to whether |
| 60 | .Fa s1 | 54 | .Fa s1 |
| 61 | is greater than, equal to, or less than | 55 | is greater than, equal to, or less than |
| 62 | .Fa s2 . | 56 | .Fa s2 . |
| @@ -70,6 +64,10 @@ is greater than, equal to, or less than | |||
| 70 | .Sh STANDARDS | 64 | .Sh STANDARDS |
| 71 | The | 65 | The |
| 72 | .Fn strcoll | 66 | .Fn strcoll |
| 73 | function | 67 | function conforms to |
| 74 | conforms to | ||
| 75 | .St -ansiC . | 68 | .St -ansiC . |
| 69 | .Sh HISTORY | ||
| 70 | The | ||
| 71 | .Fn strcoll | ||
| 72 | function first appeared in | ||
| 73 | .Bx 4.3 Reno . | ||
diff --git a/src/lib/libc/string/strcoll.c b/src/lib/libc/string/strcoll.c index 86c742cba9..2df983bd65 100644 --- a/src/lib/libc/string/strcoll.c +++ b/src/lib/libc/string/strcoll.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: strcoll.c,v 1.5 2005/08/08 08:05:37 espie Exp $ */ | ||
| 1 | /*- | 2 | /*- |
| 2 | * Copyright (c) 1990 The Regents of the University of California. | 3 | * Copyright (c) 1990 The Regents of the University of California. |
| 3 | * All rights reserved. | 4 | * All rights reserved. |
| @@ -13,11 +14,7 @@ | |||
| 13 | * 2. Redistributions in binary form must reproduce the above copyright | 14 | * 2. Redistributions in binary form must reproduce the above copyright |
| 14 | * notice, this list of conditions and the following disclaimer in the | 15 | * notice, this list of conditions and the following disclaimer in the |
| 15 | * documentation and/or other materials provided with the distribution. | 16 | * documentation and/or other materials provided with the distribution. |
| 16 | * 3. All advertising materials mentioning features or use of this software | 17 | * 3. Neither the name of the University nor the names of its contributors |
| 17 | * must display the following acknowledgement: | ||
| 18 | * This product includes software developed by the University of | ||
| 19 | * California, Berkeley and its contributors. | ||
| 20 | * 4. Neither the name of the University nor the names of its contributors | ||
| 21 | * may be used to endorse or promote products derived from this software | 18 | * may be used to endorse or promote products derived from this software |
| 22 | * without specific prior written permission. | 19 | * without specific prior written permission. |
| 23 | * | 20 | * |
| @@ -34,19 +31,13 @@ | |||
| 34 | * SUCH DAMAGE. | 31 | * SUCH DAMAGE. |
| 35 | */ | 32 | */ |
| 36 | 33 | ||
| 37 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 38 | /*static char *sccsid = "from: @(#)strcoll.c 5.2 (Berkeley) 1/26/91";*/ | ||
| 39 | static char *rcsid = "$Id: strcoll.c,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $"; | ||
| 40 | #endif /* LIBC_SCCS and not lint */ | ||
| 41 | |||
| 42 | #include <string.h> | 34 | #include <string.h> |
| 43 | 35 | ||
| 44 | /* | 36 | /* |
| 45 | * Compare strings according to LC_COLLATE category of current locale. | 37 | * Compare strings according to LC_COLLATE category of current locale. |
| 46 | */ | 38 | */ |
| 47 | int | 39 | int |
| 48 | strcoll(s1, s2) | 40 | strcoll(const char *s1, const char *s2) |
| 49 | const char *s1, *s2; | ||
| 50 | { | 41 | { |
| 51 | /* LC_COLLATE is unimplemented, hence always "C" */ | 42 | /* LC_COLLATE is unimplemented, hence always "C" */ |
| 52 | return (strcmp(s1, s2)); | 43 | return (strcmp(s1, s2)); |
diff --git a/src/lib/libc/string/strcpy.3 b/src/lib/libc/string/strcpy.3 index 1ca12c2707..849184d1f5 100644 --- a/src/lib/libc/string/strcpy.3 +++ b/src/lib/libc/string/strcpy.3 | |||
| @@ -1,3 +1,5 @@ | |||
| 1 | .\" $OpenBSD: strcpy.3,v 1.20 2013/12/19 20:52:37 millert Exp $ | ||
| 2 | .\" | ||
| 1 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. | 3 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. |
| 2 | .\" All rights reserved. | 4 | .\" All rights reserved. |
| 3 | .\" | 5 | .\" |
| @@ -13,11 +15,7 @@ | |||
| 13 | .\" 2. Redistributions in binary form must reproduce the above copyright | 15 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 14 | .\" notice, this list of conditions and the following disclaimer in the | 16 | .\" notice, this list of conditions and the following disclaimer in the |
| 15 | .\" documentation and/or other materials provided with the distribution. | 17 | .\" documentation and/or other materials provided with the distribution. |
| 16 | .\" 3. All advertising materials mentioning features or use of this software | 18 | .\" 3. Neither the name of the University nor the names of its contributors |
| 17 | .\" must display the following acknowledgement: | ||
| 18 | .\" This product includes software developed by the University of | ||
| 19 | .\" California, Berkeley and its contributors. | ||
| 20 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 21 | .\" may be used to endorse or promote products derived from this software | 19 | .\" may be used to endorse or promote products derived from this software |
| 22 | .\" without specific prior written permission. | 20 | .\" without specific prior written permission. |
| 23 | .\" | 21 | .\" |
| @@ -33,90 +31,62 @@ | |||
| 33 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 34 | .\" SUCH DAMAGE. | 32 | .\" SUCH DAMAGE. |
| 35 | .\" | 33 | .\" |
| 36 | .\" from: @(#)strcpy.3 5.4 (Berkeley) 6/29/91 | 34 | .Dd $Mdocdate: December 19 2013 $ |
| 37 | .\" $Id: strcpy.3,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $ | ||
| 38 | .\" | ||
| 39 | .Dd June 29, 1991 | ||
| 40 | .Dt STRCPY 3 | 35 | .Dt STRCPY 3 |
| 41 | .Os BSD 4 | 36 | .Os |
| 42 | .Sh NAME | 37 | .Sh NAME |
| 43 | .Nm strcpy | 38 | .Nm strcpy |
| 44 | .Nd copy strings | 39 | .Nd copy a string |
| 45 | .Sh SYNOPSIS | 40 | .Sh SYNOPSIS |
| 46 | .Fd #include <string.h> | 41 | .In string.h |
| 47 | .Ft char * | 42 | .Ft char * |
| 48 | .Fn strcpy "char *dst" "const char *src" | 43 | .Fn strcpy "char *dst" "const char *src" |
| 49 | .Ft char * | ||
| 50 | .Fn strncpy "char *dst" "const char *src" "size_t len" | ||
| 51 | .Sh DESCRIPTION | 44 | .Sh DESCRIPTION |
| 52 | The | 45 | The |
| 53 | .Fn strcpy | 46 | .Fn strcpy |
| 54 | and | 47 | function copies the string |
| 55 | .Fn strncpy | ||
| 56 | functions | ||
| 57 | copy the string | ||
| 58 | .Fa src | 48 | .Fa src |
| 59 | to | 49 | to |
| 60 | .Fa dst | 50 | .Fa dst |
| 61 | (including the terminating | 51 | (including the terminating |
| 62 | .Ql \e0 | 52 | .Ql \e0 |
| 63 | character). | 53 | character). |
| 54 | The string | ||
| 55 | .Fa dst | ||
| 56 | must be at least as large as | ||
| 57 | .Fa src | ||
| 58 | to hold the result. | ||
| 64 | .Pp | 59 | .Pp |
| 65 | The | 60 | If the |
| 66 | .Fn strncpy | ||
| 67 | copies not more than | ||
| 68 | .Fa len | ||
| 69 | characters into | ||
| 70 | .Fa dst , | ||
| 71 | appending | ||
| 72 | .Ql \e0 | ||
| 73 | characters if | ||
| 74 | .Fa src | 61 | .Fa src |
| 75 | is less than | 62 | and |
| 76 | .Fa len | ||
| 77 | characters long, and | ||
| 78 | .Em not | ||
| 79 | terminating | ||
| 80 | .Fa dst | 63 | .Fa dst |
| 81 | if | 64 | strings overlap, the behavior is undefined. |
| 82 | .Fa src | ||
| 83 | is more than | ||
| 84 | .Fa len | ||
| 85 | characters long. | ||
| 86 | .Sh RETURN VALUES | 65 | .Sh RETURN VALUES |
| 87 | The | 66 | The |
| 88 | .Fn strcpy | 67 | .Fn strcpy |
| 89 | and | 68 | function returns |
| 90 | .Fn strncpy | ||
| 91 | functions | ||
| 92 | return | ||
| 93 | .Fa dst . | 69 | .Fa dst . |
| 94 | .Sh EXAMPLES | ||
| 95 | The following sets | ||
| 96 | .Dq Li chararray | ||
| 97 | to | ||
| 98 | .Dq Li abc\e0\e0\e0 : | ||
| 99 | .Bd -literal -offset indent | ||
| 100 | (void)strncpy(chararray, "abc", 6). | ||
| 101 | .Ed | ||
| 102 | .Pp | ||
| 103 | The following sets | ||
| 104 | .Dq Li chararray | ||
| 105 | to | ||
| 106 | .Dq Li abcdef : | ||
| 107 | .Bd -literal -offset indent | ||
| 108 | (void)strncpy(chararray, "abcdefgh", 6); | ||
| 109 | .Ed | ||
| 110 | .Sh SEE ALSO | 70 | .Sh SEE ALSO |
| 111 | .Xr bcopy 3 , | 71 | .Xr bcopy 3 , |
| 112 | .Xr memccpy 3 , | 72 | .Xr memccpy 3 , |
| 113 | .Xr memcpy 3 , | 73 | .Xr memcpy 3 , |
| 114 | .Xr memmove 3 | 74 | .Xr memmove 3 , |
| 75 | .Xr strcat 3 , | ||
| 76 | .Xr strlcpy 3 , | ||
| 77 | .Xr strncpy 3 , | ||
| 78 | .Xr wcscpy 3 , | ||
| 79 | .Xr wcslcpy 3 | ||
| 115 | .Sh STANDARDS | 80 | .Sh STANDARDS |
| 116 | The | 81 | The |
| 117 | .Fn strcpy | 82 | .Fn strcpy |
| 118 | and | 83 | and |
| 119 | .Fn strncpy | 84 | .Fn strncpy |
| 120 | functions | 85 | functions conform to |
| 121 | conform to | ||
| 122 | .St -ansiC . | 86 | .St -ansiC . |
| 87 | .Sh HISTORY | ||
| 88 | The | ||
| 89 | .Fn strcpy | ||
| 90 | function first appeared in the Programmer's Workbench (PWB/UNIX) | ||
| 91 | and was ported to | ||
| 92 | .At v7 . | ||
diff --git a/src/lib/libc/string/strcpy.c b/src/lib/libc/string/strcpy.c index 669bfde23e..71d90d4100 100644 --- a/src/lib/libc/string/strcpy.c +++ b/src/lib/libc/string/strcpy.c | |||
| @@ -1,3 +1,5 @@ | |||
| 1 | /* $OpenBSD: strcpy.c,v 1.8 2005/08/08 08:05:37 espie Exp $ */ | ||
| 2 | |||
| 1 | /* | 3 | /* |
| 2 | * Copyright (c) 1988 Regents of the University of California. | 4 | * Copyright (c) 1988 Regents of the University of California. |
| 3 | * All rights reserved. | 5 | * All rights reserved. |
| @@ -10,11 +12,7 @@ | |||
| 10 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the |
| 12 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. All advertising materials mentioning features or use of this software | 15 | * 3. Neither the name of the University nor the names of its contributors |
| 14 | * must display the following acknowledgement: | ||
| 15 | * This product includes software developed by the University of | ||
| 16 | * California, Berkeley and its contributors. | ||
| 17 | * 4. Neither the name of the University nor the names of its contributors | ||
| 18 | * may be used to endorse or promote products derived from this software | 16 | * may be used to endorse or promote products derived from this software |
| 19 | * without specific prior written permission. | 17 | * without specific prior written permission. |
| 20 | * | 18 | * |
| @@ -31,20 +29,22 @@ | |||
| 31 | * SUCH DAMAGE. | 29 | * SUCH DAMAGE. |
| 32 | */ | 30 | */ |
| 33 | 31 | ||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | 32 | #if !defined(_KERNEL) && !defined(_STANDALONE) |
| 35 | /*static char *sccsid = "from: @(#)strcpy.c 5.7 (Berkeley) 2/24/91";*/ | ||
| 36 | static char *rcsid = "$Id: strcpy.c,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $"; | ||
| 37 | #endif /* LIBC_SCCS and not lint */ | ||
| 38 | |||
| 39 | #include <string.h> | 33 | #include <string.h> |
| 34 | #else | ||
| 35 | #include <lib/libkern/libkern.h> | ||
| 36 | #endif | ||
| 37 | |||
| 38 | #if defined(APIWARN) | ||
| 39 | __warn_references(strcpy, | ||
| 40 | "warning: strcpy() is almost always misused, please use strlcpy()"); | ||
| 41 | #endif | ||
| 40 | 42 | ||
| 41 | char * | 43 | char * |
| 42 | strcpy(to, from) | 44 | strcpy(char *to, const char *from) |
| 43 | register char *to; | ||
| 44 | register const char *from; | ||
| 45 | { | 45 | { |
| 46 | char *save = to; | 46 | char *save = to; |
| 47 | 47 | ||
| 48 | for (; *to = *from; ++from, ++to); | 48 | for (; (*to = *from) != '\0'; ++from, ++to); |
| 49 | return(save); | 49 | return(save); |
| 50 | } | 50 | } |
diff --git a/src/lib/libc/string/strcspn.3 b/src/lib/libc/string/strcspn.3 index cc9e5c2fe3..07eb9ca26f 100644 --- a/src/lib/libc/string/strcspn.3 +++ b/src/lib/libc/string/strcspn.3 | |||
| @@ -1,3 +1,5 @@ | |||
| 1 | .\" $OpenBSD: strcspn.3,v 1.11 2013/06/05 03:39:23 tedu Exp $ | ||
| 2 | .\" | ||
| 1 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. | 3 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. |
| 2 | .\" All rights reserved. | 4 | .\" All rights reserved. |
| 3 | .\" | 5 | .\" |
| @@ -13,11 +15,7 @@ | |||
| 13 | .\" 2. Redistributions in binary form must reproduce the above copyright | 15 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 14 | .\" notice, this list of conditions and the following disclaimer in the | 16 | .\" notice, this list of conditions and the following disclaimer in the |
| 15 | .\" documentation and/or other materials provided with the distribution. | 17 | .\" documentation and/or other materials provided with the distribution. |
| 16 | .\" 3. All advertising materials mentioning features or use of this software | 18 | .\" 3. Neither the name of the University nor the names of its contributors |
| 17 | .\" must display the following acknowledgement: | ||
| 18 | .\" This product includes software developed by the University of | ||
| 19 | .\" California, Berkeley and its contributors. | ||
| 20 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 21 | .\" may be used to endorse or promote products derived from this software | 19 | .\" may be used to endorse or promote products derived from this software |
| 22 | .\" without specific prior written permission. | 20 | .\" without specific prior written permission. |
| 23 | .\" | 21 | .\" |
| @@ -33,53 +31,78 @@ | |||
| 33 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 34 | .\" SUCH DAMAGE. | 32 | .\" SUCH DAMAGE. |
| 35 | .\" | 33 | .\" |
| 36 | .\" from: @(#)strcspn.3 5.3 (Berkeley) 6/29/91 | 34 | .Dd $Mdocdate: June 5 2013 $ |
| 37 | .\" $Id: strcspn.3,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $ | ||
| 38 | .\" | ||
| 39 | .Dd June 29, 1991 | ||
| 40 | .Dt STRCSPN 3 | 35 | .Dt STRCSPN 3 |
| 41 | .Os | 36 | .Os |
| 42 | .Sh NAME | 37 | .Sh NAME |
| 43 | .Nm strcspn | 38 | .Nm strcspn |
| 44 | .Nd span the complement of a string | 39 | .Nd span the complement of a string |
| 45 | .Sh SYNOPSIS | 40 | .Sh SYNOPSIS |
| 46 | .Fd #include <string.h> | 41 | .In string.h |
| 47 | .Ft size_t | 42 | .Ft size_t |
| 48 | .Fn strcspn "const char *s" "const char *charset" | 43 | .Fn strcspn "const char *s" "const char *charset" |
| 49 | .Sh DESCRIPTION | 44 | .Sh DESCRIPTION |
| 50 | The | 45 | The |
| 51 | .Fn strcspn | 46 | .Fn strcspn |
| 52 | function | 47 | function spans the initial part of the NUL-terminated string |
| 53 | spans the initial part of the null-terminated string | ||
| 54 | .Fa s | 48 | .Fa s |
| 55 | as long as the characters from | 49 | as long as the characters from |
| 56 | .Fa s | 50 | .Fa s |
| 57 | do not occur in string | 51 | do not occur in string |
| 58 | .Fa charset | 52 | .Fa charset |
| 59 | (it | 53 | (it spans the |
| 60 | spans the | ||
| 61 | .Em complement | 54 | .Em complement |
| 62 | of | 55 | of |
| 63 | .Fa charset ) . | 56 | .Fa charset ) . |
| 64 | .Sh RETURN VALUES | 57 | .Sh RETURN VALUES |
| 65 | The | 58 | The |
| 66 | .Fn strcspn | 59 | .Fn strcspn |
| 67 | function | 60 | function returns the number of characters spanned. |
| 68 | returns the number of characters spanned. | 61 | .Sh EXAMPLES |
| 62 | The following call to | ||
| 63 | .Fn strcspn | ||
| 64 | will return 3, since the first three characters of string | ||
| 65 | .Fa s | ||
| 66 | do not occur in string | ||
| 67 | .Fa charset : | ||
| 68 | .Bd -literal -offset indent | ||
| 69 | char *s = "foobar"; | ||
| 70 | char *charset = "bar"; | ||
| 71 | size_t span; | ||
| 72 | |||
| 73 | span = strcspn(s, charset); | ||
| 74 | .Ed | ||
| 75 | .Pp | ||
| 76 | The following removes the first (if any) newline character from string | ||
| 77 | .Fa line . | ||
| 78 | This is useful for trimming the newline after a | ||
| 79 | .Xr fgets 3 | ||
| 80 | call. | ||
| 81 | .Bd -literal -offset indent | ||
| 82 | char line[BUFSIZ]; | ||
| 83 | |||
| 84 | if (fgets(line, sizeof(line), fp) != NULL) | ||
| 85 | line[strcspn(line, "\en")] = '\e0'; | ||
| 86 | .Ed | ||
| 69 | .Sh SEE ALSO | 87 | .Sh SEE ALSO |
| 70 | .Xr index 3 , | ||
| 71 | .Xr memchr 3 , | 88 | .Xr memchr 3 , |
| 72 | .Xr rindex 3 , | ||
| 73 | .Xr strchr 3 , | 89 | .Xr strchr 3 , |
| 74 | .Xr strpbrk 3 , | 90 | .Xr strpbrk 3 , |
| 75 | .Xr strrchr 3 , | 91 | .Xr strrchr 3 , |
| 76 | .Xr strsep 3 , | 92 | .Xr strsep 3 , |
| 77 | .Xr strspn 3 , | 93 | .Xr strspn 3 , |
| 78 | .Xr strstr 3 , | 94 | .Xr strstr 3 , |
| 79 | .Xr strtok 3 | 95 | .Xr strtok 3 , |
| 96 | .Xr wcscspn 3 | ||
| 80 | .Sh STANDARDS | 97 | .Sh STANDARDS |
| 81 | The | 98 | The |
| 82 | .Fn strcspn | 99 | .Fn strcspn |
| 83 | function | 100 | function conforms to |
| 84 | conforms to | ||
| 85 | .St -ansiC . | 101 | .St -ansiC . |
| 102 | .Sh HISTORY | ||
| 103 | The | ||
| 104 | .Fn strcspn | ||
| 105 | function first appeared in | ||
| 106 | .At III | ||
| 107 | and was reimplemented for | ||
| 108 | .Bx 4.3 Tahoe . | ||
diff --git a/src/lib/libc/string/strcspn.c b/src/lib/libc/string/strcspn.c index acb4d2a3af..1eb233614d 100644 --- a/src/lib/libc/string/strcspn.c +++ b/src/lib/libc/string/strcspn.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: strcspn.c,v 1.5 2005/08/08 08:05:37 espie Exp $ */ | ||
| 1 | /*- | 2 | /*- |
| 2 | * Copyright (c) 1990 The Regents of the University of California. | 3 | * Copyright (c) 1990 The Regents of the University of California. |
| 3 | * All rights reserved. | 4 | * All rights reserved. |
| @@ -13,11 +14,7 @@ | |||
| 13 | * 2. Redistributions in binary form must reproduce the above copyright | 14 | * 2. Redistributions in binary form must reproduce the above copyright |
| 14 | * notice, this list of conditions and the following disclaimer in the | 15 | * notice, this list of conditions and the following disclaimer in the |
| 15 | * documentation and/or other materials provided with the distribution. | 16 | * documentation and/or other materials provided with the distribution. |
| 16 | * 3. All advertising materials mentioning features or use of this software | 17 | * 3. Neither the name of the University nor the names of its contributors |
| 17 | * must display the following acknowledgement: | ||
| 18 | * This product includes software developed by the University of | ||
| 19 | * California, Berkeley and its contributors. | ||
| 20 | * 4. Neither the name of the University nor the names of its contributors | ||
| 21 | * may be used to endorse or promote products derived from this software | 18 | * may be used to endorse or promote products derived from this software |
| 22 | * without specific prior written permission. | 19 | * without specific prior written permission. |
| 23 | * | 20 | * |
| @@ -34,23 +31,16 @@ | |||
| 34 | * SUCH DAMAGE. | 31 | * SUCH DAMAGE. |
| 35 | */ | 32 | */ |
| 36 | 33 | ||
| 37 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 38 | /*static char *sccsid = "from: @(#)strcspn.c 5.6 (Berkeley) 1/26/91";*/ | ||
| 39 | static char *rcsid = "$Id: strcspn.c,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $"; | ||
| 40 | #endif /* LIBC_SCCS and not lint */ | ||
| 41 | |||
| 42 | #include <string.h> | 34 | #include <string.h> |
| 43 | 35 | ||
| 44 | /* | 36 | /* |
| 45 | * Span the complement of string s2. | 37 | * Span the complement of string s2. |
| 46 | */ | 38 | */ |
| 47 | size_t | 39 | size_t |
| 48 | strcspn(s1, s2) | 40 | strcspn(const char *s1, const char *s2) |
| 49 | const char *s1; | ||
| 50 | register const char *s2; | ||
| 51 | { | 41 | { |
| 52 | register const char *p, *spanp; | 42 | const char *p, *spanp; |
| 53 | register char c, sc; | 43 | char c, sc; |
| 54 | 44 | ||
| 55 | /* | 45 | /* |
| 56 | * Stop as soon as we find any character from s2. Note that there | 46 | * Stop as soon as we find any character from s2. Note that there |
diff --git a/src/lib/libc/string/strdup.3 b/src/lib/libc/string/strdup.3 index 925cbf3d46..2d7fa0bb96 100644 --- a/src/lib/libc/string/strdup.3 +++ b/src/lib/libc/string/strdup.3 | |||
| @@ -1,5 +1,7 @@ | |||
| 1 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. | 1 | .\" $OpenBSD: strdup.3,v 1.20 2013/06/05 03:39:23 tedu Exp $ |
| 2 | .\" All rights reserved. | 2 | .\" |
| 3 | .\" Copyright (c) 1990, 1991, 1993 | ||
| 4 | .\" The Regents of the University of California. All rights reserved. | ||
| 3 | .\" | 5 | .\" |
| 4 | .\" Redistribution and use in source and binary forms, with or without | 6 | .\" Redistribution and use in source and binary forms, with or without |
| 5 | .\" modification, are permitted provided that the following conditions | 7 | .\" modification, are permitted provided that the following conditions |
| @@ -9,11 +11,7 @@ | |||
| 9 | .\" 2. Redistributions in binary form must reproduce the above copyright | 11 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 10 | .\" notice, this list of conditions and the following disclaimer in the | 12 | .\" notice, this list of conditions and the following disclaimer in the |
| 11 | .\" documentation and/or other materials provided with the distribution. | 13 | .\" documentation and/or other materials provided with the distribution. |
| 12 | .\" 3. All advertising materials mentioning features or use of this software | 14 | .\" 3. Neither the name of the University nor the names of its contributors |
| 13 | .\" must display the following acknowledgement: | ||
| 14 | .\" This product includes software developed by the University of | ||
| 15 | .\" California, Berkeley and its contributors. | ||
| 16 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 17 | .\" may be used to endorse or promote products derived from this software | 15 | .\" may be used to endorse or promote products derived from this software |
| 18 | .\" without specific prior written permission. | 16 | .\" without specific prior written permission. |
| 19 | .\" | 17 | .\" |
| @@ -29,37 +27,86 @@ | |||
| 29 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 27 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 30 | .\" SUCH DAMAGE. | 28 | .\" SUCH DAMAGE. |
| 31 | .\" | 29 | .\" |
| 32 | .\" from: @(#)strdup.3 5.3 (Berkeley) 4/19/91 | 30 | .\" @(#)strdup.3 8.1 (Berkeley) 6/9/93 |
| 33 | .\" $Id: strdup.3,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $ | ||
| 34 | .\" | 31 | .\" |
| 35 | .Dd April 19, 1991 | 32 | .Dd $Mdocdate: June 5 2013 $ |
| 36 | .Dt STRDUP 3 | 33 | .Dt STRDUP 3 |
| 37 | .Os | 34 | .Os |
| 38 | .Sh NAME | 35 | .Sh NAME |
| 39 | .Nm strdup | 36 | .Nm strdup , |
| 37 | .Nm strndup | ||
| 40 | .Nd save a copy of a string | 38 | .Nd save a copy of a string |
| 41 | .Sh SYNOPSIS | 39 | .Sh SYNOPSIS |
| 42 | .Fd #include <string.h> | 40 | .In string.h |
| 41 | .Ft char * | ||
| 42 | .Fn strdup "const char *s" | ||
| 43 | .Ft char * | 43 | .Ft char * |
| 44 | .Fn strdup "const char *str" | 44 | .Fn strndup "const char *s" "size_t maxlen" |
| 45 | .Sh DESCRIPTION | 45 | .Sh DESCRIPTION |
| 46 | The | 46 | The |
| 47 | .Fn strdup | 47 | .Fn strdup |
| 48 | function | 48 | function allocates sufficient memory for a copy of the string |
| 49 | allocates sufficient memory for a copy | 49 | .Fa s , |
| 50 | of the string | ||
| 51 | .Fa str , | ||
| 52 | does the copy, and returns a pointer to it. | 50 | does the copy, and returns a pointer to it. |
| 53 | The pointer may subsequently be used as an | 51 | The pointer may subsequently be used as an argument to the function |
| 54 | argument to the function | ||
| 55 | .Xr free 3 . | 52 | .Xr free 3 . |
| 53 | .Pp | ||
| 54 | The | ||
| 55 | .Fn strndup | ||
| 56 | function behaves similarly to | ||
| 57 | .Nm strdup | ||
| 58 | but only copies up to | ||
| 59 | .Fa maxlen | ||
| 60 | characters from | ||
| 61 | .Fa s . | ||
| 62 | The resulting string is always NUL-terminated. | ||
| 63 | .Pp | ||
| 64 | If insufficient memory is available, | ||
| 65 | .Dv NULL | ||
| 66 | is returned. | ||
| 67 | .Sh EXAMPLES | ||
| 68 | The following will point | ||
| 69 | .Va p | ||
| 70 | to an allocated area of memory containing the NUL-terminated string | ||
| 71 | .Qq foobar : | ||
| 72 | .Bd -literal -offset indent | ||
| 73 | char *p; | ||
| 74 | |||
| 75 | p = strdup("foobar"); | ||
| 76 | if (p == NULL) | ||
| 77 | err(1, NULL); | ||
| 78 | .Ed | ||
| 79 | .Sh ERRORS | ||
| 80 | The | ||
| 81 | .Fn strdup | ||
| 82 | and | ||
| 83 | .Fn strndup | ||
| 84 | functions may fail and set the external variable | ||
| 85 | .Va errno | ||
| 86 | for any of the errors specified for the library function | ||
| 87 | .Xr malloc 3 . | ||
| 56 | .Sh SEE ALSO | 88 | .Sh SEE ALSO |
| 57 | .Xr free 3 , | 89 | .Xr free 3 , |
| 58 | .Xr malloc 3 , | 90 | .Xr malloc 3 , |
| 59 | .Xt strcpy 3 , | 91 | .Xr strcpy 3 , |
| 60 | .Xt strlen 3 | 92 | .Xr strlcpy 3 , |
| 93 | .Xr strlen 3 , | ||
| 94 | .Xr wcsdup 3 | ||
| 95 | .Sh STANDARDS | ||
| 96 | The | ||
| 97 | .Fn strdup | ||
| 98 | and | ||
| 99 | .Fn strndup | ||
| 100 | functions conform to | ||
| 101 | .St -p1003.1-2008 . | ||
| 61 | .Sh HISTORY | 102 | .Sh HISTORY |
| 62 | The | 103 | The |
| 63 | .Fn strdup | 104 | .Fn strdup |
| 64 | function | 105 | function first appeared in |
| 65 | .Ud . | 106 | .Bx 4.3 Reno . |
| 107 | The | ||
| 108 | .Fn strndup | ||
| 109 | function appeared in glibc 2.0, was reimplemented for | ||
| 110 | .Nx 4.0 , | ||
| 111 | and ported to | ||
| 112 | .Ox 4.8 . | ||
diff --git a/src/lib/libc/string/strdup.c b/src/lib/libc/string/strdup.c index 27ede44110..a6aa1e03b0 100644 --- a/src/lib/libc/string/strdup.c +++ b/src/lib/libc/string/strdup.c | |||
| @@ -1,6 +1,8 @@ | |||
| 1 | /* $OpenBSD: strdup.c,v 1.6 2005/08/08 08:05:37 espie Exp $ */ | ||
| 2 | |||
| 1 | /* | 3 | /* |
| 2 | * Copyright (c) 1988 The Regents of the University of California. | 4 | * Copyright (c) 1988, 1993 |
| 3 | * All rights reserved. | 5 | * The Regents of the University of California. All rights reserved. |
| 4 | * | 6 | * |
| 5 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without |
| 6 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions |
| @@ -10,11 +12,7 @@ | |||
| 10 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the |
| 12 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. All advertising materials mentioning features or use of this software | 15 | * 3. Neither the name of the University nor the names of its contributors |
| 14 | * must display the following acknowledgement: | ||
| 15 | * This product includes software developed by the University of | ||
| 16 | * California, Berkeley and its contributors. | ||
| 17 | * 4. Neither the name of the University nor the names of its contributors | ||
| 18 | * may be used to endorse or promote products derived from this software | 16 | * may be used to endorse or promote products derived from this software |
| 19 | * without specific prior written permission. | 17 | * without specific prior written permission. |
| 20 | * | 18 | * |
| @@ -31,24 +29,21 @@ | |||
| 31 | * SUCH DAMAGE. | 29 | * SUCH DAMAGE. |
| 32 | */ | 30 | */ |
| 33 | 31 | ||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | 32 | #include <sys/types.h> |
| 35 | /*static char *sccsid = "from: @(#)strdup.c 5.4 (Berkeley) 2/24/91";*/ | ||
| 36 | static char *rcsid = "$Id: strdup.c,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $"; | ||
| 37 | #endif /* LIBC_SCCS and not lint */ | ||
| 38 | 33 | ||
| 34 | #include <stddef.h> | ||
| 39 | #include <stdlib.h> | 35 | #include <stdlib.h> |
| 40 | #include <string.h> | 36 | #include <string.h> |
| 41 | 37 | ||
| 42 | char * | 38 | char * |
| 43 | strdup(str) | 39 | strdup(const char *str) |
| 44 | const char *str; | ||
| 45 | { | 40 | { |
| 46 | size_t len; | 41 | size_t siz; |
| 47 | char *copy; | 42 | char *copy; |
| 48 | 43 | ||
| 49 | len = strlen(str) + 1; | 44 | siz = strlen(str) + 1; |
| 50 | if (!(copy = malloc(len))) | 45 | if ((copy = malloc(siz)) == NULL) |
| 51 | return((char *)NULL); | 46 | return(NULL); |
| 52 | memcpy(copy, str, len); | 47 | (void)memcpy(copy, str, siz); |
| 53 | return(copy); | 48 | return(copy); |
| 54 | } | 49 | } |
diff --git a/src/lib/libc/string/strerror.3 b/src/lib/libc/string/strerror.3 index c9d8504dbb..264ac39052 100644 --- a/src/lib/libc/string/strerror.3 +++ b/src/lib/libc/string/strerror.3 | |||
| @@ -13,11 +13,7 @@ | |||
| 13 | .\" 2. Redistributions in binary form must reproduce the above copyright | 13 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 14 | .\" notice, this list of conditions and the following disclaimer in the | 14 | .\" notice, this list of conditions and the following disclaimer in the |
| 15 | .\" documentation and/or other materials provided with the distribution. | 15 | .\" documentation and/or other materials provided with the distribution. |
| 16 | .\" 3. All advertising materials mentioning features or use of this software | 16 | .\" 3. Neither the name of the University nor the names of its contributors |
| 17 | .\" must display the following acknowledgement: | ||
| 18 | .\" This product includes software developed by the University of | ||
| 19 | .\" California, Berkeley and its contributors. | ||
| 20 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 21 | .\" may be used to endorse or promote products derived from this software | 17 | .\" may be used to endorse or promote products derived from this software |
| 22 | .\" without specific prior written permission. | 18 | .\" without specific prior written permission. |
| 23 | .\" | 19 | .\" |
| @@ -33,28 +29,76 @@ | |||
| 33 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 29 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 34 | .\" SUCH DAMAGE. | 30 | .\" SUCH DAMAGE. |
| 35 | .\" | 31 | .\" |
| 36 | .\" from: @(#)strerror.3 6.9 (Berkeley) 6/29/91 | 32 | .\" $OpenBSD: strerror.3,v 1.13 2014/04/07 17:57:56 schwarze Exp $ |
| 37 | .\" $Id: strerror.3,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $ | ||
| 38 | .\" | 33 | .\" |
| 39 | .Dd June 29, 1991 | 34 | .Dd $Mdocdate: April 7 2014 $ |
| 40 | .Dt STRERROR 3 | 35 | .Dt STRERROR 3 |
| 41 | .Os BSD 4 | 36 | .Os |
| 42 | .Sh NAME | 37 | .Sh NAME |
| 43 | .Nm strerror | 38 | .Nm strerror , |
| 39 | .Nm strerror_r | ||
| 44 | .Nd get error message string | 40 | .Nd get error message string |
| 45 | .Sh SYNOPSIS | 41 | .Sh SYNOPSIS |
| 46 | .Fd #include <string.h> | 42 | .In string.h |
| 47 | .Ft char * | 43 | .Ft char * |
| 48 | .Fn strerror "int errnum" | 44 | .Fn strerror "int errnum" |
| 45 | .Ft int | ||
| 46 | .Fn strerror_r "int errnum" "char *strerrbuf" "size_t buflen" | ||
| 49 | .Sh DESCRIPTION | 47 | .Sh DESCRIPTION |
| 50 | The | 48 | The |
| 51 | .Fn strerror | 49 | .Fn strerror |
| 52 | function returns a pointer to the language-dependent error message | 50 | and |
| 53 | string affiliated with an error number. | 51 | .Fn strerror_r |
| 52 | functions map the error number | ||
| 53 | .Fa errnum | ||
| 54 | to a language-dependent error message string. | ||
| 54 | .Pp | 55 | .Pp |
| 55 | The array pointed to is not to be modified by the program, but may be | 56 | .Fn strerror |
| 56 | overwritten by subsequent calls to | 57 | returns a string containing a maximum of |
| 58 | .Dv NL_TEXTMAX | ||
| 59 | characters, including the trailing NUL. | ||
| 60 | This string is not to be modified by the calling program, | ||
| 61 | but may be overwritten by subsequent calls to | ||
| 57 | .Fn strerror . | 62 | .Fn strerror . |
| 63 | .Pp | ||
| 64 | .Fn strerror_r | ||
| 65 | is a thread safe version of | ||
| 66 | .Fn strerror | ||
| 67 | that places the error message in the specified buffer | ||
| 68 | .Fa strerrbuf . | ||
| 69 | .Sh RETURN VALUES | ||
| 70 | .Fn strerror | ||
| 71 | returns a pointer to the error message string. | ||
| 72 | If an error occurs, the error code is stored in | ||
| 73 | .Va errno . | ||
| 74 | .Pp | ||
| 75 | .Fn strerror_r | ||
| 76 | returns zero upon successful completion. | ||
| 77 | If an error occurs, the error code is stored in | ||
| 78 | .Va errno | ||
| 79 | and the error code is returned. | ||
| 80 | .Sh ERRORS | ||
| 81 | .Fn strerror | ||
| 82 | and | ||
| 83 | .Fn strerror_r | ||
| 84 | may fail if: | ||
| 85 | .Bl -tag -width Er | ||
| 86 | .It Bq Er EINVAL | ||
| 87 | .Fa errnum | ||
| 88 | is not a valid error number. | ||
| 89 | The returned error string will consist of an error message that includes | ||
| 90 | .Fa errnum . | ||
| 91 | .El | ||
| 92 | .Pp | ||
| 93 | .Fn strerror_r | ||
| 94 | may fail if: | ||
| 95 | .Bl -tag -width Er | ||
| 96 | .It Bq Er ERANGE | ||
| 97 | The error message is larger than | ||
| 98 | .Fa buflen | ||
| 99 | characters. | ||
| 100 | The message will be truncated to fit. | ||
| 101 | .El | ||
| 58 | .Sh SEE ALSO | 102 | .Sh SEE ALSO |
| 59 | .Xr intro 2 , | 103 | .Xr intro 2 , |
| 60 | .Xr perror 3 , | 104 | .Xr perror 3 , |
| @@ -63,4 +107,17 @@ overwritten by subsequent calls to | |||
| 63 | The | 107 | The |
| 64 | .Fn strerror | 108 | .Fn strerror |
| 65 | function conforms to | 109 | function conforms to |
| 66 | .St -ansiC . | 110 | .St -ansiC-99 . |
| 111 | The | ||
| 112 | .Fn strerror_r | ||
| 113 | function conforms to | ||
| 114 | .St -p1003.1-2008 . | ||
| 115 | .Sh HISTORY | ||
| 116 | The | ||
| 117 | .Fn strerror | ||
| 118 | function first appeared in | ||
| 119 | .Bx 4.3 Reno . | ||
| 120 | The | ||
| 121 | .Fn strerror_r | ||
| 122 | function first appeared in | ||
| 123 | .Ox 3.3 . | ||
diff --git a/src/lib/libc/string/strerror.c b/src/lib/libc/string/strerror.c index c3f5ab5d98..13996f08e9 100644 --- a/src/lib/libc/string/strerror.c +++ b/src/lib/libc/string/strerror.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: strerror.c,v 1.7 2005/08/08 08:05:37 espie Exp $ */ | ||
| 1 | /* | 2 | /* |
| 2 | * Copyright (c) 1988 Regents of the University of California. | 3 | * Copyright (c) 1988 Regents of the University of California. |
| 3 | * All rights reserved. | 4 | * All rights reserved. |
| @@ -10,11 +11,7 @@ | |||
| 10 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the |
| 12 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. Neither the name of the University nor the names of its contributors |
| 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 | 15 | * may be used to endorse or promote products derived from this software |
| 19 | * without specific prior written permission. | 16 | * without specific prior written permission. |
| 20 | * | 17 | * |
| @@ -31,26 +28,14 @@ | |||
| 31 | * SUCH DAMAGE. | 28 | * SUCH DAMAGE. |
| 32 | */ | 29 | */ |
| 33 | 30 | ||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 35 | /*static char *sccsid = "from: @(#)strerror.c 5.6 (Berkeley) 5/4/91";*/ | ||
| 36 | static char *rcsid = "$Id: strerror.c,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $"; | ||
| 37 | #endif /* LIBC_SCCS and not lint */ | ||
| 38 | |||
| 39 | #include <string.h> | 31 | #include <string.h> |
| 40 | #include <limits.h> | 32 | #include <limits.h> |
| 41 | 33 | ||
| 42 | /* | ||
| 43 | * Since perror() is not allowed to change the contents of strerror()'s | ||
| 44 | * static buffer, both functions supply their own buffers to the | ||
| 45 | * internal function __strerror(). | ||
| 46 | */ | ||
| 47 | |||
| 48 | extern char *__strerror __P((int, char *)); | ||
| 49 | |||
| 50 | char * | 34 | char * |
| 51 | strerror(num) | 35 | strerror(int num) |
| 52 | int num; | ||
| 53 | { | 36 | { |
| 54 | static char buf[NL_TEXTMAX]; | 37 | static char buf[NL_TEXTMAX]; |
| 55 | return __strerror(num, buf); | 38 | |
| 39 | (void)strerror_r(num, buf, sizeof(buf)); | ||
| 40 | return (buf); | ||
| 56 | } | 41 | } |
diff --git a/src/lib/libc/string/strerror_r.c b/src/lib/libc/string/strerror_r.c new file mode 100644 index 0000000000..b85136055b --- /dev/null +++ b/src/lib/libc/string/strerror_r.c | |||
| @@ -0,0 +1,137 @@ | |||
| 1 | /* $OpenBSD: strerror_r.c,v 1.8 2013/06/01 21:26:18 stsp Exp $ */ | ||
| 2 | /* Public Domain <marc@snafu.org> */ | ||
| 3 | |||
| 4 | #ifdef NLS | ||
| 5 | #define catclose _catclose | ||
| 6 | #define catgets _catgets | ||
| 7 | #define catopen _catopen | ||
| 8 | #include <nl_types.h> | ||
| 9 | #endif | ||
| 10 | |||
| 11 | #define sys_errlist _sys_errlist | ||
| 12 | #define sys_nerr _sys_nerr | ||
| 13 | #define sys_siglist _sys_siglist | ||
| 14 | |||
| 15 | #include <errno.h> | ||
| 16 | #include <limits.h> | ||
| 17 | #include <signal.h> | ||
| 18 | #include <string.h> | ||
| 19 | |||
| 20 | static size_t | ||
| 21 | __digits10(unsigned int num) | ||
| 22 | { | ||
| 23 | size_t i = 0; | ||
| 24 | |||
| 25 | do { | ||
| 26 | num /= 10; | ||
| 27 | i++; | ||
| 28 | } while (num != 0); | ||
| 29 | |||
| 30 | return i; | ||
| 31 | } | ||
| 32 | |||
| 33 | static int | ||
| 34 | __itoa(int num, int sign, char *buffer, size_t start, size_t end) | ||
| 35 | { | ||
| 36 | size_t pos; | ||
| 37 | unsigned int a; | ||
| 38 | int neg; | ||
| 39 | |||
| 40 | if (sign && num < 0) { | ||
| 41 | a = -num; | ||
| 42 | neg = 1; | ||
| 43 | } | ||
| 44 | else { | ||
| 45 | a = num; | ||
| 46 | neg = 0; | ||
| 47 | } | ||
| 48 | |||
| 49 | pos = start + __digits10(a); | ||
| 50 | if (neg) | ||
| 51 | pos++; | ||
| 52 | |||
| 53 | if (pos < end) | ||
| 54 | buffer[pos] = '\0'; | ||
| 55 | else | ||
| 56 | return ERANGE; | ||
| 57 | pos--; | ||
| 58 | do { | ||
| 59 | buffer[pos] = (a % 10) + '0'; | ||
| 60 | pos--; | ||
| 61 | a /= 10; | ||
| 62 | } while (a != 0); | ||
| 63 | if (neg) | ||
| 64 | buffer[pos] = '-'; | ||
| 65 | return 0; | ||
| 66 | } | ||
| 67 | |||
| 68 | |||
| 69 | static int | ||
| 70 | __num2string(int num, int sign, int setid, char *buf, size_t buflen, | ||
| 71 | char * list[], size_t max, const char *def) | ||
| 72 | { | ||
| 73 | int ret = 0; | ||
| 74 | size_t len; | ||
| 75 | |||
| 76 | #ifdef NLS | ||
| 77 | nl_catd catd; | ||
| 78 | catd = catopen("libc", NL_CAT_LOCALE); | ||
| 79 | #endif | ||
| 80 | |||
| 81 | if (0 <= num && num < max) { | ||
| 82 | #ifdef NLS | ||
| 83 | len = strlcpy(buf, catgets(catd, setid, num, list[num]), | ||
| 84 | buflen); | ||
| 85 | #else | ||
| 86 | len = strlcpy(buf, list[num], buflen); | ||
| 87 | #endif | ||
| 88 | if (len >= buflen) | ||
| 89 | ret = ERANGE; | ||
| 90 | } else { | ||
| 91 | #ifdef NLS | ||
| 92 | len = strlcpy(buf, catgets(catd, setid, 0xffff, def), buflen); | ||
| 93 | #else | ||
| 94 | len = strlcpy(buf, def, buflen); | ||
| 95 | #endif | ||
| 96 | if (len >= buflen) | ||
| 97 | ret = ERANGE; | ||
| 98 | else { | ||
| 99 | ret = __itoa(num, sign, buf, len, buflen); | ||
| 100 | if (ret == 0) | ||
| 101 | ret = EINVAL; | ||
| 102 | } | ||
| 103 | } | ||
| 104 | |||
| 105 | #ifdef NLS | ||
| 106 | catclose(catd); | ||
| 107 | #endif | ||
| 108 | |||
| 109 | return ret; | ||
| 110 | } | ||
| 111 | |||
| 112 | #define UPREFIX "Unknown error: " | ||
| 113 | |||
| 114 | int | ||
| 115 | strerror_r(int errnum, char *strerrbuf, size_t buflen) | ||
| 116 | { | ||
| 117 | int save_errno; | ||
| 118 | int ret_errno; | ||
| 119 | |||
| 120 | save_errno = errno; | ||
| 121 | |||
| 122 | ret_errno = __num2string(errnum, 1, 1, strerrbuf, buflen, | ||
| 123 | sys_errlist, sys_nerr, UPREFIX); | ||
| 124 | |||
| 125 | errno = ret_errno ? ret_errno : save_errno; | ||
| 126 | return (ret_errno); | ||
| 127 | } | ||
| 128 | |||
| 129 | #define USIGPREFIX "Unknown signal: " | ||
| 130 | |||
| 131 | char * | ||
| 132 | __strsignal(int num, char *buf) | ||
| 133 | { | ||
| 134 | __num2string(num, 0, 2, buf, NL_TEXTMAX, (char **)sys_siglist, NSIG, | ||
| 135 | USIGPREFIX); | ||
| 136 | return buf; | ||
| 137 | } | ||
diff --git a/src/lib/libc/string/strftime.3 b/src/lib/libc/string/strftime.3 deleted file mode 100644 index f14db4bb13..0000000000 --- a/src/lib/libc/string/strftime.3 +++ /dev/null | |||
| @@ -1,202 +0,0 @@ | |||
| 1 | .\" Copyright (c) 1989, 1991 The Regents of the University of California. | ||
| 2 | .\" All rights reserved. | ||
| 3 | .\" | ||
| 4 | .\" This code is derived from software contributed to Berkeley by | ||
| 5 | .\" the American National Standards Committee X3, on Information | ||
| 6 | .\" Processing Systems. | ||
| 7 | .\" | ||
| 8 | .\" Redistribution and use in source and binary forms, with or without | ||
| 9 | .\" modification, are permitted provided that the following conditions | ||
| 10 | .\" are met: | ||
| 11 | .\" 1. Redistributions of source code must retain the above copyright | ||
| 12 | .\" notice, this list of conditions and the following disclaimer. | ||
| 13 | .\" 2. Redistributions in binary form must reproduce the above copyright | ||
| 14 | .\" notice, this list of conditions and the following disclaimer in the | ||
| 15 | .\" documentation and/or other materials provided with the distribution. | ||
| 16 | .\" 3. All advertising materials mentioning features or use of this software | ||
| 17 | .\" must display the following acknowledgement: | ||
| 18 | .\" This product includes software developed by the University of | ||
| 19 | .\" California, Berkeley and its contributors. | ||
| 20 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 21 | .\" may be used to endorse or promote products derived from this software | ||
| 22 | .\" without specific prior written permission. | ||
| 23 | .\" | ||
| 24 | .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
| 25 | .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 26 | .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 27 | .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
| 28 | .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 29 | .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 30 | .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 31 | .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 32 | .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 33 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 34 | .\" SUCH DAMAGE. | ||
| 35 | .\" | ||
| 36 | .\" from: @(#)strftime.3 5.12 (Berkeley) 6/29/91 | ||
| 37 | .\" $Id: strftime.3,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $ | ||
| 38 | .\" | ||
| 39 | .Dd June 29, 1991 | ||
| 40 | .Dt STRFTIME 3 | ||
| 41 | .Os | ||
| 42 | .Sh NAME | ||
| 43 | .Nm strftime | ||
| 44 | .Nd format date and time | ||
| 45 | .Sh SYNOPSIS | ||
| 46 | .Fd #include <time.h> | ||
| 47 | .Ft size_t | ||
| 48 | .Fn strftime "char *buf" "size_t maxsize" "const char *format" "const struct tm *timeptr" | ||
| 49 | .Sh DESCRIPTION | ||
| 50 | The | ||
| 51 | .Fn strftime | ||
| 52 | function formats the information from | ||
| 53 | .Fa timeptr | ||
| 54 | into the buffer | ||
| 55 | .Fa buf | ||
| 56 | according to the string pointed to by | ||
| 57 | .Fa format . | ||
| 58 | .Pp | ||
| 59 | The | ||
| 60 | .Fa format | ||
| 61 | string consists of zero or more conversion specifications and | ||
| 62 | ordinary characters. | ||
| 63 | All ordinary characters are copied directly into the buffer. | ||
| 64 | A conversion specification consists of a percent sign | ||
| 65 | .Ql % | ||
| 66 | and one other character. | ||
| 67 | .Pp | ||
| 68 | No more than | ||
| 69 | .Fa maxsize | ||
| 70 | characters will be placed into the array. | ||
| 71 | If the total number of resulting characters, including the terminating | ||
| 72 | null character, is not more than | ||
| 73 | .Fa maxsize , | ||
| 74 | .Fn strftime | ||
| 75 | returns the number of characters in the array, not counting the | ||
| 76 | terminating null. | ||
| 77 | Otherwise, zero is returned. | ||
| 78 | .Pp | ||
| 79 | Each conversion specification is replaced by the characters as | ||
| 80 | follows which are then copied into the buffer. | ||
| 81 | .Bl -tag -width "xxxx" | ||
| 82 | .It Cm \&%A | ||
| 83 | is replaced by the locale's full weekday name. | ||
| 84 | .It Cm %a | ||
| 85 | is replaced by the locale's abbreviated weekday name. | ||
| 86 | .It Cm \&%B | ||
| 87 | is replaced by the locale's full month name. | ||
| 88 | .It Cm \&%b No or Cm \&%h | ||
| 89 | is replaced by the locale's abbreviated month name. | ||
| 90 | .It Cm \&%C | ||
| 91 | is replaced by the century (a year divided by 100 and truncated to an integer) | ||
| 92 | as a decimal number (00-99). | ||
| 93 | .It Cm \&%c | ||
| 94 | is replaced by the locale's appropriate date and time representation. | ||
| 95 | .It Cm \&%D | ||
| 96 | is replaced by the date in the format | ||
| 97 | .Dq Li %m/%d/%y . | ||
| 98 | .It Cm \&%d | ||
| 99 | is replaced by the day of the month as a decimal number (01-31). | ||
| 100 | .It Cm \&%e | ||
| 101 | is replaced by the day of month as a decimal number (1-31); | ||
| 102 | single digits are preceded by a blank. | ||
| 103 | .It Cm \&%H | ||
| 104 | is replaced by the hour (24-hour clock) as a decimal number (00-23). | ||
| 105 | .It Cm \&%I | ||
| 106 | is replaced by the hour (12-hour clock) as a decimal number (01-12). | ||
| 107 | .It Cm \&%j | ||
| 108 | is replaced by the day of the year as a decimal number (001-366). | ||
| 109 | .It Cm \&%k | ||
| 110 | is replaced by the hour (24-hour clock) as a decimal number (0-23); | ||
| 111 | single digits are preceded by a blank. | ||
| 112 | .It Cm \&%l | ||
| 113 | is replaced by the hour (12-hour clock) as a decimal number (1-12); | ||
| 114 | single digits are preceded by a blank. | ||
| 115 | .It Cm \&%M | ||
| 116 | is replaced by the minute as a decimal number (00-59). | ||
| 117 | .It Cm %m | ||
| 118 | is replaced by the month as a decimal number (01-12). | ||
| 119 | .It Cm %n | ||
| 120 | is replaced by a newline. | ||
| 121 | .It Cm %p | ||
| 122 | is replaced by the locale's equivalent of either | ||
| 123 | .Dq Tn AM | ||
| 124 | or | ||
| 125 | .Dq Tn PM . | ||
| 126 | .It Cm \&%R | ||
| 127 | is replaced by the time in the format | ||
| 128 | .Dq Li %H:%M . | ||
| 129 | .It Cm \&%r | ||
| 130 | is replaced by the locale's representation of 12-hour clock time | ||
| 131 | using AM/PM notation. | ||
| 132 | .It Cm \&%T | ||
| 133 | is replaced by the time in the format | ||
| 134 | .Dq Li %H:%M:%S . | ||
| 135 | .It Cm \&%t | ||
| 136 | is replaced by a tab. | ||
| 137 | .It Cm \&%S | ||
| 138 | is replaced by the second as a decimal number (00-60). | ||
| 139 | .It Cm %s | ||
| 140 | is replaced by the number of seconds since the Epoch, UCT (see | ||
| 141 | .Xr mktime 3 ) . | ||
| 142 | .It Cm \&%U | ||
| 143 | is replaced by the week number of the year (Sunday as the first day of | ||
| 144 | the week) as a decimal number (00-53). | ||
| 145 | .It Cm \&%u | ||
| 146 | is replaced by the weekday (Monday as the first day of the week) | ||
| 147 | as a decimal number (1-7). | ||
| 148 | .It Cm \&%V | ||
| 149 | is replaced by the week number of the year (Monday as the first day of | ||
| 150 | the week) as a decimal number (01-53). If the week containing January | ||
| 151 | 1 has four or more days in the new year, then it is week 1; otherwise | ||
| 152 | it is week 53 of the previous year, and the next week is week 1. | ||
| 153 | .It Cm \&%W | ||
| 154 | is replaced by the week number of the year (Monday as the first day of | ||
| 155 | the week) as a decimal number (00-53). | ||
| 156 | .It Cm \&%w | ||
| 157 | is replaced by the weekday (Sunday as the first day of the week) | ||
| 158 | as a decimal number (0-6). | ||
| 159 | .It Cm \&%X | ||
| 160 | is replaced by the locale's appropriate date representation. | ||
| 161 | .It Cm \&%x | ||
| 162 | is replaced by the locale's appropriate time representation. | ||
| 163 | .It Cm \&%Y | ||
| 164 | is replaced by the year with century as a decimal number. | ||
| 165 | .It Cm \&%y | ||
| 166 | is replaced by the year without century as a decimal number (00-99). | ||
| 167 | .It Cm \&%Z | ||
| 168 | is replaced by the time zone name. | ||
| 169 | .It Cm %% | ||
| 170 | is replaced by | ||
| 171 | .Ql % . | ||
| 172 | .El | ||
| 173 | .Sh SEE ALSO | ||
| 174 | .Xr date 1 , | ||
| 175 | .Xr ctime 3 , | ||
| 176 | .Xr printf 1 , | ||
| 177 | .Xr printf 3 | ||
| 178 | .Sh STANDARDS | ||
| 179 | The | ||
| 180 | .Fn strftime | ||
| 181 | function | ||
| 182 | conforms to | ||
| 183 | .St -ansiC . | ||
| 184 | The | ||
| 185 | .Ql \&%C , | ||
| 186 | .Ql \&%D , | ||
| 187 | .Ql \&%e , | ||
| 188 | .Ql \&%h , | ||
| 189 | .Ql \&%k , | ||
| 190 | .Ql \&%l , | ||
| 191 | .Ql \&%n , | ||
| 192 | .Ql \&%r , | ||
| 193 | .Ql \&%R , | ||
| 194 | .Ql \&%s . | ||
| 195 | .Ql \&%t , | ||
| 196 | .Ql \&%T , | ||
| 197 | .Ql \&%u , | ||
| 198 | and | ||
| 199 | .Ql \&%V | ||
| 200 | conversion specifications are extensions. | ||
| 201 | .Sh BUGS | ||
| 202 | There is no conversion specification for the phase of the moon. | ||
diff --git a/src/lib/libc/string/strftime.c b/src/lib/libc/string/strftime.c deleted file mode 100644 index fffa9ecbb0..0000000000 --- a/src/lib/libc/string/strftime.c +++ /dev/null | |||
| @@ -1,317 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1989 The Regents of the University of California. | ||
| 3 | * All rights reserved. | ||
| 4 | * | ||
| 5 | * Redistribution and use in source and binary forms, with or without | ||
| 6 | * modification, are permitted provided that the following conditions | ||
| 7 | * are met: | ||
| 8 | * 1. Redistributions of source code must retain the above copyright | ||
| 9 | * notice, this list of conditions and the following disclaimer. | ||
| 10 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer in the | ||
| 12 | * documentation and/or other materials provided with the distribution. | ||
| 13 | * 3. All advertising materials mentioning features or use of this software | ||
| 14 | * must display the following acknowledgement: | ||
| 15 | * This product includes software developed by the University of | ||
| 16 | * California, Berkeley and its contributors. | ||
| 17 | * 4. Neither the name of the University nor the names of its contributors | ||
| 18 | * may be used to endorse or promote products derived from this software | ||
| 19 | * without specific prior written permission. | ||
| 20 | * | ||
| 21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
| 22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
| 25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 31 | * SUCH DAMAGE. | ||
| 32 | */ | ||
| 33 | |||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 35 | /*static char *sccsid = "from: @(#)strftime.c 5.11 (Berkeley) 2/24/91";*/ | ||
| 36 | static char *rcsid = "$Id: strftime.c,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $"; | ||
| 37 | #endif /* LIBC_SCCS and not lint */ | ||
| 38 | |||
| 39 | #include <sys/localedef.h> | ||
| 40 | #include <locale.h> | ||
| 41 | #include <string.h> | ||
| 42 | #include <tzfile.h> | ||
| 43 | #include <time.h> | ||
| 44 | |||
| 45 | static size_t gsize; | ||
| 46 | static char *pt; | ||
| 47 | static int _add(), _conv(), _secs(); | ||
| 48 | static size_t _fmt(); | ||
| 49 | |||
| 50 | size_t | ||
| 51 | strftime(s, maxsize, format, t) | ||
| 52 | char *s; | ||
| 53 | size_t maxsize; | ||
| 54 | const char *format; | ||
| 55 | const struct tm *t; | ||
| 56 | { | ||
| 57 | tzset(); | ||
| 58 | |||
| 59 | pt = s; | ||
| 60 | if ((gsize = maxsize) < 1) | ||
| 61 | return(0); | ||
| 62 | if (_fmt(format, t)) { | ||
| 63 | *pt = '\0'; | ||
| 64 | return(maxsize - gsize); | ||
| 65 | } | ||
| 66 | return(0); | ||
| 67 | } | ||
| 68 | |||
| 69 | #define SUN_WEEK(t) (((t)->tm_yday + 7 - \ | ||
| 70 | ((t)->tm_wday)) / 7) | ||
| 71 | #define MON_WEEK(t) (((t)->tm_yday + 7 - \ | ||
| 72 | ((t)->tm_wday ? (t)->tm_wday - 1 : 6)) / 7) | ||
| 73 | static size_t | ||
| 74 | _fmt(format, t) | ||
| 75 | register char *format; | ||
| 76 | struct tm *t; | ||
| 77 | { | ||
| 78 | for (; *format; ++format) { | ||
| 79 | if (*format == '%') { | ||
| 80 | ++format; | ||
| 81 | if (*format == 'E') { | ||
| 82 | /* Alternate Era */ | ||
| 83 | ++format; | ||
| 84 | } else if (*format == 'O') { | ||
| 85 | /* Alternate numeric symbols */ | ||
| 86 | ++format; | ||
| 87 | } | ||
| 88 | switch(*format) { | ||
| 89 | case '\0': | ||
| 90 | --format; | ||
| 91 | break; | ||
| 92 | case 'A': | ||
| 93 | if (t->tm_wday < 0 || t->tm_wday > 6) | ||
| 94 | return(0); | ||
| 95 | if (!_add(_CurrentTimeLocale->day[t->tm_wday])) | ||
| 96 | return(0); | ||
| 97 | continue; | ||
| 98 | case 'a': | ||
| 99 | if (t->tm_wday < 0 || t->tm_wday > 6) | ||
| 100 | return(0); | ||
| 101 | if (!_add(_CurrentTimeLocale->abday[t->tm_wday])) | ||
| 102 | return(0); | ||
| 103 | continue; | ||
| 104 | case 'B': | ||
| 105 | if (t->tm_mon < 0 || t->tm_mon > 11) | ||
| 106 | return(0); | ||
| 107 | if (!_add(_CurrentTimeLocale->mon[t->tm_mon])) | ||
| 108 | return(0); | ||
| 109 | continue; | ||
| 110 | case 'b': | ||
| 111 | case 'h': | ||
| 112 | if (t->tm_mon < 0 || t->tm_mon > 11) | ||
| 113 | return(0); | ||
| 114 | if (!_add(_CurrentTimeLocale->abmon[t->tm_mon])) | ||
| 115 | return(0); | ||
| 116 | continue; | ||
| 117 | case 'C': | ||
| 118 | if (!_conv((t->tm_year + TM_YEAR_BASE) / 100, | ||
| 119 | 2, '0')) | ||
| 120 | return(0); | ||
| 121 | continue; | ||
| 122 | case 'c': | ||
| 123 | if (!_fmt(_CurrentTimeLocale->d_t_fmt, t)) | ||
| 124 | return(0); | ||
| 125 | continue; | ||
| 126 | case 'D': | ||
| 127 | if (!_fmt("%m/%d/%y", t)) | ||
| 128 | return(0); | ||
| 129 | continue; | ||
| 130 | case 'd': | ||
| 131 | if (!_conv(t->tm_mday, 2, '0')) | ||
| 132 | return(0); | ||
| 133 | continue; | ||
| 134 | case 'e': | ||
| 135 | if (!_conv(t->tm_mday, 2, ' ')) | ||
| 136 | return(0); | ||
| 137 | continue; | ||
| 138 | case 'H': | ||
| 139 | if (!_conv(t->tm_hour, 2, '0')) | ||
| 140 | return(0); | ||
| 141 | continue; | ||
| 142 | case 'I': | ||
| 143 | if (!_conv(t->tm_hour % 12 ? | ||
| 144 | t->tm_hour % 12 : 12, 2, '0')) | ||
| 145 | return(0); | ||
| 146 | continue; | ||
| 147 | case 'j': | ||
| 148 | if (!_conv(t->tm_yday + 1, 3, '0')) | ||
| 149 | return(0); | ||
| 150 | continue; | ||
| 151 | case 'k': | ||
| 152 | if (!_conv(t->tm_hour, 2, ' ')) | ||
| 153 | return(0); | ||
| 154 | continue; | ||
| 155 | case 'l': | ||
| 156 | if (!_conv(t->tm_hour % 12 ? | ||
| 157 | t->tm_hour % 12: 12, 2, ' ')) | ||
| 158 | return(0); | ||
| 159 | continue; | ||
| 160 | case 'M': | ||
| 161 | if (!_conv(t->tm_min, 2, '0')) | ||
| 162 | return(0); | ||
| 163 | continue; | ||
| 164 | case 'm': | ||
| 165 | if (!_conv(t->tm_mon + 1, 2, '0')) | ||
| 166 | return(0); | ||
| 167 | continue; | ||
| 168 | case 'n': | ||
| 169 | if (!_add("\n")) | ||
| 170 | return(0); | ||
| 171 | continue; | ||
| 172 | case 'p': | ||
| 173 | if (!_add(_CurrentTimeLocale->am_pm[t->tm_hour >= 12])) | ||
| 174 | return(0); | ||
| 175 | continue; | ||
| 176 | case 'R': | ||
| 177 | if (!_fmt("%H:%M", t)) | ||
| 178 | return(0); | ||
| 179 | continue; | ||
| 180 | case 'r': | ||
| 181 | if (!_fmt(_CurrentTimeLocale->t_fmt_ampm, t)) | ||
| 182 | return(0); | ||
| 183 | continue; | ||
| 184 | case 'S': | ||
| 185 | if (!_conv(t->tm_sec, 2, '0')) | ||
| 186 | return(0); | ||
| 187 | continue; | ||
| 188 | case 's': | ||
| 189 | if (!_secs(t)) | ||
| 190 | return(0); | ||
| 191 | continue; | ||
| 192 | case 'T': | ||
| 193 | if (!_fmt("%H:%M:%S", t)) | ||
| 194 | return(0); | ||
| 195 | continue; | ||
| 196 | case 't': | ||
| 197 | if (!_add("\t")) | ||
| 198 | return(0); | ||
| 199 | continue; | ||
| 200 | case 'U': | ||
| 201 | if (!_conv(SUN_WEEK(t), 2, '0')) | ||
| 202 | return(0); | ||
| 203 | continue; | ||
| 204 | case 'u': | ||
| 205 | if (!_conv(t->tm_wday ? t->tm_wday : 7, 2, '0')) | ||
| 206 | return(0); | ||
| 207 | continue; | ||
| 208 | case 'V': | ||
| 209 | { | ||
| 210 | /* ISO 8601 Week Of Year: | ||
| 211 | If the week (Monday - Sunday) containing | ||
| 212 | January 1 has four or more days in the new | ||
| 213 | year, then it is week 1; otherwise it is | ||
| 214 | week 53 of the previous year and the next | ||
| 215 | week is week one. */ | ||
| 216 | |||
| 217 | int week = MON_WEEK(t); | ||
| 218 | |||
| 219 | if (((t->tm_yday + 7 - (t->tm_wday + 1)) % 7) >= 4) { | ||
| 220 | week++; | ||
| 221 | } else if (week == 0) { | ||
| 222 | week = 53; | ||
| 223 | } | ||
| 224 | |||
| 225 | if (!_conv(week, 2, '0')) | ||
| 226 | return(0); | ||
| 227 | continue; | ||
| 228 | } | ||
| 229 | case 'W': | ||
| 230 | if (!_conv(MON_WEEK(t), 2, '0')) | ||
| 231 | return(0); | ||
| 232 | continue; | ||
| 233 | case 'w': | ||
| 234 | if (!_conv(t->tm_wday, 1, '0')) | ||
| 235 | return(0); | ||
| 236 | continue; | ||
| 237 | case 'x': | ||
| 238 | if (!_fmt(_CurrentTimeLocale->d_fmt, t)) | ||
| 239 | return(0); | ||
| 240 | continue; | ||
| 241 | case 'X': | ||
| 242 | if (!_fmt(_CurrentTimeLocale->t_fmt, t)) | ||
| 243 | return(0); | ||
| 244 | continue; | ||
| 245 | case 'y': | ||
| 246 | if (!_conv((t->tm_year + TM_YEAR_BASE) % 100, | ||
| 247 | 2, '0')) | ||
| 248 | return(0); | ||
| 249 | continue; | ||
| 250 | case 'Y': | ||
| 251 | if (!_conv((t->tm_year + TM_YEAR_BASE), 4, '0')) | ||
| 252 | return(0); | ||
| 253 | continue; | ||
| 254 | case 'Z': | ||
| 255 | if (t->tm_zone && !_add(t->tm_zone)) | ||
| 256 | return(0); | ||
| 257 | continue; | ||
| 258 | case '%': | ||
| 259 | /* | ||
| 260 | * X311J/88-090 (4.12.3.5): if conversion char is | ||
| 261 | * undefined, behavior is undefined. Print out the | ||
| 262 | * character itself as printf(3) does. | ||
| 263 | */ | ||
| 264 | default: | ||
| 265 | break; | ||
| 266 | } | ||
| 267 | } | ||
| 268 | if (!gsize--) | ||
| 269 | return(0); | ||
| 270 | *pt++ = *format; | ||
| 271 | } | ||
| 272 | return(gsize); | ||
| 273 | } | ||
| 274 | |||
| 275 | static | ||
| 276 | _secs(t) | ||
| 277 | struct tm *t; | ||
| 278 | { | ||
| 279 | static char buf[15]; | ||
| 280 | register time_t s; | ||
| 281 | register char *p; | ||
| 282 | struct tm tmp; | ||
| 283 | |||
| 284 | /* Make a copy, mktime(3) modifies the tm struct. */ | ||
| 285 | tmp = *t; | ||
| 286 | s = mktime(&tmp); | ||
| 287 | for (p = buf + sizeof(buf) - 2; s > 0 && p > buf; s /= 10) | ||
| 288 | *p-- = s % 10 + '0'; | ||
| 289 | return(_add(++p)); | ||
| 290 | } | ||
| 291 | |||
| 292 | static | ||
| 293 | _conv(n, digits, pad) | ||
| 294 | int n, digits; | ||
| 295 | char pad; | ||
| 296 | { | ||
| 297 | static char buf[10]; | ||
| 298 | register char *p; | ||
| 299 | |||
| 300 | for (p = buf + sizeof(buf) - 2; n > 0 && p > buf; n /= 10, --digits) | ||
| 301 | *p-- = n % 10 + '0'; | ||
| 302 | while (p > buf && digits-- > 0) | ||
| 303 | *p-- = pad; | ||
| 304 | return(_add(++p)); | ||
| 305 | } | ||
| 306 | |||
| 307 | static | ||
| 308 | _add(str) | ||
| 309 | register char *str; | ||
| 310 | { | ||
| 311 | for (;; ++pt, --gsize) { | ||
| 312 | if (!gsize) | ||
| 313 | return(0); | ||
| 314 | if (!(*pt = *str++)) | ||
| 315 | return(1); | ||
| 316 | } | ||
| 317 | } | ||
diff --git a/src/lib/libc/string/string.3 b/src/lib/libc/string/string.3 index aaf97e0321..2373d1fb9c 100644 --- a/src/lib/libc/string/string.3 +++ b/src/lib/libc/string/string.3 | |||
| @@ -11,11 +11,7 @@ | |||
| 11 | .\" 2. Redistributions in binary form must reproduce the above copyright | 11 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 12 | .\" notice, this list of conditions and the following disclaimer in the | 12 | .\" notice, this list of conditions and the following disclaimer in the |
| 13 | .\" documentation and/or other materials provided with the distribution. | 13 | .\" documentation and/or other materials provided with the distribution. |
| 14 | .\" 3. All advertising materials mentioning features or use of this software | 14 | .\" 3. Neither the name of the University nor the names of its contributors |
| 15 | .\" must display the following acknowledgement: | ||
| 16 | .\" This product includes software developed by the University of | ||
| 17 | .\" California, Berkeley and its contributors. | ||
| 18 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 19 | .\" may be used to endorse or promote products derived from this software | 15 | .\" may be used to endorse or promote products derived from this software |
| 20 | .\" without specific prior written permission. | 16 | .\" without specific prior written permission. |
| 21 | .\" | 17 | .\" |
| @@ -31,38 +27,20 @@ | |||
| 31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 27 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 32 | .\" SUCH DAMAGE. | 28 | .\" SUCH DAMAGE. |
| 33 | .\" | 29 | .\" |
| 34 | .\" from: @(#)string.3 6.9 (Berkeley) 4/19/91 | 30 | .\" $OpenBSD: string.3,v 1.13 2013/06/05 03:39:23 tedu Exp $ |
| 35 | .\" $Id: string.3,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $ | ||
| 36 | .\" | 31 | .\" |
| 37 | .Dd April 19, 1991 | 32 | .Dd $Mdocdate: June 5 2013 $ |
| 38 | .Dt STRING 3 | 33 | .Dt STRING 3 |
| 39 | .Os BSD 4 | 34 | .Os |
| 40 | .Sh NAME | 35 | .Sh NAME |
| 41 | .Nm strcat , | 36 | .Nm string |
| 42 | .Nm strncat , | ||
| 43 | .Nm strchr , | ||
| 44 | .Nm strrchr , | ||
| 45 | .Nm strcmp , | ||
| 46 | .Nm strncmp , | ||
| 47 | .Nm strcasecmp, | ||
| 48 | .Nm strncasecmp , | ||
| 49 | .Nm strcpy , | ||
| 50 | .Nm strncpy , | ||
| 51 | .Nm strerror , | ||
| 52 | .Nm strlen , | ||
| 53 | .Nm strpbrk , | ||
| 54 | .Nm strsep, | ||
| 55 | .Nm strspn , | ||
| 56 | .Nm strcspn , | ||
| 57 | .Nm strstr , | ||
| 58 | .Nm strtok , | ||
| 59 | .Nm index , | ||
| 60 | .Nm rindex | ||
| 61 | .Nd string specific functions | 37 | .Nd string specific functions |
| 62 | .Sh SYNOPSIS | 38 | .Sh SYNOPSIS |
| 63 | .Fd #include <string.h> | 39 | .In string.h |
| 64 | .Ft char * | 40 | .Ft char * |
| 65 | .Fn strcat "char *s" "const char * append" | 41 | .Fn strcat "char *s" "const char *append" |
| 42 | .Ft char * | ||
| 43 | .Fn strlcat "char *s" "const char *append" "size_t size" | ||
| 66 | .Ft char * | 44 | .Ft char * |
| 67 | .Fn strncat "char *s" "const char *append" "size_t count" | 45 | .Fn strncat "char *s" "const char *append" "size_t count" |
| 68 | .Ft char * | 46 | .Ft char * |
| @@ -80,6 +58,8 @@ | |||
| 80 | .Ft char * | 58 | .Ft char * |
| 81 | .Fn strcpy "char *dst" "const char *src" | 59 | .Fn strcpy "char *dst" "const char *src" |
| 82 | .Ft char * | 60 | .Ft char * |
| 61 | .Fn strlcpy "char *dst" "const char *src" "size_t size" | ||
| 62 | .Ft char * | ||
| 83 | .Fn strncpy "char *dst" "const char *src" "size_t count" | 63 | .Fn strncpy "char *dst" "const char *src" "size_t count" |
| 84 | .Ft char * | 64 | .Ft char * |
| 85 | .Fn strerror "int errno" | 65 | .Fn strerror "int errno" |
| @@ -103,35 +83,37 @@ | |||
| 103 | .Fn rindex "const char *s" "int c" | 83 | .Fn rindex "const char *s" "int c" |
| 104 | .Sh DESCRIPTION | 84 | .Sh DESCRIPTION |
| 105 | The string functions | 85 | The string functions |
| 106 | functions manipulate strings terminated by a | 86 | manipulate strings terminated by a |
| 107 | null byte. | 87 | NUL byte. |
| 108 | .Pp | 88 | .Pp |
| 109 | See the specific manual pages for more information. | 89 | See the specific manual pages for more information. |
| 110 | For manipulating variable length generic objects as byte | 90 | For manipulating variable length generic objects as byte |
| 111 | strings (without the null byte check), see | 91 | strings (without the NUL-byte check), see |
| 112 | .Xr bstring 3 . | 92 | .Xr bstring 3 . |
| 113 | .Pp | 93 | .Pp |
| 114 | Except as noted in their specific manual pages, | 94 | Except as noted in their specific manual pages, |
| 115 | the string functions do not test the destination | 95 | the string functions do not test the destination |
| 116 | for size limitations. | 96 | for size limitations. |
| 117 | .Sh SEE ALSO | 97 | .Sh SEE ALSO |
| 98 | .Xr bstring 3 , | ||
| 118 | .Xr index 3 , | 99 | .Xr index 3 , |
| 100 | .Xr rindex 3 , | ||
| 101 | .Xr strcasecmp 3 , | ||
| 119 | .Xr strcat 3 , | 102 | .Xr strcat 3 , |
| 120 | .Xr strchr 3 , | 103 | .Xr strchr 3 , |
| 121 | .Xr strrchr 3 , | ||
| 122 | .Xr strcmp 3 , | 104 | .Xr strcmp 3 , |
| 123 | .Xr strcasecmp 3 , | ||
| 124 | .Xr strcpy 3 , | 105 | .Xr strcpy 3 , |
| 106 | .Xr strcspn 3 , | ||
| 125 | .Xr strerror 3 , | 107 | .Xr strerror 3 , |
| 108 | .Xr strlcat 3 , | ||
| 109 | .Xr strlcpy 3 , | ||
| 126 | .Xr strlen 3 , | 110 | .Xr strlen 3 , |
| 127 | .Xr strpbrk 3 , | 111 | .Xr strpbrk 3 , |
| 112 | .Xr strrchr 3 , | ||
| 128 | .Xr strsep 3 , | 113 | .Xr strsep 3 , |
| 129 | .Xr strspn 3 , | 114 | .Xr strspn 3 , |
| 130 | .Xr strcspn 3 , | ||
| 131 | .Xr strstr 3 , | 115 | .Xr strstr 3 , |
| 132 | .Xr strtok 3 , | 116 | .Xr strtok 3 |
| 133 | .Xr rindex 3 | ||
| 134 | .Xr bstring 3 | ||
| 135 | .Sh STANDARDS | 117 | .Sh STANDARDS |
| 136 | The | 118 | The |
| 137 | .Fn strcat , | 119 | .Fn strcat , |
| @@ -145,12 +127,10 @@ The | |||
| 145 | .Fn strerror , | 127 | .Fn strerror , |
| 146 | .Fn strlen , | 128 | .Fn strlen , |
| 147 | .Fn strpbrk , | 129 | .Fn strpbrk , |
| 148 | .Fn strsep , | ||
| 149 | .Fn strspn , | 130 | .Fn strspn , |
| 150 | .Fn strcspn , | 131 | .Fn strcspn , |
| 151 | .Fn strstr , | 132 | .Fn strstr , |
| 152 | and | 133 | and |
| 153 | .Fn strtok | 134 | .Fn strtok |
| 154 | functions | 135 | functions conform to |
| 155 | conform to | ||
| 156 | .St -ansiC . | 136 | .St -ansiC . |
diff --git a/src/lib/libc/string/strlcat.c b/src/lib/libc/string/strlcat.c new file mode 100644 index 0000000000..ceab094411 --- /dev/null +++ b/src/lib/libc/string/strlcat.c | |||
| @@ -0,0 +1,55 @@ | |||
| 1 | /* $OpenBSD: strlcat.c,v 1.13 2005/08/08 08:05:37 espie Exp $ */ | ||
| 2 | |||
| 3 | /* | ||
| 4 | * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> | ||
| 5 | * | ||
| 6 | * Permission to use, copy, modify, and distribute this software for any | ||
| 7 | * purpose with or without fee is hereby granted, provided that the above | ||
| 8 | * copyright notice and this permission notice appear in all copies. | ||
| 9 | * | ||
| 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <sys/types.h> | ||
| 20 | #include <string.h> | ||
| 21 | |||
| 22 | /* | ||
| 23 | * Appends src to string dst of size siz (unlike strncat, siz is the | ||
| 24 | * full size of dst, not space left). At most siz-1 characters | ||
| 25 | * will be copied. Always NUL terminates (unless siz <= strlen(dst)). | ||
| 26 | * Returns strlen(src) + MIN(siz, strlen(initial dst)). | ||
| 27 | * If retval >= siz, truncation occurred. | ||
| 28 | */ | ||
| 29 | size_t | ||
| 30 | strlcat(char *dst, const char *src, size_t siz) | ||
| 31 | { | ||
| 32 | char *d = dst; | ||
| 33 | const char *s = src; | ||
| 34 | size_t n = siz; | ||
| 35 | size_t dlen; | ||
| 36 | |||
| 37 | /* Find the end of dst and adjust bytes left but don't go past end */ | ||
| 38 | while (n-- != 0 && *d != '\0') | ||
| 39 | d++; | ||
| 40 | dlen = d - dst; | ||
| 41 | n = siz - dlen; | ||
| 42 | |||
| 43 | if (n == 0) | ||
| 44 | return(dlen + strlen(s)); | ||
| 45 | while (*s != '\0') { | ||
| 46 | if (n != 1) { | ||
| 47 | *d++ = *s; | ||
| 48 | n--; | ||
| 49 | } | ||
| 50 | s++; | ||
| 51 | } | ||
| 52 | *d = '\0'; | ||
| 53 | |||
| 54 | return(dlen + (s - src)); /* count does not include NUL */ | ||
| 55 | } | ||
diff --git a/src/lib/libc/string/strlcpy.3 b/src/lib/libc/string/strlcpy.3 new file mode 100644 index 0000000000..044c959c0c --- /dev/null +++ b/src/lib/libc/string/strlcpy.3 | |||
| @@ -0,0 +1,188 @@ | |||
| 1 | .\" $OpenBSD: strlcpy.3,v 1.26 2013/09/30 12:02:35 millert Exp $ | ||
| 2 | .\" | ||
| 3 | .\" Copyright (c) 1998, 2000 Todd C. Miller <Todd.Miller@courtesan.com> | ||
| 4 | .\" | ||
| 5 | .\" Permission to use, copy, modify, and distribute this software for any | ||
| 6 | .\" purpose with or without fee is hereby granted, provided that the above | ||
| 7 | .\" copyright notice and this permission notice appear in all copies. | ||
| 8 | .\" | ||
| 9 | .\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 10 | .\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 11 | .\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 12 | .\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 13 | .\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 14 | .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 15 | .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 16 | .\" | ||
| 17 | .Dd $Mdocdate: September 30 2013 $ | ||
| 18 | .Dt STRLCPY 3 | ||
| 19 | .Os | ||
| 20 | .Sh NAME | ||
| 21 | .Nm strlcpy , | ||
| 22 | .Nm strlcat | ||
| 23 | .Nd size-bounded string copying and concatenation | ||
| 24 | .Sh SYNOPSIS | ||
| 25 | .In string.h | ||
| 26 | .Ft size_t | ||
| 27 | .Fn strlcpy "char *dst" "const char *src" "size_t dstsize" | ||
| 28 | .Ft size_t | ||
| 29 | .Fn strlcat "char *dst" "const char *src" "size_t dstsize" | ||
| 30 | .Sh DESCRIPTION | ||
| 31 | The | ||
| 32 | .Fn strlcpy | ||
| 33 | and | ||
| 34 | .Fn strlcat | ||
| 35 | functions copy and concatenate strings with the | ||
| 36 | same input parameters and output result as | ||
| 37 | .Xr snprintf 3 . | ||
| 38 | They are designed to be safer, more consistent, and less error | ||
| 39 | prone replacements for the easily misused functions | ||
| 40 | .Xr strncpy 3 | ||
| 41 | and | ||
| 42 | .Xr strncat 3 . | ||
| 43 | .Pp | ||
| 44 | .Fn strlcpy | ||
| 45 | and | ||
| 46 | .Fn strlcat | ||
| 47 | take the full size of the destination buffer and guarantee | ||
| 48 | NUL-termination if there is room. | ||
| 49 | Note that room for the NUL should be included in | ||
| 50 | .Fa dstsize . | ||
| 51 | .Pp | ||
| 52 | .Fn strlcpy | ||
| 53 | copies up to | ||
| 54 | .Fa dstsize | ||
| 55 | \- 1 characters from the string | ||
| 56 | .Fa src | ||
| 57 | to | ||
| 58 | .Fa dst , | ||
| 59 | NUL-terminating the result if | ||
| 60 | .Fa dstsize | ||
| 61 | is not 0. | ||
| 62 | .Pp | ||
| 63 | .Fn strlcat | ||
| 64 | appends string | ||
| 65 | .Fa src | ||
| 66 | to the end of | ||
| 67 | .Fa dst . | ||
| 68 | It will append at most | ||
| 69 | .Fa dstsize | ||
| 70 | \- strlen(dst) \- 1 characters. | ||
| 71 | It will then NUL-terminate, unless | ||
| 72 | .Fa dstsize | ||
| 73 | is 0 or the original | ||
| 74 | .Fa dst | ||
| 75 | string was longer than | ||
| 76 | .Fa dstsize | ||
| 77 | (in practice this should not happen | ||
| 78 | as it means that either | ||
| 79 | .Fa dstsize | ||
| 80 | is incorrect or that | ||
| 81 | .Fa dst | ||
| 82 | is not a proper string). | ||
| 83 | .Pp | ||
| 84 | If the | ||
| 85 | .Fa src | ||
| 86 | and | ||
| 87 | .Fa dst | ||
| 88 | strings overlap, the behavior is undefined. | ||
| 89 | .Sh RETURN VALUES | ||
| 90 | Besides quibbles over the return type | ||
| 91 | .Pf ( Va size_t | ||
| 92 | versus | ||
| 93 | .Va int ) | ||
| 94 | and signal handler safety | ||
| 95 | .Pf ( Xr snprintf 3 | ||
| 96 | is not entirely safe on some systems), the | ||
| 97 | following two are equivalent: | ||
| 98 | .Bd -literal -offset indent | ||
| 99 | n = strlcpy(dst, src, len); | ||
| 100 | n = snprintf(dst, len, "%s", src); | ||
| 101 | .Ed | ||
| 102 | .Pp | ||
| 103 | Like | ||
| 104 | .Xr snprintf 3 , | ||
| 105 | the | ||
| 106 | .Fn strlcpy | ||
| 107 | and | ||
| 108 | .Fn strlcat | ||
| 109 | functions return the total length of the string they tried to create. | ||
| 110 | For | ||
| 111 | .Fn strlcpy | ||
| 112 | that means the length of | ||
| 113 | .Fa src . | ||
| 114 | For | ||
| 115 | .Fn strlcat | ||
| 116 | that means the initial length of | ||
| 117 | .Fa dst | ||
| 118 | plus | ||
| 119 | the length of | ||
| 120 | .Fa src . | ||
| 121 | .Pp | ||
| 122 | If the return value is | ||
| 123 | .Cm >= | ||
| 124 | .Va dstsize , | ||
| 125 | the output string has been truncated. | ||
| 126 | It is the caller's responsibility to handle this. | ||
| 127 | .Sh EXAMPLES | ||
| 128 | The following code fragment illustrates the simple case: | ||
| 129 | .Bd -literal -offset indent | ||
| 130 | char *s, *p, buf[BUFSIZ]; | ||
| 131 | |||
| 132 | \&... | ||
| 133 | |||
| 134 | (void)strlcpy(buf, s, sizeof(buf)); | ||
| 135 | (void)strlcat(buf, p, sizeof(buf)); | ||
| 136 | .Ed | ||
| 137 | .Pp | ||
| 138 | To detect truncation, perhaps while building a pathname, something | ||
| 139 | like the following might be used: | ||
| 140 | .Bd -literal -offset indent | ||
| 141 | char *dir, *file, pname[PATH_MAX]; | ||
| 142 | |||
| 143 | \&... | ||
| 144 | |||
| 145 | if (strlcpy(pname, dir, sizeof(pname)) >= sizeof(pname)) | ||
| 146 | goto toolong; | ||
| 147 | if (strlcat(pname, file, sizeof(pname)) >= sizeof(pname)) | ||
| 148 | goto toolong; | ||
| 149 | .Ed | ||
| 150 | .Pp | ||
| 151 | Since it is known how many characters were copied the first time, things | ||
| 152 | can be sped up a bit by using a copy instead of an append: | ||
| 153 | .Bd -literal -offset indent | ||
| 154 | char *dir, *file, pname[PATH_MAX]; | ||
| 155 | size_t n; | ||
| 156 | |||
| 157 | \&... | ||
| 158 | |||
| 159 | n = strlcpy(pname, dir, sizeof(pname)); | ||
| 160 | if (n >= sizeof(pname)) | ||
| 161 | goto toolong; | ||
| 162 | if (strlcpy(pname + n, file, sizeof(pname) - n) >= sizeof(pname) - n) | ||
| 163 | goto toolong; | ||
| 164 | .Ed | ||
| 165 | .Pp | ||
| 166 | However, one may question the validity of such optimizations, as they | ||
| 167 | defeat the whole purpose of | ||
| 168 | .Fn strlcpy | ||
| 169 | and | ||
| 170 | .Fn strlcat . | ||
| 171 | As a matter of fact, the first version of this manual page got it wrong. | ||
| 172 | .Sh SEE ALSO | ||
| 173 | .Xr snprintf 3 , | ||
| 174 | .Xr strncat 3 , | ||
| 175 | .Xr strncpy 3 , | ||
| 176 | .Xr wcslcpy 3 | ||
| 177 | .Sh HISTORY | ||
| 178 | .Fn strlcpy | ||
| 179 | and | ||
| 180 | .Fn strlcat | ||
| 181 | first appeared in | ||
| 182 | .Ox 2.4 . | ||
| 183 | .Sh AUTHORS | ||
| 184 | .Fn strlcpy | ||
| 185 | and | ||
| 186 | .Fn strlcat | ||
| 187 | were created by | ||
| 188 | .An Todd C. Miller Aq Mt Todd.Miller@courtesan.com . | ||
diff --git a/src/lib/libc/string/strlcpy.c b/src/lib/libc/string/strlcpy.c new file mode 100644 index 0000000000..d32b6590f1 --- /dev/null +++ b/src/lib/libc/string/strlcpy.c | |||
| @@ -0,0 +1,51 @@ | |||
| 1 | /* $OpenBSD: strlcpy.c,v 1.11 2006/05/05 15:27:38 millert Exp $ */ | ||
| 2 | |||
| 3 | /* | ||
| 4 | * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> | ||
| 5 | * | ||
| 6 | * Permission to use, copy, modify, and distribute this software for any | ||
| 7 | * purpose with or without fee is hereby granted, provided that the above | ||
| 8 | * copyright notice and this permission notice appear in all copies. | ||
| 9 | * | ||
| 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <sys/types.h> | ||
| 20 | #include <string.h> | ||
| 21 | |||
| 22 | /* | ||
| 23 | * Copy src to string dst of size siz. At most siz-1 characters | ||
| 24 | * will be copied. Always NUL terminates (unless siz == 0). | ||
| 25 | * Returns strlen(src); if retval >= siz, truncation occurred. | ||
| 26 | */ | ||
| 27 | size_t | ||
| 28 | strlcpy(char *dst, const char *src, size_t siz) | ||
| 29 | { | ||
| 30 | char *d = dst; | ||
| 31 | const char *s = src; | ||
| 32 | size_t n = siz; | ||
| 33 | |||
| 34 | /* Copy as many bytes as will fit */ | ||
| 35 | if (n != 0) { | ||
| 36 | while (--n != 0) { | ||
| 37 | if ((*d++ = *s++) == '\0') | ||
| 38 | break; | ||
| 39 | } | ||
| 40 | } | ||
| 41 | |||
| 42 | /* Not enough room in dst, add NUL and traverse rest of src */ | ||
| 43 | if (n == 0) { | ||
| 44 | if (siz != 0) | ||
| 45 | *d = '\0'; /* NUL-terminate dst */ | ||
| 46 | while (*s++) | ||
| 47 | ; | ||
| 48 | } | ||
| 49 | |||
| 50 | return(s - src - 1); /* count does not include NUL */ | ||
| 51 | } | ||
diff --git a/src/lib/libc/string/strlen.3 b/src/lib/libc/string/strlen.3 index f4aff363ee..5428627abb 100644 --- a/src/lib/libc/string/strlen.3 +++ b/src/lib/libc/string/strlen.3 | |||
| @@ -1,3 +1,5 @@ | |||
| 1 | .\" $OpenBSD: strlen.3,v 1.12 2013/07/17 05:42:11 schwarze Exp $ | ||
| 2 | .\" | ||
| 1 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. | 3 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. |
| 2 | .\" All rights reserved. | 4 | .\" All rights reserved. |
| 3 | .\" | 5 | .\" |
| @@ -13,11 +15,7 @@ | |||
| 13 | .\" 2. Redistributions in binary form must reproduce the above copyright | 15 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 14 | .\" notice, this list of conditions and the following disclaimer in the | 16 | .\" notice, this list of conditions and the following disclaimer in the |
| 15 | .\" documentation and/or other materials provided with the distribution. | 17 | .\" documentation and/or other materials provided with the distribution. |
| 16 | .\" 3. All advertising materials mentioning features or use of this software | 18 | .\" 3. Neither the name of the University nor the names of its contributors |
| 17 | .\" must display the following acknowledgement: | ||
| 18 | .\" This product includes software developed by the University of | ||
| 19 | .\" California, Berkeley and its contributors. | ||
| 20 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 21 | .\" may be used to endorse or promote products derived from this software | 19 | .\" may be used to endorse or promote products derived from this software |
| 22 | .\" without specific prior written permission. | 20 | .\" without specific prior written permission. |
| 23 | .\" | 21 | .\" |
| @@ -33,39 +31,75 @@ | |||
| 33 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 34 | .\" SUCH DAMAGE. | 32 | .\" SUCH DAMAGE. |
| 35 | .\" | 33 | .\" |
| 36 | .\" from: @(#)strlen.3 5.4 (Berkeley) 6/29/91 | 34 | .Dd $Mdocdate: July 17 2013 $ |
| 37 | .\" $Id: strlen.3,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $ | ||
| 38 | .\" | ||
| 39 | .Dd June 29, 1991 | ||
| 40 | .Dt STRLEN 3 | 35 | .Dt STRLEN 3 |
| 41 | .Os | 36 | .Os |
| 42 | .Sh NAME | 37 | .Sh NAME |
| 43 | .Nm strlen | 38 | .Nm strlen , |
| 44 | .Nd find length of string | 39 | .Nm strnlen |
| 40 | .Nd find length of a string | ||
| 45 | .Sh SYNOPSIS | 41 | .Sh SYNOPSIS |
| 46 | .Fd #include <string.h> | 42 | .In string.h |
| 47 | .Ft size_t | 43 | .Ft size_t |
| 48 | .Fn strlen "const char *s" | 44 | .Fn strlen "const char *s" |
| 45 | .Ft size_t | ||
| 46 | .Fn strnlen "const char *s" "size_t maxlen" | ||
| 49 | .Sh DESCRIPTION | 47 | .Sh DESCRIPTION |
| 50 | The | 48 | The |
| 51 | .Fn strlen | 49 | .Fn strlen |
| 52 | function | 50 | function computes the length of the string |
| 53 | computes the length of the string | ||
| 54 | .Fa s . | 51 | .Fa s . |
| 52 | .Pp | ||
| 53 | The | ||
| 54 | .Fn strnlen | ||
| 55 | function computes the length of the string | ||
| 56 | .Fa s , | ||
| 57 | up to | ||
| 58 | .Fa maxlen | ||
| 59 | characters. | ||
| 60 | The | ||
| 61 | .Fn strnlen | ||
| 62 | function will never attempt to address more than | ||
| 63 | .Fa maxlen | ||
| 64 | characters, making it suitable for use with character arrays that are | ||
| 65 | not guaranteed to be NUL-terminated. | ||
| 55 | .Sh RETURN VALUES | 66 | .Sh RETURN VALUES |
| 56 | The | 67 | The |
| 57 | .Fn strlen | 68 | .Fn strlen |
| 58 | function | 69 | function returns the number of characters that precede the terminating |
| 59 | returns | 70 | .Tn NUL |
| 60 | the number of characters that precede the | ||
| 61 | terminating | ||
| 62 | .Dv NUL | ||
| 63 | character. | 71 | character. |
| 72 | .Pp | ||
| 73 | The | ||
| 74 | .Fn strnlen | ||
| 75 | function returns the number of characters that precede the terminating | ||
| 76 | .Tn NUL | ||
| 77 | or | ||
| 78 | .Fa maxlen , | ||
| 79 | whichever is smaller. | ||
| 64 | .Sh SEE ALSO | 80 | .Sh SEE ALSO |
| 65 | .Xr string 3 | 81 | .Xr string 3 , |
| 82 | .Xr wcslen 3 | ||
| 66 | .Sh STANDARDS | 83 | .Sh STANDARDS |
| 67 | The | 84 | The |
| 68 | .Fn strlen | 85 | .Fn strlen |
| 69 | function | 86 | function conforms to |
| 70 | conforms to | ||
| 71 | .St -ansiC . | 87 | .St -ansiC . |
| 88 | .Pp | ||
| 89 | The | ||
| 90 | .Fn strlen | ||
| 91 | and | ||
| 92 | .Fn strnlen | ||
| 93 | functions conform to | ||
| 94 | .St -p1003.1-2008 . | ||
| 95 | .Sh HISTORY | ||
| 96 | The | ||
| 97 | .Fn strlen | ||
| 98 | function first appeared in the Programmer's Workbench (PWB/UNIX) | ||
| 99 | and was ported to | ||
| 100 | .At v7 . | ||
| 101 | The | ||
| 102 | .Fn strnlen | ||
| 103 | function appeared in glibc 2.0 | ||
| 104 | and was reimplemented for | ||
| 105 | .Ox 4.8 . | ||
diff --git a/src/lib/libc/string/strlen.c b/src/lib/libc/string/strlen.c index d23aadafc0..12d9ec4dad 100644 --- a/src/lib/libc/string/strlen.c +++ b/src/lib/libc/string/strlen.c | |||
| @@ -1,6 +1,8 @@ | |||
| 1 | /* $OpenBSD: strlen.c,v 1.7 2005/08/08 08:05:37 espie Exp $ */ | ||
| 2 | |||
| 1 | /*- | 3 | /*- |
| 2 | * Copyright (c) 1990 The Regents of the University of California. | 4 | * Copyright (c) 1990, 1993 |
| 3 | * All rights reserved. | 5 | * The Regents of the University of California. All rights reserved. |
| 4 | * | 6 | * |
| 5 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without |
| 6 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions |
| @@ -10,11 +12,7 @@ | |||
| 10 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the |
| 12 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. All advertising materials mentioning features or use of this software | 15 | * 3. Neither the name of the University nor the names of its contributors |
| 14 | * must display the following acknowledgement: | ||
| 15 | * This product includes software developed by the University of | ||
| 16 | * California, Berkeley and its contributors. | ||
| 17 | * 4. Neither the name of the University nor the names of its contributors | ||
| 18 | * may be used to endorse or promote products derived from this software | 16 | * may be used to endorse or promote products derived from this software |
| 19 | * without specific prior written permission. | 17 | * without specific prior written permission. |
| 20 | * | 18 | * |
| @@ -31,20 +29,19 @@ | |||
| 31 | * SUCH DAMAGE. | 29 | * SUCH DAMAGE. |
| 32 | */ | 30 | */ |
| 33 | 31 | ||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | 32 | #if !defined(_KERNEL) && !defined(_STANDALONE) |
| 35 | /*static char *sccsid = "from: @(#)strlen.c 5.5 (Berkeley) 1/26/91";*/ | ||
| 36 | static char *rcsid = "$Id: strlen.c,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $"; | ||
| 37 | #endif /* LIBC_SCCS and not lint */ | ||
| 38 | |||
| 39 | #include <string.h> | 33 | #include <string.h> |
| 34 | #else | ||
| 35 | #include <lib/libkern/libkern.h> | ||
| 36 | #endif | ||
| 40 | 37 | ||
| 41 | size_t | 38 | size_t |
| 42 | strlen(str) | 39 | strlen(const char *str) |
| 43 | const char *str; | ||
| 44 | { | 40 | { |
| 45 | register const char *s; | 41 | const char *s; |
| 46 | 42 | ||
| 47 | for (s = str; *s; ++s); | 43 | for (s = str; *s; ++s) |
| 48 | return(s - str); | 44 | ; |
| 45 | return (s - str); | ||
| 49 | } | 46 | } |
| 50 | 47 | ||
diff --git a/src/lib/libc/string/strmode.3 b/src/lib/libc/string/strmode.3 index 1907e7ab03..bebda2ca1c 100644 --- a/src/lib/libc/string/strmode.3 +++ b/src/lib/libc/string/strmode.3 | |||
| @@ -1,5 +1,7 @@ | |||
| 1 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. | 1 | .\" $OpenBSD: strmode.3,v 1.16 2013/06/05 03:39:23 tedu Exp $ |
| 2 | .\" All rights reserved. | 2 | .\" |
| 3 | .\" Copyright (c) 1990, 1991, 1993 | ||
| 4 | .\" The Regents of the University of California. All rights reserved. | ||
| 3 | .\" | 5 | .\" |
| 4 | .\" Redistribution and use in source and binary forms, with or without | 6 | .\" Redistribution and use in source and binary forms, with or without |
| 5 | .\" modification, are permitted provided that the following conditions | 7 | .\" modification, are permitted provided that the following conditions |
| @@ -9,11 +11,7 @@ | |||
| 9 | .\" 2. Redistributions in binary form must reproduce the above copyright | 11 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 10 | .\" notice, this list of conditions and the following disclaimer in the | 12 | .\" notice, this list of conditions and the following disclaimer in the |
| 11 | .\" documentation and/or other materials provided with the distribution. | 13 | .\" documentation and/or other materials provided with the distribution. |
| 12 | .\" 3. All advertising materials mentioning features or use of this software | 14 | .\" 3. Neither the name of the University nor the names of its contributors |
| 13 | .\" must display the following acknowledgement: | ||
| 14 | .\" This product includes software developed by the University of | ||
| 15 | .\" California, Berkeley and its contributors. | ||
| 16 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 17 | .\" may be used to endorse or promote products derived from this software | 15 | .\" may be used to endorse or promote products derived from this software |
| 18 | .\" without specific prior written permission. | 16 | .\" without specific prior written permission. |
| 19 | .\" | 17 | .\" |
| @@ -29,31 +27,28 @@ | |||
| 29 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 27 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 30 | .\" SUCH DAMAGE. | 28 | .\" SUCH DAMAGE. |
| 31 | .\" | 29 | .\" |
| 32 | .\" from: @(#)strmode.3 5.4 (Berkeley) 7/31/91 | 30 | .\" @(#)strmode.3 8.3 (Berkeley) 7/28/94 |
| 33 | .\" $Id: strmode.3,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $ | ||
| 34 | .\" | 31 | .\" |
| 35 | .Dd July 31, 1991 | 32 | .Dd $Mdocdate: June 5 2013 $ |
| 36 | .Dt STRMODE 3 | 33 | .Dt STRMODE 3 |
| 37 | .Os | 34 | .Os |
| 38 | .Sh NAME | 35 | .Sh NAME |
| 39 | .Nm strmode | 36 | .Nm strmode |
| 40 | .Nd convert inode status information into a symbolic string | 37 | .Nd convert inode status information into a symbolic string |
| 41 | .Sh SYNOPSIS | 38 | .Sh SYNOPSIS |
| 42 | .Fd #include <string.h> | 39 | .In string.h |
| 43 | .Ft void | 40 | .Ft void |
| 44 | .Fn strmode "mode_t mode" "char *bp" | 41 | .Fn strmode "mode_t mode" "char *bp" |
| 45 | .Sh DESCRIPTION | 42 | .Sh DESCRIPTION |
| 46 | The | 43 | The |
| 47 | .Fn strmode | 44 | .Fn strmode |
| 48 | function | 45 | function converts a file |
| 49 | converts a file | ||
| 50 | .Fa mode | 46 | .Fa mode |
| 51 | (the type and permission information associated with an inode, see | 47 | (the type and permission information associated with an inode, see |
| 52 | .Xr stat 2 ) | 48 | .Xr stat 2 ) |
| 53 | into a symbolic string which is stored in the location referenced by | 49 | into a symbolic string which is stored in the location referenced by |
| 54 | .Fa bp . | 50 | .Fa bp . |
| 55 | This stored string is eleven characters in length plus a trailing | 51 | This stored string is eleven characters in length plus a trailing NUL byte. |
| 56 | .Dv NULL . | ||
| 57 | .Pp | 52 | .Pp |
| 58 | The first character is the inode type, and will be one of the following: | 53 | The first character is the inode type, and will be one of the following: |
| 59 | .Pp | 54 | .Pp |
| @@ -69,10 +64,10 @@ directory | |||
| 69 | .It l | 64 | .It l |
| 70 | symbolic link | 65 | symbolic link |
| 71 | .It p | 66 | .It p |
| 72 | fifo | 67 | FIFO |
| 73 | .It s | 68 | .It s |
| 74 | socket | 69 | socket |
| 75 | .It ? | 70 | .It \&? |
| 76 | unknown inode type | 71 | unknown inode type |
| 77 | .El | 72 | .El |
| 78 | .Pp | 73 | .Pp |
| @@ -80,46 +75,58 @@ The next nine characters encode three sets of permissions, in three | |||
| 80 | characters each. | 75 | characters each. |
| 81 | The first three characters are the permissions for the owner of the | 76 | The first three characters are the permissions for the owner of the |
| 82 | file, the second three for the group the file belongs to, and the | 77 | file, the second three for the group the file belongs to, and the |
| 83 | third for the ``other'', or default, set of users. | 78 | third for the |
| 79 | .Dq other , | ||
| 80 | or default, set of users. | ||
| 84 | .Pp | 81 | .Pp |
| 85 | Permission checking is done as specifically as possible. | 82 | Permission checking is done as specifically as possible. |
| 86 | If read permission is denied to the owner of a file in the first set | 83 | If read permission is denied to the owner of a file in the first set |
| 87 | of permissions, the owner of the file will not be able to read the file. | 84 | of permissions, the owner of the file will not be able to read the file. |
| 88 | This is true even if the owner is in the file's group and the group | 85 | This is true even if the owner is in the file's group and the group |
| 89 | permissions allow reading or the ``other'' permissions allow reading. | 86 | permissions allow reading or the |
| 87 | .Dq other | ||
| 88 | permissions allow reading. | ||
| 90 | .Pp | 89 | .Pp |
| 91 | If the first character of the three character set is an ``r'', the file is | 90 | If the first character of the three character set is an |
| 92 | readable for that set of users; if a dash ``\-'', it is not readable. | 91 | .Sq r , |
| 92 | the file is readable for that set of users; if a dash | ||
| 93 | .Pq Ql - , | ||
| 94 | it is not readable. | ||
| 93 | .Pp | 95 | .Pp |
| 94 | If the second character of the three character set is a ``w'', the file is | 96 | If the second character of the three character set is a |
| 95 | writable for that set of users; if a dash ``\-'', it is not writable. | 97 | .Sq w , |
| 98 | the file is writable for that set of users; if a dash | ||
| 99 | .Pq Ql - , | ||
| 100 | it is not writable. | ||
| 96 | .Pp | 101 | .Pp |
| 97 | The third character is the first of the following characters that apply: | 102 | The third character is the first of the following characters that apply: |
| 98 | .Bl -tag -width xxxx | 103 | .Bl -tag -width xxxx |
| 99 | .It S | 104 | .It S |
| 100 | If the character is part of the owner permissions and the file is not | 105 | If the character is part of the owner permissions and the file is not |
| 101 | executable or the directory is not searchable, by the owner, and the | 106 | executable or the directory is not searchable by the owner, and the |
| 102 | set-user-id bit is set. | 107 | set-user-ID bit is set. |
| 103 | .It S | 108 | .It S |
| 104 | If the character is part of the group permissions and the file is not | 109 | If the character is part of the group permissions and the file is not |
| 105 | executable or the directory is not searchable, by the group, and the | 110 | executable or the directory is not searchable by the group, and the |
| 106 | set-group-id bit is set. | 111 | set-group-ID bit is set. |
| 107 | .It T | 112 | .It T |
| 108 | If the character is part of the other permissions and the file is not | 113 | If the character is part of the other permissions and the file is not |
| 109 | executable or the directory is not searchable, by others, and the ``sticky'' | 114 | executable or the directory is not searchable by others, and the |
| 115 | .Dq sticky | ||
| 110 | .Pq Dv S_ISVTX | 116 | .Pq Dv S_ISVTX |
| 111 | bit is set. | 117 | bit is set. |
| 112 | .It s | 118 | .It s |
| 113 | If the character is part of the owner permissions and the file is | 119 | If the character is part of the owner permissions and the file is |
| 114 | executable or the directory searchable, by the owner, and the set-user-id | 120 | executable or the directory searchable by the owner, and the set-user-ID |
| 115 | bit is set. | 121 | bit is set. |
| 116 | .It s | 122 | .It s |
| 117 | If the character is part of the group permissions and the file is | 123 | If the character is part of the group permissions and the file is |
| 118 | executable or the directory searchable, by the group, and the set-group-id | 124 | executable or the directory searchable by the group, and the set-group-ID |
| 119 | bit is set. | 125 | bit is set. |
| 120 | .It t | 126 | .It t |
| 121 | If the character is part of the other permissions and the file is | 127 | If the character is part of the other permissions and the file is |
| 122 | executable or the directory searchable, by others, and the ``sticky'' | 128 | executable or the directory searchable by others, and the |
| 129 | .Dq sticky | ||
| 123 | .Pq Dv S_ISVTX | 130 | .Pq Dv S_ISVTX |
| 124 | bit is set. | 131 | bit is set. |
| 125 | .It x | 132 | .It x |
| @@ -128,14 +135,15 @@ The file is executable or the directory is searchable. | |||
| 128 | None of the above apply. | 135 | None of the above apply. |
| 129 | .El | 136 | .El |
| 130 | .Pp | 137 | .Pp |
| 131 | The last character is a plus sign ``+'' if any there are any alternate | 138 | The last character is a plus sign |
| 139 | .Pq Ql + | ||
| 140 | if there are any alternate | ||
| 132 | or additional access control methods associated with the inode, otherwise | 141 | or additional access control methods associated with the inode, otherwise |
| 133 | it will be a space. | 142 | it will be a space. |
| 134 | .Sh RETURN VALUES | 143 | .Sh RETURN VALUES |
| 135 | The | 144 | The |
| 136 | .Fn strmode | 145 | .Fn strmode |
| 137 | function | 146 | function always returns 0. |
| 138 | always returns 0. | ||
| 139 | .Sh SEE ALSO | 147 | .Sh SEE ALSO |
| 140 | .Xr chmod 1 , | 148 | .Xr chmod 1 , |
| 141 | .Xr find 1 , | 149 | .Xr find 1 , |
| @@ -145,5 +153,5 @@ always returns 0. | |||
| 145 | .Sh HISTORY | 153 | .Sh HISTORY |
| 146 | The | 154 | The |
| 147 | .Fn strmode | 155 | .Fn strmode |
| 148 | function | 156 | function first appeared in |
| 149 | .Ud . | 157 | .Bx 4.3 Reno . |
diff --git a/src/lib/libc/string/strmode.c b/src/lib/libc/string/strmode.c index 441fc76e90..6f0fa34ed8 100644 --- a/src/lib/libc/string/strmode.c +++ b/src/lib/libc/string/strmode.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: strmode.c,v 1.7 2005/08/08 08:05:37 espie Exp $ */ | ||
| 1 | /*- | 2 | /*- |
| 2 | * Copyright (c) 1990 The Regents of the University of California. | 3 | * Copyright (c) 1990 The Regents of the University of California. |
| 3 | * All rights reserved. | 4 | * All rights reserved. |
| @@ -10,11 +11,7 @@ | |||
| 10 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the |
| 12 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. Neither the name of the University nor the names of its contributors |
| 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 | 15 | * may be used to endorse or promote products derived from this software |
| 19 | * without specific prior written permission. | 16 | * without specific prior written permission. |
| 20 | * | 17 | * |
| @@ -31,19 +28,14 @@ | |||
| 31 | * SUCH DAMAGE. | 28 | * SUCH DAMAGE. |
| 32 | */ | 29 | */ |
| 33 | 30 | ||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 35 | /*static char *sccsid = "from: @(#)strmode.c 5.3 (Berkeley) 5/18/90";*/ | ||
| 36 | static char *rcsid = "$Id: strmode.c,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $"; | ||
| 37 | #endif /* LIBC_SCCS and not lint */ | ||
| 38 | |||
| 39 | #include <sys/types.h> | 31 | #include <sys/types.h> |
| 40 | #include <sys/stat.h> | 32 | #include <sys/stat.h> |
| 41 | #include <string.h> | 33 | #include <string.h> |
| 42 | 34 | ||
| 35 | /* XXX mode should be mode_t */ | ||
| 36 | |||
| 43 | void | 37 | void |
| 44 | strmode(mode, p) | 38 | strmode(int mode, char *p) |
| 45 | register mode_t mode; | ||
| 46 | register char *p; | ||
| 47 | { | 39 | { |
| 48 | /* print type */ | 40 | /* print type */ |
| 49 | switch (mode & S_IFMT) { | 41 | switch (mode & S_IFMT) { |
diff --git a/src/lib/libc/string/strncat.3 b/src/lib/libc/string/strncat.3 new file mode 100644 index 0000000000..bd15ef10fa --- /dev/null +++ b/src/lib/libc/string/strncat.3 | |||
| @@ -0,0 +1,128 @@ | |||
| 1 | .\" $OpenBSD: strncat.3,v 1.2 2013/12/19 22:00:58 jmc Exp $ | ||
| 2 | .\" | ||
| 3 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. | ||
| 4 | .\" All rights reserved. | ||
| 5 | .\" | ||
| 6 | .\" This code is derived from software contributed to Berkeley by | ||
| 7 | .\" Chris Torek and the American National Standards Committee X3, | ||
| 8 | .\" on Information Processing Systems. | ||
| 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. 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 $Mdocdate: December 19 2013 $ | ||
| 35 | .Dt STRNCAT 3 | ||
| 36 | .Os | ||
| 37 | .Sh NAME | ||
| 38 | .Nm strncat | ||
| 39 | .Nd concatenate a string with part of another | ||
| 40 | .Sh SYNOPSIS | ||
| 41 | .In string.h | ||
| 42 | .Ft char * | ||
| 43 | .Fn strncat "char *s" "const char *append" "size_t count" | ||
| 44 | .Sh DESCRIPTION | ||
| 45 | The | ||
| 46 | .Fn strncat | ||
| 47 | function appends not more than | ||
| 48 | .Fa count | ||
| 49 | characters of the NUL-terminated string | ||
| 50 | .Fa append | ||
| 51 | to the end of the NUL-terminated string | ||
| 52 | .Fa s . | ||
| 53 | Space for the terminating | ||
| 54 | .Ql \e0 | ||
| 55 | should not be included in | ||
| 56 | .Fa count . | ||
| 57 | The string | ||
| 58 | .Fa s | ||
| 59 | must have sufficient space to hold the result. | ||
| 60 | .Sh RETURN VALUES | ||
| 61 | The | ||
| 62 | .Fn strncat | ||
| 63 | function returns the pointer | ||
| 64 | .Fa s . | ||
| 65 | .Sh EXAMPLES | ||
| 66 | The following appends | ||
| 67 | .Dq Li abc | ||
| 68 | to | ||
| 69 | .Va chararray : | ||
| 70 | .Bd -literal -offset indent | ||
| 71 | char *letters = "abcdefghi"; | ||
| 72 | |||
| 73 | (void)strncat(chararray, letters, 3); | ||
| 74 | .Ed | ||
| 75 | .Pp | ||
| 76 | The following example shows how to use | ||
| 77 | .Fn strncat | ||
| 78 | safely in conjunction with | ||
| 79 | .Xr strncpy 3 . | ||
| 80 | .Bd -literal -offset indent | ||
| 81 | char buf[BUFSIZ]; | ||
| 82 | char *input, *suffix; | ||
| 83 | |||
| 84 | (void)strncpy(buf, input, sizeof(buf) - 1); | ||
| 85 | buf[sizeof(buf) - 1] = '\e0'; | ||
| 86 | (void)strncat(buf, suffix, sizeof(buf) - 1 - strlen(buf)); | ||
| 87 | .Ed | ||
| 88 | .Pp | ||
| 89 | The above will copy as many characters from | ||
| 90 | .Va input | ||
| 91 | to | ||
| 92 | .Va buf | ||
| 93 | as will fit. | ||
| 94 | It then appends as many characters from | ||
| 95 | .Va suffix | ||
| 96 | as will fit (or none | ||
| 97 | if there is no space). | ||
| 98 | For operations like this, the | ||
| 99 | .Xr strlcpy 3 | ||
| 100 | and | ||
| 101 | .Xr strlcat 3 | ||
| 102 | functions are a better choice, as shown below. | ||
| 103 | .Bd -literal -offset indent | ||
| 104 | (void)strlcpy(buf, input, sizeof(buf)); | ||
| 105 | (void)strlcat(buf, suffix, sizeof(buf)); | ||
| 106 | .Ed | ||
| 107 | .Sh SEE ALSO | ||
| 108 | .Xr bcopy 3 , | ||
| 109 | .Xr memccpy 3 , | ||
| 110 | .Xr memcpy 3 , | ||
| 111 | .Xr memmove 3 , | ||
| 112 | .Xr strcat 3 , | ||
| 113 | .Xr strcpy 3 , | ||
| 114 | .Xr strlcpy 3 , | ||
| 115 | .Xr wcscat 3 , | ||
| 116 | .Xr wcslcpy 3 | ||
| 117 | .Sh STANDARDS | ||
| 118 | The | ||
| 119 | .Fn strcat | ||
| 120 | and | ||
| 121 | .Fn strncat | ||
| 122 | functions conform to | ||
| 123 | .St -ansiC . | ||
| 124 | .Sh HISTORY | ||
| 125 | The | ||
| 126 | .Fn strncat | ||
| 127 | function first appeared in | ||
| 128 | .At v7 . | ||
diff --git a/src/lib/libc/string/strncat.c b/src/lib/libc/string/strncat.c index 3d96452af4..c4df4f2fad 100644 --- a/src/lib/libc/string/strncat.c +++ b/src/lib/libc/string/strncat.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: strncat.c,v 1.5 2005/08/08 08:05:37 espie Exp $ */ | ||
| 1 | /*- | 2 | /*- |
| 2 | * Copyright (c) 1990 The Regents of the University of California. | 3 | * Copyright (c) 1990 The Regents of the University of California. |
| 3 | * All rights reserved. | 4 | * All rights reserved. |
| @@ -13,11 +14,7 @@ | |||
| 13 | * 2. Redistributions in binary form must reproduce the above copyright | 14 | * 2. Redistributions in binary form must reproduce the above copyright |
| 14 | * notice, this list of conditions and the following disclaimer in the | 15 | * notice, this list of conditions and the following disclaimer in the |
| 15 | * documentation and/or other materials provided with the distribution. | 16 | * documentation and/or other materials provided with the distribution. |
| 16 | * 3. All advertising materials mentioning features or use of this software | 17 | * 3. Neither the name of the University nor the names of its contributors |
| 17 | * must display the following acknowledgement: | ||
| 18 | * This product includes software developed by the University of | ||
| 19 | * California, Berkeley and its contributors. | ||
| 20 | * 4. Neither the name of the University nor the names of its contributors | ||
| 21 | * may be used to endorse or promote products derived from this software | 18 | * may be used to endorse or promote products derived from this software |
| 22 | * without specific prior written permission. | 19 | * without specific prior written permission. |
| 23 | * | 20 | * |
| @@ -34,11 +31,6 @@ | |||
| 34 | * SUCH DAMAGE. | 31 | * SUCH DAMAGE. |
| 35 | */ | 32 | */ |
| 36 | 33 | ||
| 37 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 38 | /*static char *sccsid = "from: @(#)strncat.c 5.6 (Berkeley) 1/26/91";*/ | ||
| 39 | static char *rcsid = "$Id: strncat.c,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $"; | ||
| 40 | #endif /* LIBC_SCCS and not lint */ | ||
| 41 | |||
| 42 | #include <string.h> | 34 | #include <string.h> |
| 43 | 35 | ||
| 44 | /* | 36 | /* |
| @@ -46,14 +38,11 @@ static char *rcsid = "$Id: strncat.c,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $ | |||
| 46 | * are written at dst (at most n+1 bytes being appended). Return dst. | 38 | * are written at dst (at most n+1 bytes being appended). Return dst. |
| 47 | */ | 39 | */ |
| 48 | char * | 40 | char * |
| 49 | strncat(dst, src, n) | 41 | strncat(char *dst, const char *src, size_t n) |
| 50 | char *dst; | ||
| 51 | const char *src; | ||
| 52 | register size_t n; | ||
| 53 | { | 42 | { |
| 54 | if (n != 0) { | 43 | if (n != 0) { |
| 55 | register char *d = dst; | 44 | char *d = dst; |
| 56 | register const char *s = src; | 45 | const char *s = src; |
| 57 | 46 | ||
| 58 | while (*d != 0) | 47 | while (*d != 0) |
| 59 | d++; | 48 | d++; |
diff --git a/src/lib/libc/string/strncmp.c b/src/lib/libc/string/strncmp.c index 0638d4dcf2..0aea80d7d9 100644 --- a/src/lib/libc/string/strncmp.c +++ b/src/lib/libc/string/strncmp.c | |||
| @@ -1,3 +1,5 @@ | |||
| 1 | /* $OpenBSD: strncmp.c,v 1.7 2005/08/08 08:05:37 espie Exp $ */ | ||
| 2 | |||
| 1 | /* | 3 | /* |
| 2 | * Copyright (c) 1989 The Regents of the University of California. | 4 | * Copyright (c) 1989 The Regents of the University of California. |
| 3 | * All rights reserved. | 5 | * All rights reserved. |
| @@ -10,11 +12,7 @@ | |||
| 10 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the |
| 12 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. All advertising materials mentioning features or use of this software | 15 | * 3. Neither the name of the University nor the names of its contributors |
| 14 | * must display the following acknowledgement: | ||
| 15 | * This product includes software developed by the University of | ||
| 16 | * California, Berkeley and its contributors. | ||
| 17 | * 4. Neither the name of the University nor the names of its contributors | ||
| 18 | * may be used to endorse or promote products derived from this software | 16 | * may be used to endorse or promote products derived from this software |
| 19 | * without specific prior written permission. | 17 | * without specific prior written permission. |
| 20 | * | 18 | * |
| @@ -31,17 +29,14 @@ | |||
| 31 | * SUCH DAMAGE. | 29 | * SUCH DAMAGE. |
| 32 | */ | 30 | */ |
| 33 | 31 | ||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | 32 | #if !defined(_KERNEL) && !defined(_STANDALONE) |
| 35 | /*static char *sccsid = "from: @(#)strncmp.c 5.6 (Berkeley) 1/26/91";*/ | ||
| 36 | static char *rcsid = "$Id: strncmp.c,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $"; | ||
| 37 | #endif /* LIBC_SCCS and not lint */ | ||
| 38 | |||
| 39 | #include <string.h> | 33 | #include <string.h> |
| 34 | #else | ||
| 35 | #include <lib/libkern/libkern.h> | ||
| 36 | #endif | ||
| 40 | 37 | ||
| 41 | int | 38 | int |
| 42 | strncmp(s1, s2, n) | 39 | strncmp(const char *s1, const char *s2, size_t n) |
| 43 | register const char *s1, *s2; | ||
| 44 | register size_t n; | ||
| 45 | { | 40 | { |
| 46 | 41 | ||
| 47 | if (n == 0) | 42 | if (n == 0) |
diff --git a/src/lib/libc/string/strncpy.3 b/src/lib/libc/string/strncpy.3 new file mode 100644 index 0000000000..dd8ddb86fc --- /dev/null +++ b/src/lib/libc/string/strncpy.3 | |||
| @@ -0,0 +1,153 @@ | |||
| 1 | .\" $OpenBSD: strncpy.3,v 1.1 2013/12/19 20:52:37 millert Exp $ | ||
| 2 | .\" | ||
| 3 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. | ||
| 4 | .\" All rights reserved. | ||
| 5 | .\" | ||
| 6 | .\" This code is derived from software contributed to Berkeley by | ||
| 7 | .\" Chris Torek and the American National Standards Committee X3, | ||
| 8 | .\" on Information Processing Systems. | ||
| 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. 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 $Mdocdate: December 19 2013 $ | ||
| 35 | .Dt STRNCPY 3 | ||
| 36 | .Os | ||
| 37 | .Sh NAME | ||
| 38 | .Nm strncpy | ||
| 39 | .Nd copy part of a string to another | ||
| 40 | .Sh SYNOPSIS | ||
| 41 | .In string.h | ||
| 42 | .Ft char * | ||
| 43 | .Fn strncpy "char *dst" "const char *src" "size_t len" | ||
| 44 | .Sh DESCRIPTION | ||
| 45 | The | ||
| 46 | .Fn strncpy | ||
| 47 | function copies not more than | ||
| 48 | .Fa len | ||
| 49 | characters from the string | ||
| 50 | .Fa src | ||
| 51 | to | ||
| 52 | .Fa dst . | ||
| 53 | If | ||
| 54 | .Fa src | ||
| 55 | is less than | ||
| 56 | .Fa len | ||
| 57 | characters long, | ||
| 58 | it appends | ||
| 59 | .Ql \e0 | ||
| 60 | characters for the rest of | ||
| 61 | .Fa len . | ||
| 62 | If the length of | ||
| 63 | .Fa src | ||
| 64 | is greater than or equal to | ||
| 65 | .Fa len , | ||
| 66 | .Fa dst | ||
| 67 | will | ||
| 68 | .Em not | ||
| 69 | be NUL-terminated. | ||
| 70 | .Pp | ||
| 71 | If the | ||
| 72 | .Fa src | ||
| 73 | and | ||
| 74 | .Fa dst | ||
| 75 | strings overlap, the behavior is undefined. | ||
| 76 | .Sh RETURN VALUES | ||
| 77 | The | ||
| 78 | .Fn strncpy | ||
| 79 | function returns | ||
| 80 | .Fa dst . | ||
| 81 | .Sh EXAMPLES | ||
| 82 | The following sets | ||
| 83 | .Va chararray | ||
| 84 | to | ||
| 85 | .Dq abc\e0\e0\e0 : | ||
| 86 | .Bd -literal -offset indent | ||
| 87 | (void)strncpy(chararray, "abc", 6); | ||
| 88 | .Ed | ||
| 89 | .Pp | ||
| 90 | The following sets | ||
| 91 | .Va chararray | ||
| 92 | to | ||
| 93 | .Dq abcdef | ||
| 94 | and does | ||
| 95 | .Em not | ||
| 96 | NUL terminate | ||
| 97 | .Va chararray | ||
| 98 | because the length of the source string is greater than or equal to the | ||
| 99 | length parameter. | ||
| 100 | .Fn strncpy | ||
| 101 | .Em only | ||
| 102 | NUL terminates the destination string when the length of the source | ||
| 103 | string is less than the length parameter. | ||
| 104 | .Bd -literal -offset indent | ||
| 105 | (void)strncpy(chararray, "abcdefgh", 6); | ||
| 106 | .Ed | ||
| 107 | .Pp | ||
| 108 | The following copies as many characters from | ||
| 109 | .Va input | ||
| 110 | to | ||
| 111 | .Va buf | ||
| 112 | as will fit and NUL terminates the result. | ||
| 113 | Because | ||
| 114 | .Fn strncpy | ||
| 115 | does | ||
| 116 | .Em not | ||
| 117 | guarantee to NUL terminate the string itself, it must be done by hand. | ||
| 118 | .Bd -literal -offset indent | ||
| 119 | char buf[BUFSIZ]; | ||
| 120 | |||
| 121 | (void)strncpy(buf, input, sizeof(buf) - 1); | ||
| 122 | buf[sizeof(buf) - 1] = '\e0'; | ||
| 123 | .Ed | ||
| 124 | .Pp | ||
| 125 | Note that | ||
| 126 | .Xr strlcpy 3 | ||
| 127 | is a better choice for this kind of operation. | ||
| 128 | The equivalent using | ||
| 129 | .Xr strlcpy 3 | ||
| 130 | is simply: | ||
| 131 | .Bd -literal -offset indent | ||
| 132 | (void)strlcpy(buf, input, sizeof(buf)); | ||
| 133 | .Ed | ||
| 134 | .Sh SEE ALSO | ||
| 135 | .Xr bcopy 3 , | ||
| 136 | .Xr memccpy 3 , | ||
| 137 | .Xr memcpy 3 , | ||
| 138 | .Xr memmove 3 , | ||
| 139 | .Xr strcat 3 , | ||
| 140 | .Xr strlcpy 3 , | ||
| 141 | .Xr strncat 3 , | ||
| 142 | .Xr wcscpy 3 , | ||
| 143 | .Xr wcslcpy 3 | ||
| 144 | .Sh STANDARDS | ||
| 145 | The | ||
| 146 | .Fn strncpy | ||
| 147 | function conforms to | ||
| 148 | .St -ansiC . | ||
| 149 | .Sh HISTORY | ||
| 150 | The | ||
| 151 | .Fn strncpy | ||
| 152 | function first appeared in | ||
| 153 | .At v7 . | ||
diff --git a/src/lib/libc/string/strncpy.c b/src/lib/libc/string/strncpy.c index 5215311b75..4426cbe2e3 100644 --- a/src/lib/libc/string/strncpy.c +++ b/src/lib/libc/string/strncpy.c | |||
| @@ -1,3 +1,5 @@ | |||
| 1 | /* $OpenBSD: strncpy.c,v 1.6 2005/08/08 08:05:37 espie Exp $ */ | ||
| 2 | |||
| 1 | /*- | 3 | /*- |
| 2 | * Copyright (c) 1990 The Regents of the University of California. | 4 | * Copyright (c) 1990 The Regents of the University of California. |
| 3 | * All rights reserved. | 5 | * All rights reserved. |
| @@ -13,11 +15,7 @@ | |||
| 13 | * 2. Redistributions in binary form must reproduce the above copyright | 15 | * 2. Redistributions in binary form must reproduce the above copyright |
| 14 | * notice, this list of conditions and the following disclaimer in the | 16 | * notice, this list of conditions and the following disclaimer in the |
| 15 | * documentation and/or other materials provided with the distribution. | 17 | * documentation and/or other materials provided with the distribution. |
| 16 | * 3. All advertising materials mentioning features or use of this software | 18 | * 3. Neither the name of the University nor the names of its contributors |
| 17 | * must display the following acknowledgement: | ||
| 18 | * This product includes software developed by the University of | ||
| 19 | * California, Berkeley and its contributors. | ||
| 20 | * 4. Neither the name of the University nor the names of its contributors | ||
| 21 | * may be used to endorse or promote products derived from this software | 19 | * may be used to endorse or promote products derived from this software |
| 22 | * without specific prior written permission. | 20 | * without specific prior written permission. |
| 23 | * | 21 | * |
| @@ -34,26 +32,22 @@ | |||
| 34 | * SUCH DAMAGE. | 32 | * SUCH DAMAGE. |
| 35 | */ | 33 | */ |
| 36 | 34 | ||
| 37 | #if defined(LIBC_SCCS) && !defined(lint) | 35 | #if !defined(_KERNEL) && !defined(_STANDALONE) |
| 38 | /*static char *sccsid = "from: @(#)strncpy.c 5.6 (Berkeley) 1/26/91";*/ | ||
| 39 | static char *rcsid = "$Id: strncpy.c,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $"; | ||
| 40 | #endif /* LIBC_SCCS and not lint */ | ||
| 41 | |||
| 42 | #include <string.h> | 36 | #include <string.h> |
| 37 | #else | ||
| 38 | #include <lib/libkern/libkern.h> | ||
| 39 | #endif | ||
| 43 | 40 | ||
| 44 | /* | 41 | /* |
| 45 | * Copy src to dst, truncating or null-padding to always copy n bytes. | 42 | * Copy src to dst, truncating or null-padding to always copy n bytes. |
| 46 | * Return dst. | 43 | * Return dst. |
| 47 | */ | 44 | */ |
| 48 | char * | 45 | char * |
| 49 | strncpy(dst, src, n) | 46 | strncpy(char *dst, const char *src, size_t n) |
| 50 | char *dst; | ||
| 51 | const char *src; | ||
| 52 | register size_t n; | ||
| 53 | { | 47 | { |
| 54 | if (n != 0) { | 48 | if (n != 0) { |
| 55 | register char *d = dst; | 49 | char *d = dst; |
| 56 | register const char *s = src; | 50 | const char *s = src; |
| 57 | 51 | ||
| 58 | do { | 52 | do { |
| 59 | if ((*d++ = *s++) == 0) { | 53 | if ((*d++ = *s++) == 0) { |
diff --git a/src/lib/libc/string/strndup.c b/src/lib/libc/string/strndup.c new file mode 100644 index 0000000000..27701ac555 --- /dev/null +++ b/src/lib/libc/string/strndup.c | |||
| @@ -0,0 +1,39 @@ | |||
| 1 | /* $OpenBSD: strndup.c,v 1.1 2010/05/18 22:24:55 tedu Exp $ */ | ||
| 2 | |||
| 3 | /* | ||
| 4 | * Copyright (c) 2010 Todd C. Miller <Todd.Miller@courtesan.com> | ||
| 5 | * | ||
| 6 | * Permission to use, copy, modify, and distribute this software for any | ||
| 7 | * purpose with or without fee is hereby granted, provided that the above | ||
| 8 | * copyright notice and this permission notice appear in all copies. | ||
| 9 | * | ||
| 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <sys/types.h> | ||
| 20 | |||
| 21 | #include <stddef.h> | ||
| 22 | #include <stdlib.h> | ||
| 23 | #include <string.h> | ||
| 24 | |||
| 25 | char * | ||
| 26 | strndup(const char *str, size_t maxlen) | ||
| 27 | { | ||
| 28 | char *copy; | ||
| 29 | size_t len; | ||
| 30 | |||
| 31 | len = strnlen(str, maxlen); | ||
| 32 | copy = malloc(len + 1); | ||
| 33 | if (copy != NULL) { | ||
| 34 | (void)memcpy(copy, str, len); | ||
| 35 | copy[len] = '\0'; | ||
| 36 | } | ||
| 37 | |||
| 38 | return copy; | ||
| 39 | } | ||
diff --git a/src/lib/libc/string/strnlen.c b/src/lib/libc/string/strnlen.c new file mode 100644 index 0000000000..a5e13ae04e --- /dev/null +++ b/src/lib/libc/string/strnlen.c | |||
| @@ -0,0 +1,36 @@ | |||
| 1 | /* $OpenBSD: strnlen.c,v 1.4 2012/04/26 01:22:31 matthew Exp $ */ | ||
| 2 | |||
| 3 | /* | ||
| 4 | * Copyright (c) 2010 Todd C. Miller <Todd.Miller@courtesan.com> | ||
| 5 | * | ||
| 6 | * Permission to use, copy, modify, and distribute this software for any | ||
| 7 | * purpose with or without fee is hereby granted, provided that the above | ||
| 8 | * copyright notice and this permission notice appear in all copies. | ||
| 9 | * | ||
| 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <sys/types.h> | ||
| 20 | |||
| 21 | #if !defined(_KERNEL) && !defined(_STANDALONE) | ||
| 22 | #include <string.h> | ||
| 23 | #else | ||
| 24 | #include <lib/libkern/libkern.h> | ||
| 25 | #endif | ||
| 26 | |||
| 27 | size_t | ||
| 28 | strnlen(const char *str, size_t maxlen) | ||
| 29 | { | ||
| 30 | const char *cp; | ||
| 31 | |||
| 32 | for (cp = str; maxlen != 0 && *cp != '\0'; cp++, maxlen--) | ||
| 33 | ; | ||
| 34 | |||
| 35 | return (size_t)(cp - str); | ||
| 36 | } | ||
diff --git a/src/lib/libc/string/strpbrk.3 b/src/lib/libc/string/strpbrk.3 index 8578546c05..b758df6854 100644 --- a/src/lib/libc/string/strpbrk.3 +++ b/src/lib/libc/string/strpbrk.3 | |||
| @@ -1,3 +1,5 @@ | |||
| 1 | .\" $OpenBSD: strpbrk.3,v 1.10 2013/06/05 03:39:23 tedu Exp $ | ||
| 2 | .\" | ||
| 1 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. | 3 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. |
| 2 | .\" All rights reserved. | 4 | .\" All rights reserved. |
| 3 | .\" | 5 | .\" |
| @@ -13,11 +15,7 @@ | |||
| 13 | .\" 2. Redistributions in binary form must reproduce the above copyright | 15 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 14 | .\" notice, this list of conditions and the following disclaimer in the | 16 | .\" notice, this list of conditions and the following disclaimer in the |
| 15 | .\" documentation and/or other materials provided with the distribution. | 17 | .\" documentation and/or other materials provided with the distribution. |
| 16 | .\" 3. All advertising materials mentioning features or use of this software | 18 | .\" 3. Neither the name of the University nor the names of its contributors |
| 17 | .\" must display the following acknowledgement: | ||
| 18 | .\" This product includes software developed by the University of | ||
| 19 | .\" California, Berkeley and its contributors. | ||
| 20 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 21 | .\" may be used to endorse or promote products derived from this software | 19 | .\" may be used to endorse or promote products derived from this software |
| 22 | .\" without specific prior written permission. | 20 | .\" without specific prior written permission. |
| 23 | .\" | 21 | .\" |
| @@ -33,24 +31,20 @@ | |||
| 33 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 34 | .\" SUCH DAMAGE. | 32 | .\" SUCH DAMAGE. |
| 35 | .\" | 33 | .\" |
| 36 | .\" from: @(#)strpbrk.3 5.4 (Berkeley) 6/29/91 | 34 | .Dd $Mdocdate: June 5 2013 $ |
| 37 | .\" $Id: strpbrk.3,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $ | ||
| 38 | .\" | ||
| 39 | .Dd June 29, 1991 | ||
| 40 | .Dt STRPBRK 3 | 35 | .Dt STRPBRK 3 |
| 41 | .Os | 36 | .Os |
| 42 | .Sh NAME | 37 | .Sh NAME |
| 43 | .Nm strpbrk | 38 | .Nm strpbrk |
| 44 | .Nd locate multiple characters in string | 39 | .Nd locate multiple characters in string |
| 45 | .Sh SYNOPSIS | 40 | .Sh SYNOPSIS |
| 46 | .Fd #include <string.h> | 41 | .In string.h |
| 47 | .Ft char * | 42 | .Ft char * |
| 48 | .Fn strpbrk "const char *s" "const char *charset" | 43 | .Fn strpbrk "const char *s" "const char *charset" |
| 49 | .Sh DESCRIPTION | 44 | .Sh DESCRIPTION |
| 50 | The | 45 | The |
| 51 | .Fn strpbrk | 46 | .Fn strpbrk |
| 52 | function | 47 | function locates in the NUL-terminated string |
| 53 | locates in the null-terminated string | ||
| 54 | .Fa s | 48 | .Fa s |
| 55 | the first occurrence of any character in the string | 49 | the first occurrence of any character in the string |
| 56 | .Fa charset | 50 | .Fa charset |
| @@ -58,23 +52,29 @@ and returns a pointer to this character. | |||
| 58 | If no characters from | 52 | If no characters from |
| 59 | .Fa charset | 53 | .Fa charset |
| 60 | occur anywhere in | 54 | occur anywhere in |
| 61 | .Fa s | 55 | .Fa s , |
| 62 | .Fn strpbrk | 56 | .Fn strpbrk |
| 63 | returns NULL. | 57 | returns |
| 58 | .Dv NULL . | ||
| 64 | .Sh SEE ALSO | 59 | .Sh SEE ALSO |
| 65 | .Xr index 3 , | ||
| 66 | .Xr memchr 3 , | 60 | .Xr memchr 3 , |
| 67 | .Xr rindex 3 , | ||
| 68 | .Xr strchr 3 , | 61 | .Xr strchr 3 , |
| 69 | .Xr strcspn 3 , | 62 | .Xr strcspn 3 , |
| 70 | .Xr strrchr 3 , | 63 | .Xr strrchr 3 , |
| 71 | .Xr strsep 3 , | 64 | .Xr strsep 3 , |
| 72 | .Xr strspn 3 , | 65 | .Xr strspn 3 , |
| 73 | .Xr strstr 3 , | 66 | .Xr strstr 3 , |
| 74 | .Xr strtok 3 | 67 | .Xr strtok 3 , |
| 68 | .Xr wcspbrk 3 | ||
| 75 | .Sh STANDARDS | 69 | .Sh STANDARDS |
| 76 | The | 70 | The |
| 77 | .Fn strpbrk | 71 | .Fn strpbrk |
| 78 | function | 72 | function conforms to |
| 79 | conforms to | ||
| 80 | .St -ansiC . | 73 | .St -ansiC . |
| 74 | .Sh HISTORY | ||
| 75 | The | ||
| 76 | .Fn strpbrk | ||
| 77 | function first appeared in | ||
| 78 | .At III | ||
| 79 | and was reimplemented for | ||
| 80 | .Bx 4.3 Tahoe . | ||
diff --git a/src/lib/libc/string/strpbrk.c b/src/lib/libc/string/strpbrk.c index f1d542a525..cd3b71c0d3 100644 --- a/src/lib/libc/string/strpbrk.c +++ b/src/lib/libc/string/strpbrk.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: strpbrk.c,v 1.5 2005/08/08 08:05:37 espie Exp $ */ | ||
| 1 | /* | 2 | /* |
| 2 | * Copyright (c) 1985 Regents of the University of California. | 3 | * Copyright (c) 1985 Regents of the University of California. |
| 3 | * All rights reserved. | 4 | * All rights reserved. |
| @@ -10,11 +11,7 @@ | |||
| 10 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the |
| 12 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. Neither the name of the University nor the names of its contributors |
| 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 | 15 | * may be used to endorse or promote products derived from this software |
| 19 | * without specific prior written permission. | 16 | * without specific prior written permission. |
| 20 | * | 17 | * |
| @@ -31,22 +28,16 @@ | |||
| 31 | * SUCH DAMAGE. | 28 | * SUCH DAMAGE. |
| 32 | */ | 29 | */ |
| 33 | 30 | ||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 35 | /*static char *sccsid = "from: @(#)strpbrk.c 5.8 (Berkeley) 1/26/91";*/ | ||
| 36 | static char *rcsid = "$Id: strpbrk.c,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $"; | ||
| 37 | #endif /* LIBC_SCCS and not lint */ | ||
| 38 | |||
| 39 | #include <string.h> | 31 | #include <string.h> |
| 40 | 32 | ||
| 41 | /* | 33 | /* |
| 42 | * Find the first occurrence in s1 of a character in s2 (excluding NUL). | 34 | * Find the first occurrence in s1 of a character in s2 (excluding NUL). |
| 43 | */ | 35 | */ |
| 44 | char * | 36 | char * |
| 45 | strpbrk(s1, s2) | 37 | strpbrk(const char *s1, const char *s2) |
| 46 | register const char *s1, *s2; | ||
| 47 | { | 38 | { |
| 48 | register const char *scanp; | 39 | const char *scanp; |
| 49 | register int c, sc; | 40 | int c, sc; |
| 50 | 41 | ||
| 51 | while ((c = *s1++) != 0) { | 42 | while ((c = *s1++) != 0) { |
| 52 | for (scanp = s2; (sc = *scanp++) != 0;) | 43 | for (scanp = s2; (sc = *scanp++) != 0;) |
diff --git a/src/lib/libc/string/strrchr.3 b/src/lib/libc/string/strrchr.3 index 1d98cbff24..046b28ce56 100644 --- a/src/lib/libc/string/strrchr.3 +++ b/src/lib/libc/string/strrchr.3 | |||
| @@ -1,3 +1,5 @@ | |||
| 1 | .\" $OpenBSD: strrchr.3,v 1.10 2013/06/05 03:39:23 tedu Exp $ | ||
| 2 | .\" | ||
| 1 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. | 3 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. |
| 2 | .\" All rights reserved. | 4 | .\" All rights reserved. |
| 3 | .\" | 5 | .\" |
| @@ -13,11 +15,7 @@ | |||
| 13 | .\" 2. Redistributions in binary form must reproduce the above copyright | 15 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 14 | .\" notice, this list of conditions and the following disclaimer in the | 16 | .\" notice, this list of conditions and the following disclaimer in the |
| 15 | .\" documentation and/or other materials provided with the distribution. | 17 | .\" documentation and/or other materials provided with the distribution. |
| 16 | .\" 3. All advertising materials mentioning features or use of this software | 18 | .\" 3. Neither the name of the University nor the names of its contributors |
| 17 | .\" must display the following acknowledgement: | ||
| 18 | .\" This product includes software developed by the University of | ||
| 19 | .\" California, Berkeley and its contributors. | ||
| 20 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 21 | .\" may be used to endorse or promote products derived from this software | 19 | .\" may be used to endorse or promote products derived from this software |
| 22 | .\" without specific prior written permission. | 20 | .\" without specific prior written permission. |
| 23 | .\" | 21 | .\" |
| @@ -33,28 +31,29 @@ | |||
| 33 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 34 | .\" SUCH DAMAGE. | 32 | .\" SUCH DAMAGE. |
| 35 | .\" | 33 | .\" |
| 36 | .\" from: @(#)strrchr.3 5.3 (Berkeley) 6/29/91 | 34 | .Dd $Mdocdate: June 5 2013 $ |
| 37 | .\" $Id: strrchr.3,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $ | ||
| 38 | .\" | ||
| 39 | .Dd June 29, 1991 | ||
| 40 | .Dt STRRCHR 3 | 35 | .Dt STRRCHR 3 |
| 41 | .Os | 36 | .Os |
| 42 | .Sh NAME | 37 | .Sh NAME |
| 43 | .Nm strrchr | 38 | .Nm strrchr , |
| 44 | .Nd locate character in string | 39 | .Nm rindex |
| 40 | .Nd locate last occurrence of a character in a string | ||
| 45 | .Sh SYNOPSIS | 41 | .Sh SYNOPSIS |
| 46 | .Fd #include <string.h> | 42 | .In string.h |
| 47 | .Ft char * | 43 | .Ft char * |
| 48 | .Fn strrchr "const char *s" "int c" | 44 | .Fn strrchr "const char *s" "int c" |
| 45 | .Ft char * | ||
| 46 | .Fn rindex "const char *s" "int c" | ||
| 49 | .Sh DESCRIPTION | 47 | .Sh DESCRIPTION |
| 50 | The | 48 | The |
| 51 | .Fn strrchr | 49 | .Fn strrchr |
| 52 | function | 50 | function locates the last occurrence of the character |
| 53 | locates the last occurrence of | ||
| 54 | .Fa c | 51 | .Fa c |
| 55 | (converted to a char) | ||
| 56 | in the string | 52 | in the string |
| 57 | .Fa s . | 53 | .Fa s . |
| 54 | The terminating | ||
| 55 | .Tn NUL | ||
| 56 | character is considered part of the string. | ||
| 58 | If | 57 | If |
| 59 | .Fa c | 58 | .Fa c |
| 60 | is | 59 | is |
| @@ -62,30 +61,56 @@ is | |||
| 62 | .Fn strrchr | 61 | .Fn strrchr |
| 63 | locates the terminating | 62 | locates the terminating |
| 64 | .Ql \e0 . | 63 | .Ql \e0 . |
| 64 | .Pp | ||
| 65 | The | ||
| 66 | .Fn rindex | ||
| 67 | function is an old synonym for | ||
| 68 | .Fn strrchr . | ||
| 65 | .Sh RETURN VALUES | 69 | .Sh RETURN VALUES |
| 66 | The | 70 | The |
| 67 | .Fn strrchr | 71 | .Fn strrchr |
| 68 | function | 72 | function returns a pointer to the located character or |
| 69 | returns a pointer to the character, | 73 | .Dv NULL |
| 70 | or a null | 74 | if the character does not appear in the string. |
| 71 | pointer if | 75 | .Sh EXAMPLES |
| 72 | .Fa c | 76 | After the following call to |
| 73 | does not occur anywhere in | 77 | .Fn strrchr , |
| 74 | .Fa s . | 78 | .Va p |
| 79 | will point to the string | ||
| 80 | .Qq obar : | ||
| 81 | .Bd -literal -offset indent | ||
| 82 | char *p; | ||
| 83 | char *s = "foobar"; | ||
| 84 | |||
| 85 | p = strrchr(s, 'o'); | ||
| 86 | .Ed | ||
| 75 | .Sh SEE ALSO | 87 | .Sh SEE ALSO |
| 76 | .Xr index 3 , | ||
| 77 | .Xr memchr 3 , | 88 | .Xr memchr 3 , |
| 78 | .Xr rindex 3 , | ||
| 79 | .Xr strchr 3 , | 89 | .Xr strchr 3 , |
| 80 | .Xr strcspn 3 , | 90 | .Xr strcspn 3 , |
| 81 | .Xr strpbrk 3 , | 91 | .Xr strpbrk 3 , |
| 82 | .Xr strsep 3 , | 92 | .Xr strsep 3 , |
| 83 | .Xr strspn 3 , | 93 | .Xr strspn 3 , |
| 84 | .Xr strstr 3 , | 94 | .Xr strstr 3 , |
| 85 | .Xr strtok 3 | 95 | .Xr strtok 3 , |
| 96 | .Xr wcsrchr 3 | ||
| 86 | .Sh STANDARDS | 97 | .Sh STANDARDS |
| 87 | The | 98 | The |
| 88 | .Fn strrchr | 99 | .Fn strrchr |
| 89 | function | 100 | function conforms to |
| 90 | conforms to | ||
| 91 | .St -ansiC . | 101 | .St -ansiC . |
| 102 | .Pp | ||
| 103 | The | ||
| 104 | .Fn rindex | ||
| 105 | function is deprecated and shouldn't be used in new code. | ||
| 106 | .Sh HISTORY | ||
| 107 | The | ||
| 108 | .Fn rindex | ||
| 109 | function first appeared in | ||
| 110 | .At v7 . | ||
| 111 | The | ||
| 112 | .Fn strrchr | ||
| 113 | function first appeared in | ||
| 114 | .At III | ||
| 115 | and was reimplemented for | ||
| 116 | .Bx 4.3 Tahoe . | ||
diff --git a/src/lib/libc/string/strsep.3 b/src/lib/libc/string/strsep.3 index 21aa7376f2..77053f66d7 100644 --- a/src/lib/libc/string/strsep.3 +++ b/src/lib/libc/string/strsep.3 | |||
| @@ -1,8 +1,11 @@ | |||
| 1 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. | 1 | .\" $OpenBSD: strsep.3,v 1.14 2013/06/05 03:39:23 tedu Exp $ |
| 2 | .\" All rights reserved. | 2 | .\" |
| 3 | .\" Copyright (c) 1990, 1991, 1993 | ||
| 4 | .\" The Regents of the University of California. All rights reserved. | ||
| 3 | .\" | 5 | .\" |
| 4 | .\" This code is derived from software contributed to Berkeley by | 6 | .\" This code is derived from software contributed to Berkeley by |
| 5 | .\" Chris Torek. | 7 | .\" Chris Torek. |
| 8 | .\" | ||
| 6 | .\" Redistribution and use in source and binary forms, with or without | 9 | .\" Redistribution and use in source and binary forms, with or without |
| 7 | .\" modification, are permitted provided that the following conditions | 10 | .\" modification, are permitted provided that the following conditions |
| 8 | .\" are met: | 11 | .\" are met: |
| @@ -11,11 +14,7 @@ | |||
| 11 | .\" 2. Redistributions in binary form must reproduce the above copyright | 14 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 12 | .\" notice, this list of conditions and the following disclaimer in the | 15 | .\" notice, this list of conditions and the following disclaimer in the |
| 13 | .\" documentation and/or other materials provided with the distribution. | 16 | .\" documentation and/or other materials provided with the distribution. |
| 14 | .\" 3. All advertising materials mentioning features or use of this software | 17 | .\" 3. Neither the name of the University nor the names of its contributors |
| 15 | .\" must display the following acknowledgement: | ||
| 16 | .\" This product includes software developed by the University of | ||
| 17 | .\" California, Berkeley and its contributors. | ||
| 18 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 19 | .\" may be used to endorse or promote products derived from this software | 18 | .\" may be used to endorse or promote products derived from this software |
| 20 | .\" without specific prior written permission. | 19 | .\" without specific prior written permission. |
| 21 | .\" | 20 | .\" |
| @@ -31,39 +30,48 @@ | |||
| 31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 30 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 32 | .\" SUCH DAMAGE. | 31 | .\" SUCH DAMAGE. |
| 33 | .\" | 32 | .\" |
| 34 | .\" from: @(#)strsep.3 5.3 (Berkeley) 4/19/91 | 33 | .\" @(#)strsep.3 8.1 (Berkeley) 6/9/93 |
| 35 | .\" $Id: strsep.3,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $ | ||
| 36 | .\" | 34 | .\" |
| 37 | .Dd April 19, 1991 | 35 | .Dd $Mdocdate: June 5 2013 $ |
| 38 | .Dt STRSEP 3 | 36 | .Dt STRSEP 3 |
| 39 | .Os | 37 | .Os |
| 40 | .Sh NAME | 38 | .Sh NAME |
| 41 | .Nm strsep | 39 | .Nm strsep |
| 42 | .Nd separate strings | 40 | .Nd separate strings |
| 43 | .Sh SYNOPSIS | 41 | .Sh SYNOPSIS |
| 44 | .Fd #include <string.h> | 42 | .In string.h |
| 45 | .Ft char * | 43 | .Ft char * |
| 46 | .Fn strsep "char **stringp" "char *delim" | 44 | .Fn strsep "char **stringp" "const char *delim" |
| 47 | .Sh DESCRIPTION | 45 | .Sh DESCRIPTION |
| 48 | The | 46 | The |
| 49 | .Fn strsep | 47 | .Fn strsep |
| 50 | locates in the null-terminated string at | 48 | function locates, in the string referenced by |
| 51 | .Fa *stringp | ||
| 52 | the first occurrence of any character in | ||
| 53 | .Fa delim | ||
| 54 | and replaces this with a | ||
| 55 | .Ql \e0 , | ||
| 56 | records the location of the immediate following character in | ||
| 57 | .Fa *stringp , | 49 | .Fa *stringp , |
| 58 | then returns the original value of | 50 | the first occurrence of any character in the string |
| 51 | .Fa delim | ||
| 52 | (or the terminating | ||
| 53 | .Ql \e0 | ||
| 54 | character) and replaces it with a | ||
| 55 | .Ql \e0 . | ||
| 56 | The location of the next character after the delimiter character | ||
| 57 | (or | ||
| 58 | .Dv NULL , | ||
| 59 | if the end of the string was reached) is stored in | ||
| 59 | .Fa *stringp . | 60 | .Fa *stringp . |
| 60 | If no delimiter characters are found, | 61 | The original value of |
| 61 | .Fn strsep | ||
| 62 | sets | ||
| 63 | .Fa *stringp | 62 | .Fa *stringp |
| 63 | is returned. | ||
| 64 | .Pp | ||
| 65 | An | ||
| 66 | .Dq empty | ||
| 67 | field, i.e., one caused by two adjacent delimiter characters, | ||
| 68 | can be detected by comparing the location referenced by the pointer returned | ||
| 69 | by | ||
| 70 | .Fn strsep | ||
| 64 | to | 71 | to |
| 65 | .Dv NULL ; | 72 | .Ql \e0 . |
| 66 | if | 73 | .Pp |
| 74 | If | ||
| 67 | .Fa *stringp | 75 | .Fa *stringp |
| 68 | is initially | 76 | is initially |
| 69 | .Dv NULL , | 77 | .Dv NULL , |
| @@ -73,20 +81,30 @@ returns | |||
| 73 | .Sh EXAMPLES | 81 | .Sh EXAMPLES |
| 74 | The following uses | 82 | The following uses |
| 75 | .Fn strsep | 83 | .Fn strsep |
| 76 | to parse strings containing runs of white space, | 84 | to parse a string, containing tokens delimited by whitespace, into an |
| 77 | making up an argument vector: | 85 | argument vector: |
| 78 | .Bd -literal -offset indent | 86 | .Bd -literal -offset indent |
| 79 | char inputstring[100]; | 87 | char **ap, *argv[10], *inputstring; |
| 80 | char **argv[51], **ap = argv, *p, *val; | 88 | |
| 81 | /* set up inputstring */ | 89 | for (ap = argv; ap < &argv[9] && |
| 82 | for (p = inputstring; p != NULL; ) { | 90 | (*ap = strsep(&inputstring, " \et")) != NULL;) { |
| 83 | while ((val = strsep(&p, " \et")) != NULL && *val == '\e0'); | 91 | if (**ap != '\e0') |
| 84 | *ap++ = val; | 92 | ap++; |
| 85 | } | 93 | } |
| 86 | *ap = 0; | 94 | *ap = NULL; |
| 87 | .Ed | 95 | .Ed |
| 88 | .Sh HISTORY | 96 | .Sh HISTORY |
| 89 | The | 97 | The |
| 90 | .Fn strsep | 98 | .Fn strsep |
| 91 | function is | 99 | function first appeared in |
| 92 | .Ud . | 100 | .Bx 4.3 Reno . |
| 101 | It is intended as a replacement for the | ||
| 102 | .Xr strtok 3 | ||
| 103 | function. | ||
| 104 | While the | ||
| 105 | .Xr strtok 3 | ||
| 106 | function should be preferred for portability reasons (it conforms to | ||
| 107 | .St -ansiC ) | ||
| 108 | it is unable to handle empty fields, i.e., detect fields delimited by | ||
| 109 | two adjacent delimiter characters, or to be used for more than a single | ||
| 110 | string at a time. | ||
diff --git a/src/lib/libc/string/strsep.c b/src/lib/libc/string/strsep.c index 69be7fe046..2ffc4b4c46 100644 --- a/src/lib/libc/string/strsep.c +++ b/src/lib/libc/string/strsep.c | |||
| @@ -1,6 +1,8 @@ | |||
| 1 | /* $OpenBSD: strsep.c,v 1.7 2014/02/05 20:42:32 stsp Exp $ */ | ||
| 2 | |||
| 1 | /*- | 3 | /*- |
| 2 | * Copyright (c) 1990 The Regents of the University of California. | 4 | * Copyright (c) 1990, 1993 |
| 3 | * All rights reserved. | 5 | * The Regents of the University of California. All rights reserved. |
| 4 | * | 6 | * |
| 5 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without |
| 6 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions |
| @@ -10,11 +12,7 @@ | |||
| 10 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the |
| 12 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. All advertising materials mentioning features or use of this software | 15 | * 3. Neither the name of the University nor the names of its contributors |
| 14 | * must display the following acknowledgement: | ||
| 15 | * This product includes software developed by the University of | ||
| 16 | * California, Berkeley and its contributors. | ||
| 17 | * 4. Neither the name of the University nor the names of its contributors | ||
| 18 | * may be used to endorse or promote products derived from this software | 16 | * may be used to endorse or promote products derived from this software |
| 19 | * without specific prior written permission. | 17 | * without specific prior written permission. |
| 20 | * | 18 | * |
| @@ -31,15 +29,10 @@ | |||
| 31 | * SUCH DAMAGE. | 29 | * SUCH DAMAGE. |
| 32 | */ | 30 | */ |
| 33 | 31 | ||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 35 | /*static const char sccsid[] = "from: @(#)strsep.c 5.4 (Berkeley) 1/26/91";*/ | ||
| 36 | static char *rcsid = "$Id: strsep.c,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $"; | ||
| 37 | #endif /* LIBC_SCCS and not lint */ | ||
| 38 | |||
| 39 | #include <string.h> | 32 | #include <string.h> |
| 40 | 33 | ||
| 41 | /* | 34 | /* |
| 42 | * Get next token from string *stringp, where tokens are nonempty | 35 | * Get next token from string *stringp, where tokens are possibly-empty |
| 43 | * strings separated by characters from delim. | 36 | * strings separated by characters from delim. |
| 44 | * | 37 | * |
| 45 | * Writes NULs into the string at *stringp to end tokens. | 38 | * Writes NULs into the string at *stringp to end tokens. |
| @@ -47,16 +40,14 @@ static char *rcsid = "$Id: strsep.c,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $" | |||
| 47 | * On return, *stringp points past the last NUL written (if there might | 40 | * On return, *stringp points past the last NUL written (if there might |
| 48 | * be further tokens), or is NULL (if there are definitely no more tokens). | 41 | * be further tokens), or is NULL (if there are definitely no more tokens). |
| 49 | * | 42 | * |
| 50 | * If *stringp is NULL, strtoken returns NULL. | 43 | * If *stringp is NULL, strsep returns NULL. |
| 51 | */ | 44 | */ |
| 52 | char * | 45 | char * |
| 53 | strsep(stringp, delim) | 46 | strsep(char **stringp, const char *delim) |
| 54 | register char **stringp; | ||
| 55 | register const char *delim; | ||
| 56 | { | 47 | { |
| 57 | register char *s; | 48 | char *s; |
| 58 | register const char *spanp; | 49 | const char *spanp; |
| 59 | register int c, sc; | 50 | int c, sc; |
| 60 | char *tok; | 51 | char *tok; |
| 61 | 52 | ||
| 62 | if ((s = *stringp) == NULL) | 53 | if ((s = *stringp) == NULL) |
diff --git a/src/lib/libc/string/strsignal.3 b/src/lib/libc/string/strsignal.3 index 3287fef53e..3261f699d8 100644 --- a/src/lib/libc/string/strsignal.3 +++ b/src/lib/libc/string/strsignal.3 | |||
| @@ -13,11 +13,7 @@ | |||
| 13 | .\" 2. Redistributions in binary form must reproduce the above copyright | 13 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 14 | .\" notice, this list of conditions and the following disclaimer in the | 14 | .\" notice, this list of conditions and the following disclaimer in the |
| 15 | .\" documentation and/or other materials provided with the distribution. | 15 | .\" documentation and/or other materials provided with the distribution. |
| 16 | .\" 3. All advertising materials mentioning features or use of this software | 16 | .\" 3. Neither the name of the University nor the names of its contributors |
| 17 | .\" must display the following acknowledgement: | ||
| 18 | .\" This product includes software developed by the University of | ||
| 19 | .\" California, Berkeley and its contributors. | ||
| 20 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 21 | .\" may be used to endorse or promote products derived from this software | 17 | .\" may be used to endorse or promote products derived from this software |
| 22 | .\" without specific prior written permission. | 18 | .\" without specific prior written permission. |
| 23 | .\" | 19 | .\" |
| @@ -33,17 +29,16 @@ | |||
| 33 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 29 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 34 | .\" SUCH DAMAGE. | 30 | .\" SUCH DAMAGE. |
| 35 | .\" | 31 | .\" |
| 36 | .\" from: @(#)strerror.3 6.9 (Berkeley) 6/29/91 | 32 | .\" $OpenBSD: strsignal.3,v 1.8 2013/06/05 03:39:23 tedu Exp $ |
| 37 | .\" $Id: strsignal.3,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $ | ||
| 38 | .\" | 33 | .\" |
| 39 | .Dd June 29, 1991 | 34 | .Dd $Mdocdate: June 5 2013 $ |
| 40 | .Dt STRSIGNAL 3 | 35 | .Dt STRSIGNAL 3 |
| 41 | .Os BSD 4 | 36 | .Os |
| 42 | .Sh NAME | 37 | .Sh NAME |
| 43 | .Nm strsignal | 38 | .Nm strsignal |
| 44 | .Nd get signal description string | 39 | .Nd get signal description string |
| 45 | .Sh SYNOPSIS | 40 | .Sh SYNOPSIS |
| 46 | .Fd #include <string.h> | 41 | .In string.h |
| 47 | .Ft char * | 42 | .Ft char * |
| 48 | .Fn strsignal "int sig" | 43 | .Fn strsignal "int sig" |
| 49 | .Sh DESCRIPTION | 44 | .Sh DESCRIPTION |
| @@ -59,3 +54,15 @@ overwritten by subsequent calls to | |||
| 59 | .Xr intro 2 , | 54 | .Xr intro 2 , |
| 60 | .Xr psignal 3 , | 55 | .Xr psignal 3 , |
| 61 | .Xr setlocale 3 | 56 | .Xr setlocale 3 |
| 57 | .Sh STANDARDS | ||
| 58 | The | ||
| 59 | .Fn strsignal | ||
| 60 | function conforms to | ||
| 61 | .St -p1003.1-2008 . | ||
| 62 | .Sh HISTORY | ||
| 63 | The | ||
| 64 | .Fn strsignal | ||
| 65 | function first appeared in | ||
| 66 | .At V.4 | ||
| 67 | and was reimplemented for | ||
| 68 | .Nx 1.0 . | ||
diff --git a/src/lib/libc/string/strsignal.c b/src/lib/libc/string/strsignal.c index ec4a267edf..aa541cefed 100644 --- a/src/lib/libc/string/strsignal.c +++ b/src/lib/libc/string/strsignal.c | |||
| @@ -10,11 +10,7 @@ | |||
| 10 | * 2. Redistributions in binary form must reproduce the above copyright | 10 | * 2. Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in the | 11 | * notice, this list of conditions and the following disclaimer in the |
| 12 | * documentation and/or other materials provided with the distribution. | 12 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. All advertising materials mentioning features or use of this software | 13 | * 3. Neither the name of the University nor the names of its contributors |
| 14 | * must display the following acknowledgement: | ||
| 15 | * This product includes software developed by the University of | ||
| 16 | * California, Berkeley and its contributors. | ||
| 17 | * 4. Neither the name of the University nor the names of its contributors | ||
| 18 | * may be used to endorse or promote products derived from this software | 14 | * may be used to endorse or promote products derived from this software |
| 19 | * without specific prior written permission. | 15 | * without specific prior written permission. |
| 20 | * | 16 | * |
| @@ -31,20 +27,15 @@ | |||
| 31 | * SUCH DAMAGE. | 27 | * SUCH DAMAGE. |
| 32 | */ | 28 | */ |
| 33 | 29 | ||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 35 | /*static char *sccsid = "from: @(#)strerror.c 5.6 (Berkeley) 5/4/91";*/ | ||
| 36 | static char *rcsid = "$Id: strsignal.c,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $"; | ||
| 37 | #endif /* LIBC_SCCS and not lint */ | ||
| 38 | |||
| 39 | #include <string.h> | 30 | #include <string.h> |
| 40 | #include <limits.h> | 31 | #include <limits.h> |
| 41 | 32 | ||
| 42 | extern char *__strsignal __P((int, char *)); | 33 | extern char *__strsignal(int, char *); |
| 43 | 34 | ||
| 44 | char * | 35 | char * |
| 45 | strsignal(sig) | 36 | strsignal(int sig) |
| 46 | int sig; | ||
| 47 | { | 37 | { |
| 48 | static char buf[NL_TEXTMAX]; | 38 | static char buf[NL_TEXTMAX]; |
| 39 | |||
| 49 | return __strsignal(sig, buf); | 40 | return __strsignal(sig, buf); |
| 50 | } | 41 | } |
diff --git a/src/lib/libc/string/strspn.3 b/src/lib/libc/string/strspn.3 index 4de03aa58b..e339d9b6af 100644 --- a/src/lib/libc/string/strspn.3 +++ b/src/lib/libc/string/strspn.3 | |||
| @@ -1,3 +1,5 @@ | |||
| 1 | .\" $OpenBSD: strspn.3,v 1.11 2013/06/05 03:39:23 tedu Exp $ | ||
| 2 | .\" | ||
| 1 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. | 3 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. |
| 2 | .\" All rights reserved. | 4 | .\" All rights reserved. |
| 3 | .\" | 5 | .\" |
| @@ -13,11 +15,7 @@ | |||
| 13 | .\" 2. Redistributions in binary form must reproduce the above copyright | 15 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 14 | .\" notice, this list of conditions and the following disclaimer in the | 16 | .\" notice, this list of conditions and the following disclaimer in the |
| 15 | .\" documentation and/or other materials provided with the distribution. | 17 | .\" documentation and/or other materials provided with the distribution. |
| 16 | .\" 3. All advertising materials mentioning features or use of this software | 18 | .\" 3. Neither the name of the University nor the names of its contributors |
| 17 | .\" must display the following acknowledgement: | ||
| 18 | .\" This product includes software developed by the University of | ||
| 19 | .\" California, Berkeley and its contributors. | ||
| 20 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 21 | .\" may be used to endorse or promote products derived from this software | 19 | .\" may be used to endorse or promote products derived from this software |
| 22 | .\" without specific prior written permission. | 20 | .\" without specific prior written permission. |
| 23 | .\" | 21 | .\" |
| @@ -33,24 +31,20 @@ | |||
| 33 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 34 | .\" SUCH DAMAGE. | 32 | .\" SUCH DAMAGE. |
| 35 | .\" | 33 | .\" |
| 36 | .\" from: @(#)strspn.3 5.3 (Berkeley) 6/29/91 | 34 | .Dd $Mdocdate: June 5 2013 $ |
| 37 | .\" $Id: strspn.3,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $ | ||
| 38 | .\" | ||
| 39 | .Dd June 29, 1991 | ||
| 40 | .Dt STRSPN 3 | 35 | .Dt STRSPN 3 |
| 41 | .Os | 36 | .Os |
| 42 | .Sh NAME | 37 | .Sh NAME |
| 43 | .Nm strspn | 38 | .Nm strspn |
| 44 | .Nd span a string | 39 | .Nd span a string |
| 45 | .Sh SYNOPSIS | 40 | .Sh SYNOPSIS |
| 46 | .Fd #include <string.h> | 41 | .In string.h |
| 47 | .Ft size_t | 42 | .Ft size_t |
| 48 | .Fn strspn "const char *s" "const char *charset" | 43 | .Fn strspn "const char *s" "const char *charset" |
| 49 | .Sh DESCRIPTION | 44 | .Sh DESCRIPTION |
| 50 | The | 45 | The |
| 51 | .Xr strcspn | 46 | .Fn strspn |
| 52 | function | 47 | function spans the initial part of the NUL-terminated string |
| 53 | spans the initial part of the null-terminated string | ||
| 54 | .Fa s | 48 | .Fa s |
| 55 | as long as the characters from | 49 | as long as the characters from |
| 56 | .Fa s | 50 | .Fa s |
| @@ -59,22 +53,40 @@ occur in string | |||
| 59 | .Sh RETURN VALUES | 53 | .Sh RETURN VALUES |
| 60 | The | 54 | The |
| 61 | .Fn strspn | 55 | .Fn strspn |
| 62 | function | 56 | function returns the number of characters spanned. |
| 63 | returns the number of characters spanned. | 57 | .Sh EXAMPLES |
| 58 | The following call to | ||
| 59 | .Fn strspn | ||
| 60 | will return 3, since the first three characters of string | ||
| 61 | .Fa s | ||
| 62 | are part of string | ||
| 63 | .Fa charset : | ||
| 64 | .Bd -literal -offset indent | ||
| 65 | char *s = "foobar"; | ||
| 66 | char *charset = "of"; | ||
| 67 | size_t span; | ||
| 68 | |||
| 69 | span = strspn(s, charset); | ||
| 70 | .Ed | ||
| 64 | .Sh SEE ALSO | 71 | .Sh SEE ALSO |
| 65 | .Xr index 3 , | ||
| 66 | .Xr memchr 3 , | 72 | .Xr memchr 3 , |
| 67 | .Xr rindex 3 , | ||
| 68 | .Xr strchr 3 , | 73 | .Xr strchr 3 , |
| 69 | .Xr strcspn 3 , | 74 | .Xr strcspn 3 , |
| 70 | .Xr strpbrk 3 , | 75 | .Xr strpbrk 3 , |
| 71 | .Xr strrchr 3 , | 76 | .Xr strrchr 3 , |
| 72 | .Xr strsep 3 , | 77 | .Xr strsep 3 , |
| 73 | .Xr strstr 3 , | 78 | .Xr strstr 3 , |
| 74 | .Xr strtok 3 | 79 | .Xr strtok 3 , |
| 80 | .Xr wcsspn 3 | ||
| 75 | .Sh STANDARDS | 81 | .Sh STANDARDS |
| 76 | The | 82 | The |
| 77 | .Fn strspn | 83 | .Fn strspn |
| 78 | function | 84 | function conforms to |
| 79 | conforms to | ||
| 80 | .St -ansiC . | 85 | .St -ansiC . |
| 86 | .Sh HISTORY | ||
| 87 | The | ||
| 88 | .Fn strspn | ||
| 89 | function first appeared in | ||
| 90 | .At III | ||
| 91 | and was reimplemented for | ||
| 92 | .Bx 4.3 Tahoe . | ||
diff --git a/src/lib/libc/string/strspn.c b/src/lib/libc/string/strspn.c index 6224b25c2a..385649c041 100644 --- a/src/lib/libc/string/strspn.c +++ b/src/lib/libc/string/strspn.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: strspn.c,v 1.5 2005/08/08 08:05:37 espie Exp $ */ | ||
| 1 | /* | 2 | /* |
| 2 | * Copyright (c) 1989 The Regents of the University of California. | 3 | * Copyright (c) 1989 The Regents of the University of California. |
| 3 | * All rights reserved. | 4 | * All rights reserved. |
| @@ -10,11 +11,7 @@ | |||
| 10 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the |
| 12 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. Neither the name of the University nor the names of its contributors |
| 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 | 15 | * may be used to endorse or promote products derived from this software |
| 19 | * without specific prior written permission. | 16 | * without specific prior written permission. |
| 20 | * | 17 | * |
| @@ -31,23 +28,16 @@ | |||
| 31 | * SUCH DAMAGE. | 28 | * SUCH DAMAGE. |
| 32 | */ | 29 | */ |
| 33 | 30 | ||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 35 | /*static char *sccsid = "from: @(#)strspn.c 5.8 (Berkeley) 1/26/91";*/ | ||
| 36 | static char *rcsid = "$Id: strspn.c,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $"; | ||
| 37 | #endif /* LIBC_SCCS and not lint */ | ||
| 38 | |||
| 39 | #include <string.h> | 31 | #include <string.h> |
| 40 | 32 | ||
| 41 | /* | 33 | /* |
| 42 | * Span the string s2 (skip characters that are in s2). | 34 | * Span the string s2 (skip characters that are in s2). |
| 43 | */ | 35 | */ |
| 44 | size_t | 36 | size_t |
| 45 | strspn(s1, s2) | 37 | strspn(const char *s1, const char *s2) |
| 46 | const char *s1; | ||
| 47 | register const char *s2; | ||
| 48 | { | 38 | { |
| 49 | register const char *p = s1, *spanp; | 39 | const char *p = s1, *spanp; |
| 50 | register char c, sc; | 40 | char c, sc; |
| 51 | 41 | ||
| 52 | /* | 42 | /* |
| 53 | * Skip any characters in s2, excluding the terminating \0. | 43 | * Skip any characters in s2, excluding the terminating \0. |
diff --git a/src/lib/libc/string/strstr.3 b/src/lib/libc/string/strstr.3 index 24fdf540ed..1f79d45590 100644 --- a/src/lib/libc/string/strstr.3 +++ b/src/lib/libc/string/strstr.3 | |||
| @@ -1,3 +1,5 @@ | |||
| 1 | .\" $OpenBSD: strstr.3,v 1.12 2013/06/05 03:39:23 tedu Exp $ | ||
| 2 | .\" | ||
| 1 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. | 3 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. |
| 2 | .\" All rights reserved. | 4 | .\" All rights reserved. |
| 3 | .\" | 5 | .\" |
| @@ -13,11 +15,7 @@ | |||
| 13 | .\" 2. Redistributions in binary form must reproduce the above copyright | 15 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 14 | .\" notice, this list of conditions and the following disclaimer in the | 16 | .\" notice, this list of conditions and the following disclaimer in the |
| 15 | .\" documentation and/or other materials provided with the distribution. | 17 | .\" documentation and/or other materials provided with the distribution. |
| 16 | .\" 3. All advertising materials mentioning features or use of this software | 18 | .\" 3. Neither the name of the University nor the names of its contributors |
| 17 | .\" must display the following acknowledgement: | ||
| 18 | .\" This product includes software developed by the University of | ||
| 19 | .\" California, Berkeley and its contributors. | ||
| 20 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 21 | .\" may be used to endorse or promote products derived from this software | 19 | .\" may be used to endorse or promote products derived from this software |
| 22 | .\" without specific prior written permission. | 20 | .\" without specific prior written permission. |
| 23 | .\" | 21 | .\" |
| @@ -33,57 +31,70 @@ | |||
| 33 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 34 | .\" SUCH DAMAGE. | 32 | .\" SUCH DAMAGE. |
| 35 | .\" | 33 | .\" |
| 36 | .\" from: @(#)strstr.3 5.3 (Berkeley) 6/29/91 | 34 | .Dd $Mdocdate: June 5 2013 $ |
| 37 | .\" $Id: strstr.3,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $ | ||
| 38 | .\" | ||
| 39 | .Dd June 29, 1991 | ||
| 40 | .Dt STRSTR 3 | 35 | .Dt STRSTR 3 |
| 41 | .Os | 36 | .Os |
| 42 | .Sh NAME | 37 | .Sh NAME |
| 43 | .Nm strstr | 38 | .Nm strstr , strcasestr |
| 44 | .Nd locate a substring in a string | 39 | .Nd locate a substring in a string |
| 45 | .Sh SYNOPSIS | 40 | .Sh SYNOPSIS |
| 46 | .Fd #include <string.h> | 41 | .In string.h |
| 47 | .Ft char * | 42 | .Ft char * |
| 48 | .Fn strstr "const char *big" "const char *little" | 43 | .Fn strstr "const char *big" "const char *little" |
| 44 | .Ft char * | ||
| 45 | .Fn strcasestr "const char *big" "const char *little" | ||
| 49 | .Sh DESCRIPTION | 46 | .Sh DESCRIPTION |
| 50 | The | 47 | The |
| 51 | .Fn strstr | 48 | .Fn strstr |
| 52 | function | 49 | function locates the first occurrence of the NUL-terminated string |
| 53 | locates the first occurrence of the null-terminated string | ||
| 54 | .Fa little | 50 | .Fa little |
| 55 | in the null-terminated string | 51 | in the NUL-terminated string |
| 56 | .Fa big . | 52 | .Fa big . |
| 53 | .Pp | ||
| 54 | The | ||
| 55 | .Fn strcasestr | ||
| 56 | function is similar to | ||
| 57 | .Fn strstr | ||
| 58 | but ignores the case of both strings. | ||
| 59 | .Pp | ||
| 57 | If | 60 | If |
| 58 | .Fa little | 61 | .Fa little |
| 59 | is the empty string, | 62 | is an empty string, |
| 60 | .Fn strstr | 63 | .Fa big |
| 61 | returns | 64 | is returned; |
| 62 | .Fa big ; | ||
| 63 | if | 65 | if |
| 64 | .Fa little | 66 | .Fa little |
| 65 | occurs nowhere in | 67 | occurs nowhere in |
| 66 | .Fa big , | 68 | .Fa big , |
| 67 | .Fn strstr | 69 | .Dv NULL |
| 68 | returns NULL; | 70 | is returned; |
| 69 | otherwise | 71 | otherwise a pointer to the first character of the first occurrence of |
| 70 | .Fn strstr | 72 | .Fa little |
| 71 | returns a pointer to the first character of the first occurrence of | 73 | is returned. |
| 72 | .Fa little . | ||
| 73 | .Sh SEE ALSO | 74 | .Sh SEE ALSO |
| 74 | .Xr index 3 , | ||
| 75 | .Xr memchr 3 , | 75 | .Xr memchr 3 , |
| 76 | .Xr rindex 3 , | ||
| 77 | .Xr strchr 3 , | 76 | .Xr strchr 3 , |
| 78 | .Xr strcspn 3 , | 77 | .Xr strcspn 3 , |
| 79 | .Xr strpbrk 3 , | 78 | .Xr strpbrk 3 , |
| 80 | .Xr strrchr 3 , | 79 | .Xr strrchr 3 , |
| 81 | .Xr strsep 3 , | 80 | .Xr strsep 3 , |
| 82 | .Xr strspn 3 , | 81 | .Xr strspn 3 , |
| 83 | .Xr strtok 3 | 82 | .Xr strtok 3 , |
| 83 | .Xr wcsstr 3 | ||
| 84 | .Sh STANDARDS | 84 | .Sh STANDARDS |
| 85 | The | 85 | The |
| 86 | .Fn strstr | 86 | .Fn strstr |
| 87 | function | 87 | function conforms to |
| 88 | conforms to | ||
| 89 | .St -ansiC . | 88 | .St -ansiC . |
| 89 | .Sh HISTORY | ||
| 90 | The | ||
| 91 | .Fn strstr | ||
| 92 | function first appeared in | ||
| 93 | .Bx 4.3 Reno . | ||
| 94 | The | ||
| 95 | .Fn strcasestr | ||
| 96 | function appeared in glibc 2.1, | ||
| 97 | was reimplemented for | ||
| 98 | .Fx 4.5 | ||
| 99 | and ported to | ||
| 100 | .Ox 3.8 . | ||
diff --git a/src/lib/libc/string/strstr.c b/src/lib/libc/string/strstr.c index 1ed59e357b..95a865bf79 100644 --- a/src/lib/libc/string/strstr.c +++ b/src/lib/libc/string/strstr.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: strstr.c,v 1.5 2005/08/08 08:05:37 espie Exp $ */ | ||
| 1 | /*- | 2 | /*- |
| 2 | * Copyright (c) 1990 The Regents of the University of California. | 3 | * Copyright (c) 1990 The Regents of the University of California. |
| 3 | * All rights reserved. | 4 | * All rights reserved. |
| @@ -13,11 +14,7 @@ | |||
| 13 | * 2. Redistributions in binary form must reproduce the above copyright | 14 | * 2. Redistributions in binary form must reproduce the above copyright |
| 14 | * notice, this list of conditions and the following disclaimer in the | 15 | * notice, this list of conditions and the following disclaimer in the |
| 15 | * documentation and/or other materials provided with the distribution. | 16 | * documentation and/or other materials provided with the distribution. |
| 16 | * 3. All advertising materials mentioning features or use of this software | 17 | * 3. Neither the name of the University nor the names of its contributors |
| 17 | * must display the following acknowledgement: | ||
| 18 | * This product includes software developed by the University of | ||
| 19 | * California, Berkeley and its contributors. | ||
| 20 | * 4. Neither the name of the University nor the names of its contributors | ||
| 21 | * may be used to endorse or promote products derived from this software | 18 | * may be used to endorse or promote products derived from this software |
| 22 | * without specific prior written permission. | 19 | * without specific prior written permission. |
| 23 | * | 20 | * |
| @@ -34,22 +31,16 @@ | |||
| 34 | * SUCH DAMAGE. | 31 | * SUCH DAMAGE. |
| 35 | */ | 32 | */ |
| 36 | 33 | ||
| 37 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 38 | /*static char *sccsid = "from: @(#)strstr.c 5.2 (Berkeley) 1/26/91";*/ | ||
| 39 | static char *rcsid = "$Id: strstr.c,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $"; | ||
| 40 | #endif /* LIBC_SCCS and not lint */ | ||
| 41 | |||
| 42 | #include <string.h> | 34 | #include <string.h> |
| 43 | 35 | ||
| 44 | /* | 36 | /* |
| 45 | * Find the first occurrence of find in s. | 37 | * Find the first occurrence of find in s. |
| 46 | */ | 38 | */ |
| 47 | char * | 39 | char * |
| 48 | strstr(s, find) | 40 | strstr(const char *s, const char *find) |
| 49 | register const char *s, *find; | ||
| 50 | { | 41 | { |
| 51 | register char c, sc; | 42 | char c, sc; |
| 52 | register size_t len; | 43 | size_t len; |
| 53 | 44 | ||
| 54 | if ((c = *find++) != 0) { | 45 | if ((c = *find++) != 0) { |
| 55 | len = strlen(find); | 46 | len = strlen(find); |
diff --git a/src/lib/libc/string/strtok.3 b/src/lib/libc/string/strtok.3 index 644bd10aed..046a43b6b1 100644 --- a/src/lib/libc/string/strtok.3 +++ b/src/lib/libc/string/strtok.3 | |||
| @@ -1,3 +1,5 @@ | |||
| 1 | .\" $OpenBSD: strtok.3,v 1.21 2013/06/05 03:39:23 tedu Exp $ | ||
| 2 | .\" | ||
| 1 | .\" Copyright (c) 1988, 1991 The Regents of the University of California. | 3 | .\" Copyright (c) 1988, 1991 The Regents of the University of California. |
| 2 | .\" All rights reserved. | 4 | .\" All rights reserved. |
| 3 | .\" | 5 | .\" |
| @@ -13,11 +15,7 @@ | |||
| 13 | .\" 2. Redistributions in binary form must reproduce the above copyright | 15 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 14 | .\" notice, this list of conditions and the following disclaimer in the | 16 | .\" notice, this list of conditions and the following disclaimer in the |
| 15 | .\" documentation and/or other materials provided with the distribution. | 17 | .\" documentation and/or other materials provided with the distribution. |
| 16 | .\" 3. All advertising materials mentioning features or use of this software | 18 | .\" 3. Neither the name of the University nor the names of its contributors |
| 17 | .\" must display the following acknowledgement: | ||
| 18 | .\" This product includes software developed by the University of | ||
| 19 | .\" California, Berkeley and its contributors. | ||
| 20 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 21 | .\" may be used to endorse or promote products derived from this software | 19 | .\" may be used to endorse or promote products derived from this software |
| 22 | .\" without specific prior written permission. | 20 | .\" without specific prior written permission. |
| 23 | .\" | 21 | .\" |
| @@ -33,29 +31,28 @@ | |||
| 33 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 34 | .\" SUCH DAMAGE. | 32 | .\" SUCH DAMAGE. |
| 35 | .\" | 33 | .\" |
| 36 | .\" from: @(#)strtok.3 5.8 (Berkeley) 6/29/91 | 34 | .Dd $Mdocdate: June 5 2013 $ |
| 37 | .\" $Id: strtok.3,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $ | ||
| 38 | .\" | ||
| 39 | .Dd June 29, 1991 | ||
| 40 | .Dt STRTOK 3 | 35 | .Dt STRTOK 3 |
| 41 | .Os BSD 3 | 36 | .Os |
| 42 | .Sh NAME | 37 | .Sh NAME |
| 43 | .Nm strtok , | 38 | .Nm strtok , |
| 44 | .Nm strsep | 39 | .Nm strtok_r |
| 45 | .Nd string token operations | 40 | .Nd string token operations |
| 46 | .Sh SYNOPSIS | 41 | .Sh SYNOPSIS |
| 47 | .Fd #include <string.h> | 42 | .In string.h |
| 48 | .Ft char * | 43 | .Ft char * |
| 49 | .Fn strtok "char *str" "const char *sep" | 44 | .Fn strtok "char *str" "const char *sep" |
| 45 | .Ft char * | ||
| 46 | .Fn strtok_r "char *str" "const char *sep" "char **last" | ||
| 50 | .Sh DESCRIPTION | 47 | .Sh DESCRIPTION |
| 51 | .Bf -symbolic | 48 | .Bf -symbolic |
| 52 | This interface is obsoleted by strsep(3). | 49 | This interface is obsoleted by |
| 50 | .Xr strsep 3 . | ||
| 53 | .Ef | 51 | .Ef |
| 54 | .Pp | 52 | .Pp |
| 55 | The | 53 | The |
| 56 | .Fn strtok | 54 | .Fn strtok |
| 57 | function | 55 | function is used to isolate sequential tokens in a NUL-terminated string, |
| 58 | is used to isolate sequential tokens in a null-terminated string, | ||
| 59 | .Fa str . | 56 | .Fa str . |
| 60 | These tokens are separated in the string by at least one of the | 57 | These tokens are separated in the string by at least one of the |
| 61 | characters in | 58 | characters in |
| @@ -71,42 +68,99 @@ The separator string, | |||
| 71 | must be supplied each time, and may change between calls. | 68 | must be supplied each time, and may change between calls. |
| 72 | .Pp | 69 | .Pp |
| 73 | The | 70 | The |
| 71 | .Fn strtok_r | ||
| 72 | function is a version of | ||
| 74 | .Fn strtok | 73 | .Fn strtok |
| 75 | function | 74 | that takes an explicit context argument and is reentrant. |
| 76 | returns a pointer to the beginning of each subsequent token in the string, | 75 | .Pp |
| 77 | after replacing the separator character itself with a | 76 | Since |
| 78 | .Dv NUL | 77 | .Fn strtok |
| 78 | and | ||
| 79 | .Fn strtok_r | ||
| 80 | modify the string, | ||
| 81 | .Fa str | ||
| 82 | should not point to an area in the initialized data segment. | ||
| 83 | .Sh RETURN VALUES | ||
| 84 | The | ||
| 85 | .Fn strtok | ||
| 86 | and | ||
| 87 | .Fn strtok_r | ||
| 88 | functions return a pointer to the beginning of each subsequent token | ||
| 89 | in the string, after replacing the separator character itself with an | ||
| 90 | .Tn ASCII NUL | ||
| 79 | character. | 91 | character. |
| 80 | When no more tokens remain, a null pointer is returned. | 92 | When no more tokens remain, a null pointer is returned. |
| 93 | .Sh EXAMPLES | ||
| 94 | The following will construct an array of pointers to each individual word in | ||
| 95 | the string | ||
| 96 | .Va s : | ||
| 97 | .Bd -literal -offset indent | ||
| 98 | #define MAXTOKENS 128 | ||
| 99 | |||
| 100 | char s[512], *p, *tokens[MAXTOKENS]; | ||
| 101 | char *last; | ||
| 102 | int i = 0; | ||
| 103 | |||
| 104 | snprintf(s, sizeof(s), "cat dog horse cow"); | ||
| 105 | |||
| 106 | for ((p = strtok_r(s, " ", &last)); p; | ||
| 107 | (p = strtok_r(NULL, " ", &last))) { | ||
| 108 | if (i < MAXTOKENS - 1) | ||
| 109 | tokens[i++] = p; | ||
| 110 | } | ||
| 111 | tokens[i] = NULL; | ||
| 112 | .Ed | ||
| 113 | .Pp | ||
| 114 | That is, | ||
| 115 | .Li tokens[0] | ||
| 116 | will point to | ||
| 117 | .Qq cat , | ||
| 118 | .Li tokens[1] | ||
| 119 | will point to | ||
| 120 | .Qq dog , | ||
| 121 | .Li tokens[2] | ||
| 122 | will point to | ||
| 123 | .Qq horse , | ||
| 124 | and | ||
| 125 | .Li tokens[3] | ||
| 126 | will point to | ||
| 127 | .Qq cow . | ||
| 81 | .Sh SEE ALSO | 128 | .Sh SEE ALSO |
| 82 | .Xr index 3 , | ||
| 83 | .Xr memchr 3 , | 129 | .Xr memchr 3 , |
| 84 | .Xr rindex 3 , | ||
| 85 | .Xr strchr 3 , | 130 | .Xr strchr 3 , |
| 86 | .Xr strcspn 3 , | 131 | .Xr strcspn 3 , |
| 87 | .Xr strpbrk 3 , | 132 | .Xr strpbrk 3 , |
| 88 | .Xr strrchr 3 , | 133 | .Xr strrchr 3 , |
| 89 | .Xr strsep 3 , | 134 | .Xr strsep 3 , |
| 90 | .Xr strspn 3 , | 135 | .Xr strspn 3 , |
| 91 | .Xr strstr 3 | 136 | .Xr strstr 3 , |
| 137 | .Xr wcstok 3 | ||
| 92 | .Sh STANDARDS | 138 | .Sh STANDARDS |
| 93 | The | 139 | The |
| 94 | .Fn strtok | 140 | .Fn strtok |
| 95 | function | 141 | function conforms to |
| 96 | conforms to | ||
| 97 | .St -ansiC . | 142 | .St -ansiC . |
| 143 | .Sh HISTORY | ||
| 144 | The | ||
| 145 | .Fn strtok | ||
| 146 | function first appeared in | ||
| 147 | .At III | ||
| 148 | and was reimplemented for | ||
| 149 | .Bx 4.3 Tahoe . | ||
| 150 | The | ||
| 151 | .Fn strtok_r | ||
| 152 | function first appeared in | ||
| 153 | .Nx 1.3 | ||
| 154 | and was reimplemented for | ||
| 155 | .Ox 2.7 . | ||
| 98 | .Sh BUGS | 156 | .Sh BUGS |
| 99 | There is no way to get tokens from multiple strings simultaneously. | ||
| 100 | .Pp | ||
| 101 | The System V | 157 | The System V |
| 102 | .Fn strtok , | 158 | .Fn strtok , |
| 103 | if handed a string containing only delimiter characters, | 159 | if handed a string containing only delimiter characters, |
| 104 | will not alter the next starting point, so that a call to | 160 | will not alter the next starting point, so that a call to |
| 105 | .Fn strtok | 161 | .Fn strtok |
| 106 | with a different (or empty) delimiter string | 162 | with a different (or empty) delimiter string |
| 107 | may return a | 163 | may return a non-null value. |
| 108 | .Pf non- Dv NULL | ||
| 109 | value. | ||
| 110 | Since this implementation always alters the next starting point, | 164 | Since this implementation always alters the next starting point, |
| 111 | such a sequence of calls would always return | 165 | such a sequence of calls would always return |
| 112 | .Dv NULL . | 166 | .Dv NULL . |
diff --git a/src/lib/libc/string/strtok.c b/src/lib/libc/string/strtok.c index 9f712579bf..4e963a019e 100644 --- a/src/lib/libc/string/strtok.c +++ b/src/lib/libc/string/strtok.c | |||
| @@ -10,11 +10,7 @@ | |||
| 10 | * 2. Redistributions in binary form must reproduce the above copyright | 10 | * 2. Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in the | 11 | * notice, this list of conditions and the following disclaimer in the |
| 12 | * documentation and/or other materials provided with the distribution. | 12 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. All advertising materials mentioning features or use of this software | 13 | * 3. Neither the name of the University nor the names of its contributors |
| 14 | * must display the following acknowledgement: | ||
| 15 | * This product includes software developed by the University of | ||
| 16 | * California, Berkeley and its contributors. | ||
| 17 | * 4. Neither the name of the University nor the names of its contributors | ||
| 18 | * may be used to endorse or promote products derived from this software | 14 | * may be used to endorse or promote products derived from this software |
| 19 | * without specific prior written permission. | 15 | * without specific prior written permission. |
| 20 | * | 16 | * |
| @@ -31,25 +27,25 @@ | |||
| 31 | * SUCH DAMAGE. | 27 | * SUCH DAMAGE. |
| 32 | */ | 28 | */ |
| 33 | 29 | ||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 35 | /*static char *sccsid = "from: @(#)strtok.c 5.8 (Berkeley) 2/24/91";*/ | ||
| 36 | static char *rcsid = "$Id: strtok.c,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $"; | ||
| 37 | #endif /* LIBC_SCCS and not lint */ | ||
| 38 | |||
| 39 | #include <string.h> | 30 | #include <string.h> |
| 40 | 31 | ||
| 41 | char * | 32 | char * |
| 42 | strtok(s, delim) | 33 | strtok(char *s, const char *delim) |
| 43 | register char *s; | ||
| 44 | register const char *delim; | ||
| 45 | { | 34 | { |
| 46 | register char *spanp; | ||
| 47 | register int c, sc; | ||
| 48 | char *tok; | ||
| 49 | static char *last; | 35 | static char *last; |
| 50 | 36 | ||
| 37 | return strtok_r(s, delim, &last); | ||
| 38 | } | ||
| 39 | |||
| 40 | char * | ||
| 41 | strtok_r(char *s, const char *delim, char **last) | ||
| 42 | { | ||
| 43 | char *spanp; | ||
| 44 | int c, sc; | ||
| 45 | char *tok; | ||
| 46 | |||
| 51 | 47 | ||
| 52 | if (s == NULL && (s = last) == NULL) | 48 | if (s == NULL && (s = *last) == NULL) |
| 53 | return (NULL); | 49 | return (NULL); |
| 54 | 50 | ||
| 55 | /* | 51 | /* |
| @@ -63,7 +59,7 @@ cont: | |||
| 63 | } | 59 | } |
| 64 | 60 | ||
| 65 | if (c == 0) { /* no non-delimiter characters */ | 61 | if (c == 0) { /* no non-delimiter characters */ |
| 66 | last = NULL; | 62 | *last = NULL; |
| 67 | return (NULL); | 63 | return (NULL); |
| 68 | } | 64 | } |
| 69 | tok = s - 1; | 65 | tok = s - 1; |
| @@ -81,7 +77,7 @@ cont: | |||
| 81 | s = NULL; | 77 | s = NULL; |
| 82 | else | 78 | else |
| 83 | s[-1] = 0; | 79 | s[-1] = 0; |
| 84 | last = s; | 80 | *last = s; |
| 85 | return (tok); | 81 | return (tok); |
| 86 | } | 82 | } |
| 87 | } while (sc != 0); | 83 | } while (sc != 0); |
diff --git a/src/lib/libc/string/strxfrm.3 b/src/lib/libc/string/strxfrm.3 index 84fd945472..481f741cb7 100644 --- a/src/lib/libc/string/strxfrm.3 +++ b/src/lib/libc/string/strxfrm.3 | |||
| @@ -13,11 +13,7 @@ | |||
| 13 | .\" 2. Redistributions in binary form must reproduce the above copyright | 13 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 14 | .\" notice, this list of conditions and the following disclaimer in the | 14 | .\" notice, this list of conditions and the following disclaimer in the |
| 15 | .\" documentation and/or other materials provided with the distribution. | 15 | .\" documentation and/or other materials provided with the distribution. |
| 16 | .\" 3. All advertising materials mentioning features or use of this software | 16 | .\" 3. Neither the name of the University nor the names of its contributors |
| 17 | .\" must display the following acknowledgement: | ||
| 18 | .\" This product includes software developed by the University of | ||
| 19 | .\" California, Berkeley and its contributors. | ||
| 20 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 21 | .\" may be used to endorse or promote products derived from this software | 17 | .\" may be used to endorse or promote products derived from this software |
| 22 | .\" without specific prior written permission. | 18 | .\" without specific prior written permission. |
| 23 | .\" | 19 | .\" |
| @@ -33,37 +29,51 @@ | |||
| 33 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 29 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 34 | .\" SUCH DAMAGE. | 30 | .\" SUCH DAMAGE. |
| 35 | .\" | 31 | .\" |
| 36 | .\" from: @(#)strxfrm.3 5.4 (Berkeley) 6/29/91 | 32 | .\" $OpenBSD: strxfrm.3,v 1.10 2013/06/05 03:39:23 tedu Exp $ |
| 37 | .\" $Id: strxfrm.3,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $ | ||
| 38 | .\" | 33 | .\" |
| 39 | .Dd June 29, 1991 | 34 | .Dd $Mdocdate: June 5 2013 $ |
| 40 | .Dt STRXFRM 3 | 35 | .Dt STRXFRM 3 |
| 41 | .Os | 36 | .Os |
| 42 | .Sh NAME | 37 | .Sh NAME |
| 43 | .Nm strxfrm | 38 | .Nm strxfrm |
| 44 | .Nd transform a string under locale | 39 | .Nd transform a string under locale |
| 45 | .Sh SYNOPSIS | 40 | .Sh SYNOPSIS |
| 46 | .Fd #include <string.h> | 41 | .In string.h |
| 47 | .Ft size_t | 42 | .Ft size_t |
| 48 | .Fn strxfrm "char *dst" "const char *src" "size_t n" | 43 | .Fn strxfrm "char *dst" "const char *src" "size_t n" |
| 49 | .Sh DESCRIPTION | 44 | .Sh DESCRIPTION |
| 50 | The | 45 | The idea of |
| 51 | .Fn strxfrm | 46 | .Fn strxfrm |
| 52 | function | 47 | is to |
| 53 | does something horrible (see | 48 | .Dq un-localize |
| 54 | .Tn ANSI | 49 | a string: the function transforms |
| 55 | standard). | 50 | .Ar src , |
| 56 | In this implementation it just copies. | 51 | storing the result in |
| 52 | .Ar dst , | ||
| 53 | such that | ||
| 54 | .Xr strcmp 3 | ||
| 55 | on transformed strings returns what | ||
| 56 | .Xr strcoll 3 | ||
| 57 | on the original untransformed strings would return. | ||
| 57 | .Sh SEE ALSO | 58 | .Sh SEE ALSO |
| 58 | .Xr bcmp 3 , | 59 | .Xr bcmp 3 , |
| 59 | .Xr memcmp 3 , | 60 | .Xr memcmp 3 , |
| 60 | .\" .Xr setlocale 3 , | 61 | .Xr setlocale 3 , |
| 61 | .Xr strcasecmp 3 , | 62 | .Xr strcasecmp 3 , |
| 62 | .Xr strcmp 3 , | 63 | .Xr strcmp 3 , |
| 63 | .Xr strcoll 3 | 64 | .Xr strcoll 3 |
| 64 | .Sh STANDARDS | 65 | .Sh STANDARDS |
| 65 | The | 66 | The |
| 66 | .Fn strxfrm | 67 | .Fn strxfrm |
| 67 | function | 68 | function conforms to |
| 68 | conforms to | ||
| 69 | .St -ansiC . | 69 | .St -ansiC . |
| 70 | .Sh HISTORY | ||
| 71 | The | ||
| 72 | .Fn strxfrm | ||
| 73 | function first appeared in | ||
| 74 | .Bx 4.3 Reno . | ||
| 75 | .Sh BUGS | ||
| 76 | Since locales are not fully implemented on | ||
| 77 | .Ox , | ||
| 78 | .Fn strxfrm | ||
| 79 | just returns a copy of the original string. | ||
diff --git a/src/lib/libc/string/strxfrm.c b/src/lib/libc/string/strxfrm.c index d9df77b957..6f289c901e 100644 --- a/src/lib/libc/string/strxfrm.c +++ b/src/lib/libc/string/strxfrm.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: strxfrm.c,v 1.6 2005/08/08 08:05:37 espie Exp $ */ | ||
| 1 | /*- | 2 | /*- |
| 2 | * Copyright (c) 1990 The Regents of the University of California. | 3 | * Copyright (c) 1990 The Regents of the University of California. |
| 3 | * All rights reserved. | 4 | * All rights reserved. |
| @@ -13,11 +14,7 @@ | |||
| 13 | * 2. Redistributions in binary form must reproduce the above copyright | 14 | * 2. Redistributions in binary form must reproduce the above copyright |
| 14 | * notice, this list of conditions and the following disclaimer in the | 15 | * notice, this list of conditions and the following disclaimer in the |
| 15 | * documentation and/or other materials provided with the distribution. | 16 | * documentation and/or other materials provided with the distribution. |
| 16 | * 3. All advertising materials mentioning features or use of this software | 17 | * 3. Neither the name of the University nor the names of its contributors |
| 17 | * must display the following acknowledgement: | ||
| 18 | * This product includes software developed by the University of | ||
| 19 | * California, Berkeley and its contributors. | ||
| 20 | * 4. Neither the name of the University nor the names of its contributors | ||
| 21 | * may be used to endorse or promote products derived from this software | 18 | * may be used to endorse or promote products derived from this software |
| 22 | * without specific prior written permission. | 19 | * without specific prior written permission. |
| 23 | * | 20 | * |
| @@ -34,11 +31,6 @@ | |||
| 34 | * SUCH DAMAGE. | 31 | * SUCH DAMAGE. |
| 35 | */ | 32 | */ |
| 36 | 33 | ||
| 37 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 38 | /*static char *sccsid = "from: @(#)strxfrm.c 5.2 (Berkeley) 1/26/91";*/ | ||
| 39 | static char *rcsid = "$Id: strxfrm.c,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $"; | ||
| 40 | #endif /* LIBC_SCCS and not lint */ | ||
| 41 | |||
| 42 | #include <string.h> | 34 | #include <string.h> |
| 43 | 35 | ||
| 44 | /* | 36 | /* |
| @@ -47,28 +39,13 @@ static char *rcsid = "$Id: strxfrm.c,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $ | |||
| 47 | * on the original untransformed strings would return. | 39 | * on the original untransformed strings would return. |
| 48 | */ | 40 | */ |
| 49 | size_t | 41 | size_t |
| 50 | strxfrm(dst, src, n) | 42 | strxfrm(char *dst, const char *src, size_t n) |
| 51 | register char *dst; | ||
| 52 | register const char *src; | ||
| 53 | register size_t n; | ||
| 54 | { | 43 | { |
| 55 | register size_t r = 0; | ||
| 56 | register int c; | ||
| 57 | 44 | ||
| 58 | /* | 45 | /* |
| 59 | * Since locales are unimplemented, this is just a copy. | 46 | * Since locales are unimplemented, this is just a copy. |
| 60 | */ | 47 | */ |
| 61 | if (n != 0) { | 48 | if (n == 0) |
| 62 | while ((c = *src++) != 0) { | 49 | return (strlen(src)); |
| 63 | r++; | 50 | return (strlcpy(dst, src, n)); |
| 64 | if (--n == 0) { | ||
| 65 | while (*src++ != 0) | ||
| 66 | r++; | ||
| 67 | break; | ||
| 68 | } | ||
| 69 | *dst++ = c; | ||
| 70 | } | ||
| 71 | *dst = 0; | ||
| 72 | } | ||
| 73 | return (r); | ||
| 74 | } | 51 | } |
diff --git a/src/lib/libc/string/swab.3 b/src/lib/libc/string/swab.3 index 133c487bbd..77e5a9ccbc 100644 --- a/src/lib/libc/string/swab.3 +++ b/src/lib/libc/string/swab.3 | |||
| @@ -9,11 +9,7 @@ | |||
| 9 | .\" 2. Redistributions in binary form must reproduce the above copyright | 9 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 10 | .\" notice, this list of conditions and the following disclaimer in the | 10 | .\" notice, this list of conditions and the following disclaimer in the |
| 11 | .\" documentation and/or other materials provided with the distribution. | 11 | .\" documentation and/or other materials provided with the distribution. |
| 12 | .\" 3. All advertising materials mentioning features or use of this software | 12 | .\" 3. Neither the name of the University nor the names of its contributors |
| 13 | .\" must display the following acknowledgement: | ||
| 14 | .\" This product includes software developed by the University of | ||
| 15 | .\" California, Berkeley and its contributors. | ||
| 16 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 17 | .\" may be used to endorse or promote products derived from this software | 13 | .\" may be used to endorse or promote products derived from this software |
| 18 | .\" without specific prior written permission. | 14 | .\" without specific prior written permission. |
| 19 | .\" | 15 | .\" |
| @@ -29,17 +25,16 @@ | |||
| 29 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 25 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 30 | .\" SUCH DAMAGE. | 26 | .\" SUCH DAMAGE. |
| 31 | .\" | 27 | .\" |
| 32 | .\" from: @(#)swab.3 6.6 (Berkeley) 5/1/91 | 28 | .\" $OpenBSD: swab.3,v 1.8 2013/06/05 03:39:23 tedu Exp $ |
| 33 | .\" $Id: swab.3,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $ | ||
| 34 | .\" | 29 | .\" |
| 35 | .Dd May 1, 1991 | 30 | .Dd $Mdocdate: June 5 2013 $ |
| 36 | .Dt SWAB 3 | 31 | .Dt SWAB 3 |
| 37 | .Os | 32 | .Os |
| 38 | .Sh NAME | 33 | .Sh NAME |
| 39 | .Nm swab | 34 | .Nm swab |
| 40 | .Nd swap adjacent bytes | 35 | .Nd swap adjacent bytes |
| 41 | .Sh SYNOPSIS | 36 | .Sh SYNOPSIS |
| 42 | .Fd #include <string.h> | 37 | .In unistd.h |
| 43 | .Ft void | 38 | .Ft void |
| 44 | .Fn swab "const void *src" "void *dst" "size_t len" | 39 | .Fn swab "const void *src" "void *dst" "size_t len" |
| 45 | .Sh DESCRIPTION | 40 | .Sh DESCRIPTION |
| @@ -55,12 +50,12 @@ swapping adjacent bytes. | |||
| 55 | .Pp | 50 | .Pp |
| 56 | The argument | 51 | The argument |
| 57 | .Fa len | 52 | .Fa len |
| 58 | must be even number. | 53 | must be an even number. |
| 59 | .Sh SEE ALSO | 54 | .Sh SEE ALSO |
| 60 | .Xr bzero 3 , | 55 | .Xr bzero 3 , |
| 61 | .Xr memset 3 | 56 | .Xr memset 3 |
| 62 | .Sh HISTORY | 57 | .Sh HISTORY |
| 63 | A | 58 | The |
| 64 | .Fn swab | 59 | .Fn swab |
| 65 | function appeared in | 60 | function first appeared in |
| 66 | .At v7 . | 61 | .At v7 . |
diff --git a/src/lib/libc/string/swab.c b/src/lib/libc/string/swab.c index f33fc53bd6..b74db7e62a 100644 --- a/src/lib/libc/string/swab.c +++ b/src/lib/libc/string/swab.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: swab.c,v 1.8 2008/03/15 21:54:09 ray Exp $ */ | ||
| 1 | /* | 2 | /* |
| 2 | * Copyright (c) 1988 Regents of the University of California. | 3 | * Copyright (c) 1988 Regents of the University of California. |
| 3 | * All rights reserved. | 4 | * All rights reserved. |
| @@ -13,11 +14,7 @@ | |||
| 13 | * 2. Redistributions in binary form must reproduce the above copyright | 14 | * 2. Redistributions in binary form must reproduce the above copyright |
| 14 | * notice, this list of conditions and the following disclaimer in the | 15 | * notice, this list of conditions and the following disclaimer in the |
| 15 | * documentation and/or other materials provided with the distribution. | 16 | * documentation and/or other materials provided with the distribution. |
| 16 | * 3. All advertising materials mentioning features or use of this software | 17 | * 3. Neither the name of the University nor the names of its contributors |
| 17 | * must display the following acknowledgement: | ||
| 18 | * This product includes software developed by the University of | ||
| 19 | * California, Berkeley and its contributors. | ||
| 20 | * 4. Neither the name of the University nor the names of its contributors | ||
| 21 | * may be used to endorse or promote products derived from this software | 18 | * may be used to endorse or promote products derived from this software |
| 22 | * without specific prior written permission. | 19 | * without specific prior written permission. |
| 23 | * | 20 | * |
| @@ -34,32 +31,30 @@ | |||
| 34 | * SUCH DAMAGE. | 31 | * SUCH DAMAGE. |
| 35 | */ | 32 | */ |
| 36 | 33 | ||
| 37 | #if defined(LIBC_SCCS) && !defined(lint) | 34 | #include <unistd.h> |
| 38 | /*static char *sccsid = "from: @(#)swab.c 5.10 (Berkeley) 3/6/91";*/ | ||
| 39 | static char *rcsid = "$Id: swab.c,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $"; | ||
| 40 | #endif /* LIBC_SCCS and not lint */ | ||
| 41 | |||
| 42 | #include <string.h> | ||
| 43 | 35 | ||
| 44 | void | 36 | void |
| 45 | swab(from, to, len) | 37 | swab(const void *from, void *to, size_t len) |
| 46 | const void *from; | ||
| 47 | void *to; | ||
| 48 | size_t len; | ||
| 49 | { | 38 | { |
| 50 | register unsigned long temp; | 39 | size_t n; |
| 51 | register int n; | 40 | char *fp, *tp; |
| 52 | register char *fp, *tp; | 41 | char temp; |
| 53 | 42 | ||
| 54 | n = (len >> 1) + 1; | 43 | n = (len / 2) + 1; |
| 55 | fp = (char *)from; | 44 | fp = (char *)from; |
| 56 | tp = (char *)to; | 45 | tp = (char *)to; |
| 57 | #define STEP temp = *fp++,*tp++ = *fp++,*tp++ = temp | 46 | #define STEP do { \ |
| 47 | temp = *fp++; \ | ||
| 48 | *tp++ = *fp++; \ | ||
| 49 | *tp++ = temp; \ | ||
| 50 | } while (0) | ||
| 58 | /* round to multiple of 8 */ | 51 | /* round to multiple of 8 */ |
| 59 | while ((--n) & 07) | 52 | while ((--n) & 07) |
| 60 | STEP; | 53 | STEP; |
| 61 | n >>= 3; | 54 | n >>= 3; |
| 62 | while (--n >= 0) { | 55 | if (n == 0) |
| 56 | return; | ||
| 57 | while (n-- != 0) { | ||
| 63 | STEP; STEP; STEP; STEP; | 58 | STEP; STEP; STEP; STEP; |
| 64 | STEP; STEP; STEP; STEP; | 59 | STEP; STEP; STEP; STEP; |
| 65 | } | 60 | } |
diff --git a/src/lib/libc/string/timingsafe_bcmp.c b/src/lib/libc/string/timingsafe_bcmp.c new file mode 100644 index 0000000000..9c4287cf63 --- /dev/null +++ b/src/lib/libc/string/timingsafe_bcmp.c | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | /* $OpenBSD: timingsafe_bcmp.c,v 1.1 2010/09/24 13:33:00 matthew Exp $ */ | ||
| 2 | /* | ||
| 3 | * Copyright (c) 2010 Damien Miller. All rights reserved. | ||
| 4 | * | ||
| 5 | * Permission to use, copy, modify, and distribute this software for any | ||
| 6 | * purpose with or without fee is hereby granted, provided that the above | ||
| 7 | * copyright notice and this permission notice appear in all copies. | ||
| 8 | * | ||
| 9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #if !defined(_KERNEL) && !defined(_STANDALONE) | ||
| 19 | #include <string.h> | ||
| 20 | #else | ||
| 21 | #include <lib/libkern/libkern.h> | ||
| 22 | #endif | ||
| 23 | |||
| 24 | int | ||
| 25 | timingsafe_bcmp(const void *b1, const void *b2, size_t n) | ||
| 26 | { | ||
| 27 | const unsigned char *p1 = b1, *p2 = b2; | ||
| 28 | int ret = 0; | ||
| 29 | |||
| 30 | for (; n > 0; n--) | ||
| 31 | ret |= *p1++ ^ *p2++; | ||
| 32 | return (ret != 0); | ||
| 33 | } | ||
diff --git a/src/lib/libc/string/wcscasecmp.3 b/src/lib/libc/string/wcscasecmp.3 new file mode 100644 index 0000000000..daf397aece --- /dev/null +++ b/src/lib/libc/string/wcscasecmp.3 | |||
| @@ -0,0 +1,94 @@ | |||
| 1 | .\" $OpenBSD: wcscasecmp.3,v 1.4 2013/07/16 15:21:11 schwarze 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. 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 | .\" @(#)strcasecmp.3 8.1 (Berkeley) 6/9/93 | ||
| 33 | .\" | ||
| 34 | .Dd $Mdocdate: July 16 2013 $ | ||
| 35 | .Dt WCSCASECMP 3 | ||
| 36 | .Os | ||
| 37 | .Sh NAME | ||
| 38 | .Nm wcscasecmp , | ||
| 39 | .Nm wcsncasecmp | ||
| 40 | .Nd compare wide strings, ignoring case | ||
| 41 | .Sh SYNOPSIS | ||
| 42 | .In wchar.h | ||
| 43 | .Ft int | ||
| 44 | .Fn wcscasecmp "const wchar_t *s1" "const wchar_t *s2" | ||
| 45 | .Ft int | ||
| 46 | .Fn wcsncasecmp "const wchar_t *s1" "const wchar_t *s2" "size_t len" | ||
| 47 | .Sh DESCRIPTION | ||
| 48 | The | ||
| 49 | .Fn wcscasecmp | ||
| 50 | and | ||
| 51 | .Fn wcsncasecmp | ||
| 52 | functions compare the wide strings | ||
| 53 | .Fa s1 | ||
| 54 | and | ||
| 55 | .Fa s2 | ||
| 56 | and return an integer greater than, equal to, or less than 0, | ||
| 57 | according to whether | ||
| 58 | .Fa s1 | ||
| 59 | is lexicographically greater than, equal to, or less than | ||
| 60 | .Fa s2 | ||
| 61 | after translation of each corresponding wide character to lower case. | ||
| 62 | The wide strings themselves are not modified. | ||
| 63 | .Pp | ||
| 64 | .Fn wcsncasecmp | ||
| 65 | compares at most | ||
| 66 | .Fa len | ||
| 67 | wide characters. | ||
| 68 | .Sh SEE ALSO | ||
| 69 | .Xr strcasecmp 3 , | ||
| 70 | .Xr wcscmp 3 , | ||
| 71 | .Xr wmemcmp 3 | ||
| 72 | .Sh STANDARDS | ||
| 73 | The | ||
| 74 | .Fn wcscasecmp | ||
| 75 | and | ||
| 76 | .Fn wcsncasecmp | ||
| 77 | functions conform to | ||
| 78 | .St -p1003.1-2008 . | ||
| 79 | .Sh HISTORY | ||
| 80 | The | ||
| 81 | .Fn wcscasecmp | ||
| 82 | and | ||
| 83 | .Fn wcsncasecmp | ||
| 84 | functions first appeared in | ||
| 85 | .Ox 5.0 . | ||
| 86 | .Sh AUTHORS | ||
| 87 | The | ||
| 88 | .Ox | ||
| 89 | versions of | ||
| 90 | .Fn wcscasecmp | ||
| 91 | and | ||
| 92 | .Fn wcsncasecmp | ||
| 93 | were implemented by | ||
| 94 | .An Marc Espie Aq Mt espie@openbsd.org . | ||
diff --git a/src/lib/libc/string/wcscasecmp.c b/src/lib/libc/string/wcscasecmp.c new file mode 100644 index 0000000000..b14997ee75 --- /dev/null +++ b/src/lib/libc/string/wcscasecmp.c | |||
| @@ -0,0 +1,61 @@ | |||
| 1 | /* $OpenBSD: wcscasecmp.c,v 1.2 2011/06/01 19:29:48 naddy Exp $ */ | ||
| 2 | |||
| 3 | /* | ||
| 4 | * Copyright (c) 2011 Marc Espie | ||
| 5 | * | ||
| 6 | * Redistribution and use in source and binary forms, with or without | ||
| 7 | * modification, are permitted provided that the following conditions | ||
| 8 | * are met: | ||
| 9 | * 1. Redistributions of source code must retain the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer. | ||
| 11 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 12 | * notice, this list of conditions and the following disclaimer in the | ||
| 13 | * documentation and/or other materials provided with the distribution. | ||
| 14 | * | ||
| 15 | * THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT AND CONTRIBUTORS | ||
| 16 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
| 18 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OPENBSD | ||
| 19 | * PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
| 20 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
| 21 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
| 22 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
| 23 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
| 25 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 26 | */ | ||
| 27 | |||
| 28 | #include <wchar.h> | ||
| 29 | #include <wctype.h> | ||
| 30 | #include "locale/runetype.h" | ||
| 31 | |||
| 32 | int | ||
| 33 | wcscasecmp(const wchar_t *s1, const wchar_t *s2) | ||
| 34 | { | ||
| 35 | wchar_t l1, l2; | ||
| 36 | |||
| 37 | while ((l1 = towlower(*s1++)) == (l2 = towlower(*s2++))) { | ||
| 38 | if (l1 == 0) | ||
| 39 | return (0); | ||
| 40 | } | ||
| 41 | /* XXX assumes wchar_t = int */ | ||
| 42 | return ((rune_t)l1 - (rune_t)l2); | ||
| 43 | } | ||
| 44 | |||
| 45 | int | ||
| 46 | wcsncasecmp(const wchar_t *s1, const wchar_t *s2, size_t n) | ||
| 47 | { | ||
| 48 | wchar_t l1, l2; | ||
| 49 | |||
| 50 | if (n == 0) | ||
| 51 | return (0); | ||
| 52 | do { | ||
| 53 | if (((l1 = towlower(*s1++))) != (l2 = towlower(*s2++))) { | ||
| 54 | /* XXX assumes wchar_t = int */ | ||
| 55 | return ((rune_t)l1 - (rune_t)l2); | ||
| 56 | } | ||
| 57 | if (l1 == 0) | ||
| 58 | break; | ||
| 59 | } while (--n != 0); | ||
| 60 | return (0); | ||
| 61 | } | ||
diff --git a/src/lib/libc/string/wcscat.3 b/src/lib/libc/string/wcscat.3 new file mode 100644 index 0000000000..9b7588cf9e --- /dev/null +++ b/src/lib/libc/string/wcscat.3 | |||
| @@ -0,0 +1,115 @@ | |||
| 1 | .\" $OpenBSD: wcscat.3,v 1.3 2013/06/05 03:39:23 tedu Exp $ | ||
| 2 | .\" | ||
| 3 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. | ||
| 4 | .\" All rights reserved. | ||
| 5 | .\" | ||
| 6 | .\" This code is derived from software contributed to Berkeley by | ||
| 7 | .\" Chris Torek and the American National Standards Committee X3, | ||
| 8 | .\" on Information Processing Systems. | ||
| 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. 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 $Mdocdate: June 5 2013 $ | ||
| 35 | .Dt WCSCAT 3 | ||
| 36 | .Os | ||
| 37 | .Sh NAME | ||
| 38 | .Nm wcscat , | ||
| 39 | .Nm wcsncat | ||
| 40 | .Nd concatenate wide strings | ||
| 41 | .Sh SYNOPSIS | ||
| 42 | .In wchar.h | ||
| 43 | .Ft wchar_t * | ||
| 44 | .Fn wcscat "wchar_t * restrict s" "const wchar_t * restrict append" | ||
| 45 | .Ft wchar_t * | ||
| 46 | .Fo wcsncat | ||
| 47 | .Fa "wchar_t * restrict s" | ||
| 48 | .Fa "const wchar_t * restrict append" | ||
| 49 | .Fa "size_t count" | ||
| 50 | .Fc | ||
| 51 | .Sh DESCRIPTION | ||
| 52 | The | ||
| 53 | .Fn wcscat | ||
| 54 | and | ||
| 55 | .Fn wcsncat | ||
| 56 | functions append a copy of the wide string | ||
| 57 | .Fa append | ||
| 58 | to the end of the wide string | ||
| 59 | .Fa s , | ||
| 60 | then add a terminating null wide character (L'\e0'). | ||
| 61 | The wide string | ||
| 62 | .Fa s | ||
| 63 | must have sufficient space to hold the result. | ||
| 64 | .Pp | ||
| 65 | The | ||
| 66 | .Fn wcsncat | ||
| 67 | function appends not more than | ||
| 68 | .Fa count | ||
| 69 | wide characters where space for the terminating null wide character | ||
| 70 | should not be included in | ||
| 71 | .Fa count . | ||
| 72 | .Sh RETURN VALUES | ||
| 73 | The | ||
| 74 | .Fn wcscat | ||
| 75 | and | ||
| 76 | .Fn wcsncat | ||
| 77 | functions return the pointer | ||
| 78 | .Fa s . | ||
| 79 | .Sh SEE ALSO | ||
| 80 | .Xr strcat 3 , | ||
| 81 | .Xr strlcpy 3 , | ||
| 82 | .Xr wcscpy 3 , | ||
| 83 | .Xr wcslcpy 3 , | ||
| 84 | .Xr wmemcpy 3 , | ||
| 85 | .Xr wmemmove 3 | ||
| 86 | .Sh STANDARDS | ||
| 87 | The | ||
| 88 | .Fn wcscat | ||
| 89 | and | ||
| 90 | .Fn wcsncat | ||
| 91 | functions conform to | ||
| 92 | .St -isoC-99 | ||
| 93 | and were first introduced in | ||
| 94 | .St -isoC-amd1 . | ||
| 95 | .Sh HISTORY | ||
| 96 | The | ||
| 97 | .Fn wcscat | ||
| 98 | and | ||
| 99 | .Fn wcsncat | ||
| 100 | functions were ported from | ||
| 101 | .Nx | ||
| 102 | and first appeared in | ||
| 103 | .Ox 3.8 . | ||
| 104 | .Sh CAVEATS | ||
| 105 | Using the functions | ||
| 106 | .Fn wcscat | ||
| 107 | and | ||
| 108 | .Fn wcsncat | ||
| 109 | is very error-prone with respect to buffer overflows; | ||
| 110 | see the EXAMPLES section in | ||
| 111 | .Xr strcat 3 | ||
| 112 | for correct usage. | ||
| 113 | Using | ||
| 114 | .Xr wcslcat 3 | ||
| 115 | is a better choice in most cases. | ||
diff --git a/src/lib/libc/string/wcscat.c b/src/lib/libc/string/wcscat.c new file mode 100644 index 0000000000..a4841a975a --- /dev/null +++ b/src/lib/libc/string/wcscat.c | |||
| @@ -0,0 +1,55 @@ | |||
| 1 | /* $OpenBSD: wcscat.c,v 1.3 2005/08/08 08:05:37 espie Exp $ */ | ||
| 2 | /* $NetBSD: wcscat.c,v 1.2 2001/01/03 14:29:36 lukem Exp $ */ | ||
| 3 | |||
| 4 | /*- | ||
| 5 | * Copyright (c)1999 Citrus Project, | ||
| 6 | * All rights reserved. | ||
| 7 | * | ||
| 8 | * Redistribution and use in source and binary forms, with or without | ||
| 9 | * modification, are permitted provided that the following conditions | ||
| 10 | * are met: | ||
| 11 | * 1. Redistributions of source code must retain the above copyright | ||
| 12 | * notice, this list of conditions and the following disclaimer. | ||
| 13 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in the | ||
| 15 | * documentation and/or other materials provided with the distribution. | ||
| 16 | * | ||
| 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | ||
| 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
| 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 27 | * SUCH DAMAGE. | ||
| 28 | * | ||
| 29 | * citrus Id: wcscat.c,v 1.1 1999/12/29 21:47:45 tshiozak Exp | ||
| 30 | */ | ||
| 31 | |||
| 32 | #include <wchar.h> | ||
| 33 | |||
| 34 | #if defined(APIWARN) | ||
| 35 | __warn_references(wcscat, | ||
| 36 | "warning: wcscat() is almost always misused, please use wcslcat()"); | ||
| 37 | #endif | ||
| 38 | |||
| 39 | wchar_t * | ||
| 40 | wcscat(wchar_t *s1, const wchar_t *s2) | ||
| 41 | { | ||
| 42 | wchar_t *p; | ||
| 43 | wchar_t *q; | ||
| 44 | const wchar_t *r; | ||
| 45 | |||
| 46 | p = s1; | ||
| 47 | while (*p) | ||
| 48 | p++; | ||
| 49 | q = p; | ||
| 50 | r = s2; | ||
| 51 | while (*r) | ||
| 52 | *q++ = *r++; | ||
| 53 | *q = '\0'; | ||
| 54 | return s1; | ||
| 55 | } | ||
diff --git a/src/lib/libc/string/wcschr.3 b/src/lib/libc/string/wcschr.3 new file mode 100644 index 0000000000..bb714b2099 --- /dev/null +++ b/src/lib/libc/string/wcschr.3 | |||
| @@ -0,0 +1,85 @@ | |||
| 1 | .\" $OpenBSD: wcschr.3,v 1.4 2013/06/05 03:39:23 tedu Exp $ | ||
| 2 | .\" | ||
| 3 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. | ||
| 4 | .\" All rights reserved. | ||
| 5 | .\" | ||
| 6 | .\" This code is derived from software contributed to Berkeley by | ||
| 7 | .\" Chris Torek and the American National Standards Committee X3, | ||
| 8 | .\" on Information Processing Systems. | ||
| 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. 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 $Mdocdate: June 5 2013 $ | ||
| 35 | .Dt WCSCHR 3 | ||
| 36 | .Os | ||
| 37 | .Sh NAME | ||
| 38 | .Nm wcschr | ||
| 39 | .Nd locate first occurrence of a wide character in a wide string | ||
| 40 | .Sh SYNOPSIS | ||
| 41 | .In wchar.h | ||
| 42 | .Ft wchar_t * | ||
| 43 | .Fn wcschr "const wchar_t *s" "wchar_t c" | ||
| 44 | .Sh DESCRIPTION | ||
| 45 | The | ||
| 46 | .Fn wcschr | ||
| 47 | function locates the first occurrence of the wide character | ||
| 48 | .Fa c | ||
| 49 | in the wide string | ||
| 50 | .Fa s . | ||
| 51 | The terminating null wide character is considered part of the wide string. | ||
| 52 | If | ||
| 53 | .Fa c | ||
| 54 | is the null wide character (L'\e0'), | ||
| 55 | .Fn wcschr | ||
| 56 | locates the terminating null wide character. | ||
| 57 | .Sh RETURN VALUES | ||
| 58 | The | ||
| 59 | .Fn wcschr | ||
| 60 | function returns a pointer to the located wide character or | ||
| 61 | .Dv NULL | ||
| 62 | if the wide character does not appear in the wide string. | ||
| 63 | .Sh SEE ALSO | ||
| 64 | .Xr strchr 3 , | ||
| 65 | .Xr wcscspn 3 , | ||
| 66 | .Xr wcspbrk 3 , | ||
| 67 | .Xr wcsrchr 3 , | ||
| 68 | .Xr wcsspn 3 , | ||
| 69 | .Xr wcsstr 3 , | ||
| 70 | .Xr wcstok 3 , | ||
| 71 | .Xr wmemchr 3 | ||
| 72 | .Sh STANDARDS | ||
| 73 | The | ||
| 74 | .Fn wcschr | ||
| 75 | function conforms to | ||
| 76 | .St -isoC-99 | ||
| 77 | and was first introduced in | ||
| 78 | .St -isoC-amd1 . | ||
| 79 | .Sh HISTORY | ||
| 80 | The | ||
| 81 | .Fn wcschr | ||
| 82 | function was ported from | ||
| 83 | .Nx | ||
| 84 | and first appeared in | ||
| 85 | .Ox 3.8 . | ||
diff --git a/src/lib/libc/string/wcschr.c b/src/lib/libc/string/wcschr.c new file mode 100644 index 0000000000..b84a2d32e3 --- /dev/null +++ b/src/lib/libc/string/wcschr.c | |||
| @@ -0,0 +1,50 @@ | |||
| 1 | /* $OpenBSD: wcschr.c,v 1.4 2008/08/23 05:34:36 djm Exp $ */ | ||
| 2 | /* $NetBSD: wcschr.c,v 1.2 2001/01/03 14:29:36 lukem Exp $ */ | ||
| 3 | |||
| 4 | /*- | ||
| 5 | * Copyright (c)1999 Citrus Project, | ||
| 6 | * All rights reserved. | ||
| 7 | * | ||
| 8 | * Redistribution and use in source and binary forms, with or without | ||
| 9 | * modification, are permitted provided that the following conditions | ||
| 10 | * are met: | ||
| 11 | * 1. Redistributions of source code must retain the above copyright | ||
| 12 | * notice, this list of conditions and the following disclaimer. | ||
| 13 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in the | ||
| 15 | * documentation and/or other materials provided with the distribution. | ||
| 16 | * | ||
| 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | ||
| 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
| 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 27 | * SUCH DAMAGE. | ||
| 28 | * | ||
| 29 | * citrus Id: wcschr.c,v 1.2 2000/12/21 05:07:25 itojun Exp | ||
| 30 | */ | ||
| 31 | |||
| 32 | #include <wchar.h> | ||
| 33 | |||
| 34 | wchar_t * | ||
| 35 | wcschr(const wchar_t *s, wchar_t c) | ||
| 36 | { | ||
| 37 | const wchar_t *p; | ||
| 38 | |||
| 39 | p = s; | ||
| 40 | for (;;) { | ||
| 41 | if (*p == c) { | ||
| 42 | /* LINTED interface specification */ | ||
| 43 | return (wchar_t *)p; | ||
| 44 | } | ||
| 45 | if (!*p) | ||
| 46 | return NULL; | ||
| 47 | p++; | ||
| 48 | } | ||
| 49 | /* NOTREACHED */ | ||
| 50 | } | ||
diff --git a/src/lib/libc/string/wcscmp.3 b/src/lib/libc/string/wcscmp.3 new file mode 100644 index 0000000000..53cd15a1f0 --- /dev/null +++ b/src/lib/libc/string/wcscmp.3 | |||
| @@ -0,0 +1,92 @@ | |||
| 1 | .\" $OpenBSD: wcscmp.3,v 1.3 2013/06/05 03:39:23 tedu Exp $ | ||
| 2 | .\" | ||
| 3 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. | ||
| 4 | .\" All rights reserved. | ||
| 5 | .\" | ||
| 6 | .\" This code is derived from software contributed to Berkeley by | ||
| 7 | .\" Chris Torek and the American National Standards Committee X3, | ||
| 8 | .\" on Information Processing Systems. | ||
| 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. 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 $Mdocdate: June 5 2013 $ | ||
| 35 | .Dt WCSCMP 3 | ||
| 36 | .Os | ||
| 37 | .Sh NAME | ||
| 38 | .Nm wcscmp , | ||
| 39 | .Nm wcsncmp | ||
| 40 | .Nd compare wide strings | ||
| 41 | .Sh SYNOPSIS | ||
| 42 | .In wchar.h | ||
| 43 | .Ft int | ||
| 44 | .Fn wcscmp "const wchar_t *s1" "const wchar_t *s2" | ||
| 45 | .Ft int | ||
| 46 | .Fn wcsncmp "const wchar_t *s1" "const wchar_t *s2" "size_t len" | ||
| 47 | .Sh DESCRIPTION | ||
| 48 | The | ||
| 49 | .Fn wcscmp | ||
| 50 | and | ||
| 51 | .Fn wcsncmp | ||
| 52 | functions lexicographically compare the wide strings | ||
| 53 | .Fa s1 | ||
| 54 | and | ||
| 55 | .Fa s2 . | ||
| 56 | The | ||
| 57 | .Fn wcsncmp | ||
| 58 | function compares at most | ||
| 59 | .Fa len | ||
| 60 | wide characters. | ||
| 61 | .Sh RETURN VALUES | ||
| 62 | The | ||
| 63 | .Fn wcscmp | ||
| 64 | and | ||
| 65 | .Fn wcsncmp | ||
| 66 | functions return an integer greater than, equal to, or less than 0, according | ||
| 67 | to whether the wide string | ||
| 68 | .Fa s1 | ||
| 69 | is greater than, equal to, or less than the wide string | ||
| 70 | .Fa s2 . | ||
| 71 | .Sh SEE ALSO | ||
| 72 | .Xr strcmp 3 , | ||
| 73 | .Xr wcscasecmp 3 , | ||
| 74 | .Xr wmemcmp 3 | ||
| 75 | .Sh STANDARDS | ||
| 76 | The | ||
| 77 | .Fn wcscmp | ||
| 78 | and | ||
| 79 | .Fn wcsncmp | ||
| 80 | functions conform to | ||
| 81 | .St -isoC-99 | ||
| 82 | and were first introduced in | ||
| 83 | .St -isoC-amd1 . | ||
| 84 | .Sh HISTORY | ||
| 85 | The | ||
| 86 | .Fn wcscmp | ||
| 87 | and | ||
| 88 | .Fn wcsncmp | ||
| 89 | functions were ported from | ||
| 90 | .Nx | ||
| 91 | and first appeared in | ||
| 92 | .Ox 3.8 . | ||
diff --git a/src/lib/libc/string/wcscmp.c b/src/lib/libc/string/wcscmp.c new file mode 100644 index 0000000000..4a8f6ba3fb --- /dev/null +++ b/src/lib/libc/string/wcscmp.c | |||
| @@ -0,0 +1,51 @@ | |||
| 1 | /* $OpenBSD: wcscmp.c,v 1.4 2005/08/08 08:05:37 espie Exp $ */ | ||
| 2 | /* $NetBSD: wcscmp.c,v 1.5 2003/08/07 16:43:54 agc Exp $ */ | ||
| 3 | |||
| 4 | /*- | ||
| 5 | * Copyright (c) 1990, 1993 | ||
| 6 | * The Regents of the University of California. All rights reserved. | ||
| 7 | * | ||
| 8 | * This code is derived from software contributed to Berkeley by | ||
| 9 | * Chris Torek. | ||
| 10 | * | ||
| 11 | * Redistribution and use in source and binary forms, with or without | ||
| 12 | * modification, are permitted provided that the following conditions | ||
| 13 | * are met: | ||
| 14 | * 1. Redistributions of source code must retain the above copyright | ||
| 15 | * notice, this list of conditions and the following disclaimer. | ||
| 16 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 17 | * notice, this list of conditions and the following disclaimer in the | ||
| 18 | * documentation and/or other materials provided with the distribution. | ||
| 19 | * 3. 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 <wchar.h> | ||
| 37 | #include "locale/runetype.h" | ||
| 38 | |||
| 39 | /* | ||
| 40 | * Compare strings. | ||
| 41 | */ | ||
| 42 | int | ||
| 43 | wcscmp(const wchar_t *s1, const wchar_t *s2) | ||
| 44 | { | ||
| 45 | |||
| 46 | while (*s1 == *s2++) | ||
| 47 | if (*s1++ == 0) | ||
| 48 | return (0); | ||
| 49 | /* XXX assumes wchar_t = int */ | ||
| 50 | return (*(const rune_t *)s1 - *(const rune_t *)--s2); | ||
| 51 | } | ||
diff --git a/src/lib/libc/string/wcscpy.3 b/src/lib/libc/string/wcscpy.3 new file mode 100644 index 0000000000..2277eb419a --- /dev/null +++ b/src/lib/libc/string/wcscpy.3 | |||
| @@ -0,0 +1,129 @@ | |||
| 1 | .\" $OpenBSD: wcscpy.3,v 1.4 2013/09/25 21:49:31 millert Exp $ | ||
| 2 | .\" | ||
| 3 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. | ||
| 4 | .\" All rights reserved. | ||
| 5 | .\" | ||
| 6 | .\" This code is derived from software contributed to Berkeley by | ||
| 7 | .\" Chris Torek and the American National Standards Committee X3, | ||
| 8 | .\" on Information Processing Systems. | ||
| 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. 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 $Mdocdate: September 25 2013 $ | ||
| 35 | .Dt WCSCPY 3 | ||
| 36 | .Os | ||
| 37 | .Sh NAME | ||
| 38 | .Nm wcscpy , | ||
| 39 | .Nm wcsncpy | ||
| 40 | .Nd copy wide strings | ||
| 41 | .Sh SYNOPSIS | ||
| 42 | .In wchar.h | ||
| 43 | .Ft wchar_t * | ||
| 44 | .Fn wcscpy "wchar_t * restrict dst" "const wchar_t * restrict src" | ||
| 45 | .Ft wchar_t * | ||
| 46 | .Fo wcsncpy | ||
| 47 | .Fa "wchar_t * restrict dst" | ||
| 48 | .Fa "const wchar_t * restrict src" | ||
| 49 | .Fa "size_t len" | ||
| 50 | .Fc | ||
| 51 | .Sh DESCRIPTION | ||
| 52 | The | ||
| 53 | .Fn wcscpy | ||
| 54 | and | ||
| 55 | .Fn wcsncpy | ||
| 56 | functions copy the wide string | ||
| 57 | .Fa src | ||
| 58 | to | ||
| 59 | .Fa dst | ||
| 60 | (including the terminating null wide character). | ||
| 61 | .Pp | ||
| 62 | The | ||
| 63 | .Fn wcsncpy | ||
| 64 | function copies not more than | ||
| 65 | .Fa len | ||
| 66 | wide characters to | ||
| 67 | .Fa dst , | ||
| 68 | appending null wide characters if the length of | ||
| 69 | .Fa src | ||
| 70 | is less than | ||
| 71 | .Fa len , | ||
| 72 | and | ||
| 73 | .Em not | ||
| 74 | terminating | ||
| 75 | .Fa dst | ||
| 76 | if the length of | ||
| 77 | .Fa src | ||
| 78 | is greater than or equal to | ||
| 79 | .Fa len . | ||
| 80 | .Pp | ||
| 81 | If the | ||
| 82 | .Fa src | ||
| 83 | and | ||
| 84 | .Fa dst | ||
| 85 | strings overlap, the behavior is undefined. | ||
| 86 | .Sh RETURN VALUES | ||
| 87 | The | ||
| 88 | .Fn wcscpy | ||
| 89 | and | ||
| 90 | .Fn wcsncpy | ||
| 91 | functions return | ||
| 92 | .Fa dst . | ||
| 93 | .Sh SEE ALSO | ||
| 94 | .Xr strcpy 3 , | ||
| 95 | .Xr strlcpy 3 , | ||
| 96 | .Xr wcscat 3 , | ||
| 97 | .Xr wcslcpy 3 , | ||
| 98 | .Xr wmemcpy 3 , | ||
| 99 | .Xr wmemmove 3 | ||
| 100 | .Sh STANDARDS | ||
| 101 | The | ||
| 102 | .Fn wcscpy | ||
| 103 | and | ||
| 104 | .Fn wcsncpy | ||
| 105 | functions conform to | ||
| 106 | .St -isoC-99 | ||
| 107 | and were first introduced in | ||
| 108 | .St -isoC-amd1 . | ||
| 109 | .Sh HISTORY | ||
| 110 | The | ||
| 111 | .Fn wcscpy | ||
| 112 | and | ||
| 113 | .Fn wcsncpy | ||
| 114 | functions were ported from | ||
| 115 | .Nx | ||
| 116 | and first appeared in | ||
| 117 | .Ox 3.8 . | ||
| 118 | .Sh CAVEATS | ||
| 119 | Using the functions | ||
| 120 | .Fn wcscpy | ||
| 121 | and | ||
| 122 | .Fn wcsncpy | ||
| 123 | is very error-prone with respect to buffer overflows; | ||
| 124 | see the EXAMPLES section in | ||
| 125 | .Xr strcpy 3 | ||
| 126 | for correct usage. | ||
| 127 | Using | ||
| 128 | .Xr wcslcpy 3 | ||
| 129 | is a better choice in most cases. | ||
diff --git a/src/lib/libc/string/wcscpy.c b/src/lib/libc/string/wcscpy.c new file mode 100644 index 0000000000..75fdb75fe4 --- /dev/null +++ b/src/lib/libc/string/wcscpy.c | |||
| @@ -0,0 +1,52 @@ | |||
| 1 | /* $OpenBSD: wcscpy.c,v 1.4 2005/08/08 08:05:37 espie Exp $ */ | ||
| 2 | /* $NetBSD: wcscpy.c,v 1.2 2001/01/03 14:29:36 lukem Exp $ */ | ||
| 3 | |||
| 4 | /*- | ||
| 5 | * Copyright (c)1999 Citrus Project, | ||
| 6 | * All rights reserved. | ||
| 7 | * | ||
| 8 | * Redistribution and use in source and binary forms, with or without | ||
| 9 | * modification, are permitted provided that the following conditions | ||
| 10 | * are met: | ||
| 11 | * 1. Redistributions of source code must retain the above copyright | ||
| 12 | * notice, this list of conditions and the following disclaimer. | ||
| 13 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in the | ||
| 15 | * documentation and/or other materials provided with the distribution. | ||
| 16 | * | ||
| 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | ||
| 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
| 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 27 | * SUCH DAMAGE. | ||
| 28 | * | ||
| 29 | * citrus Id: wcscpy.c,v 1.2 2000/12/21 04:51:09 itojun Exp | ||
| 30 | */ | ||
| 31 | |||
| 32 | #include <wchar.h> | ||
| 33 | |||
| 34 | #if defined(APIWARN) | ||
| 35 | __warn_references(wcscpy, | ||
| 36 | "warning: wcscpy() is almost always misused, please use wcslcpy()"); | ||
| 37 | #endif | ||
| 38 | |||
| 39 | wchar_t * | ||
| 40 | wcscpy(wchar_t *s1, const wchar_t *s2) | ||
| 41 | { | ||
| 42 | wchar_t *p; | ||
| 43 | const wchar_t *q; | ||
| 44 | |||
| 45 | p = s1; | ||
| 46 | q = s2; | ||
| 47 | while (*q) | ||
| 48 | *p++ = *q++; | ||
| 49 | *p = '\0'; | ||
| 50 | |||
| 51 | return s1; | ||
| 52 | } | ||
diff --git a/src/lib/libc/string/wcscspn.3 b/src/lib/libc/string/wcscspn.3 new file mode 100644 index 0000000000..520a739202 --- /dev/null +++ b/src/lib/libc/string/wcscspn.3 | |||
| @@ -0,0 +1,83 @@ | |||
| 1 | .\" $OpenBSD: wcscspn.3,v 1.3 2013/06/05 03:39:23 tedu Exp $ | ||
| 2 | .\" | ||
| 3 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. | ||
| 4 | .\" All rights reserved. | ||
| 5 | .\" | ||
| 6 | .\" This code is derived from software contributed to Berkeley by | ||
| 7 | .\" Chris Torek and the American National Standards Committee X3, | ||
| 8 | .\" on Information Processing Systems. | ||
| 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. 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 $Mdocdate: June 5 2013 $ | ||
| 35 | .Dt WCSCSPN 3 | ||
| 36 | .Os | ||
| 37 | .Sh NAME | ||
| 38 | .Nm wcscspn | ||
| 39 | .Nd span the complement of a wide string | ||
| 40 | .Sh SYNOPSIS | ||
| 41 | .In wchar.h | ||
| 42 | .Ft size_t | ||
| 43 | .Fn wcscspn "const wchar_t *s" "const wchar_t *charset" | ||
| 44 | .Sh DESCRIPTION | ||
| 45 | The | ||
| 46 | .Fn wcscspn | ||
| 47 | function spans the initial part of the wide string | ||
| 48 | .Fa s | ||
| 49 | as long as the wide characters from | ||
| 50 | .Fa s | ||
| 51 | do not occur in string | ||
| 52 | .Fa charset | ||
| 53 | (it spans the | ||
| 54 | .Em complement | ||
| 55 | of | ||
| 56 | .Fa charset ) . | ||
| 57 | .Sh RETURN VALUES | ||
| 58 | The | ||
| 59 | .Fn wcscspn | ||
| 60 | function returns the number of wide characters spanned. | ||
| 61 | .Sh SEE ALSO | ||
| 62 | .Xr strcspn 3 , | ||
| 63 | .Xr wcschr 3 , | ||
| 64 | .Xr wcspbrk 3 , | ||
| 65 | .Xr wcsrchr 3 , | ||
| 66 | .Xr wcsspn 3 , | ||
| 67 | .Xr wcsstr 3 , | ||
| 68 | .Xr wcstok 3 , | ||
| 69 | .Xr wmemchr 3 | ||
| 70 | .Sh STANDARDS | ||
| 71 | The | ||
| 72 | .Fn wcscspn | ||
| 73 | function conforms to | ||
| 74 | .St -isoC-99 | ||
| 75 | and was first introduced in | ||
| 76 | .St -isoC-amd1 . | ||
| 77 | .Sh HISTORY | ||
| 78 | The | ||
| 79 | .Fn wcscspn | ||
| 80 | function was ported from | ||
| 81 | .Nx | ||
| 82 | and first appeared in | ||
| 83 | .Ox 3.8 . | ||
diff --git a/src/lib/libc/string/wcscspn.c b/src/lib/libc/string/wcscspn.c new file mode 100644 index 0000000000..cf40092465 --- /dev/null +++ b/src/lib/libc/string/wcscspn.c | |||
| @@ -0,0 +1,53 @@ | |||
| 1 | /* $OpenBSD: wcscspn.c,v 1.3 2005/08/08 08:05:37 espie Exp $ */ | ||
| 2 | /* $NetBSD: wcscspn.c,v 1.2 2001/01/03 14:29:36 lukem Exp $ */ | ||
| 3 | |||
| 4 | /*- | ||
| 5 | * Copyright (c)1999 Citrus Project, | ||
| 6 | * All rights reserved. | ||
| 7 | * | ||
| 8 | * Redistribution and use in source and binary forms, with or without | ||
| 9 | * modification, are permitted provided that the following conditions | ||
| 10 | * are met: | ||
| 11 | * 1. Redistributions of source code must retain the above copyright | ||
| 12 | * notice, this list of conditions and the following disclaimer. | ||
| 13 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in the | ||
| 15 | * documentation and/or other materials provided with the distribution. | ||
| 16 | * | ||
| 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | ||
| 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
| 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 27 | * SUCH DAMAGE. | ||
| 28 | * | ||
| 29 | * citrus Id: wcscspn.c,v 1.1 1999/12/29 21:47:45 tshiozak Exp | ||
| 30 | */ | ||
| 31 | |||
| 32 | #include <wchar.h> | ||
| 33 | |||
| 34 | size_t | ||
| 35 | wcscspn(const wchar_t *s, const wchar_t *set) | ||
| 36 | { | ||
| 37 | const wchar_t *p; | ||
| 38 | const wchar_t *q; | ||
| 39 | |||
| 40 | p = s; | ||
| 41 | while (*p) { | ||
| 42 | q = set; | ||
| 43 | while (*q) { | ||
| 44 | if (*p == *q) | ||
| 45 | goto done; | ||
| 46 | q++; | ||
| 47 | } | ||
| 48 | p++; | ||
| 49 | } | ||
| 50 | |||
| 51 | done: | ||
| 52 | return (p - s); | ||
| 53 | } | ||
diff --git a/src/lib/libc/string/wcsdup.3 b/src/lib/libc/string/wcsdup.3 new file mode 100644 index 0000000000..588a2571db --- /dev/null +++ b/src/lib/libc/string/wcsdup.3 | |||
| @@ -0,0 +1,97 @@ | |||
| 1 | .\" $OpenBSD: wcsdup.3,v 1.4 2011/07/25 00:38:53 schwarze Exp $ | ||
| 2 | .\" $NetBSD: wcsdup.3,v 1.3 2010/12/16 17:42:28 wiz Exp $ | ||
| 3 | .\" | ||
| 4 | .\" Copyright (c) 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. Neither the name of the University nor the names of its contributors | ||
| 16 | .\" may be used to endorse or promote products derived from this software | ||
| 17 | .\" without specific prior written permission. | ||
| 18 | .\" | ||
| 19 | .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
| 20 | .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 21 | .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 22 | .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
| 23 | .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 24 | .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 25 | .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 26 | .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 28 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 29 | .\" SUCH DAMAGE. | ||
| 30 | .\" | ||
| 31 | .\" @(#)strdup.3 8.1 (Berkeley) 6/9/93 | ||
| 32 | .\" | ||
| 33 | .Dd $Mdocdate: July 25 2011 $ | ||
| 34 | .Dt WCSDUP 3 | ||
| 35 | .Os | ||
| 36 | .Sh NAME | ||
| 37 | .Nm wcsdup | ||
| 38 | .Nd save a copy of a wide string | ||
| 39 | .Sh SYNOPSIS | ||
| 40 | .In wchar.h | ||
| 41 | .Ft wchar_t * | ||
| 42 | .Fn wcsdup "const wchar_t *str" | ||
| 43 | .Sh DESCRIPTION | ||
| 44 | The | ||
| 45 | .Fn wcsdup | ||
| 46 | function | ||
| 47 | allocates sufficient memory for a copy | ||
| 48 | of the wide-character string | ||
| 49 | .Fa str , | ||
| 50 | does the copy, and returns a pointer to it. | ||
| 51 | The pointer may subsequently be used as an | ||
| 52 | argument to the function | ||
| 53 | .Xr free 3 . | ||
| 54 | .Pp | ||
| 55 | If insufficient memory is available, | ||
| 56 | .Dv NULL | ||
| 57 | is returned. | ||
| 58 | .Sh EXAMPLES | ||
| 59 | The following will point | ||
| 60 | .Va p | ||
| 61 | to an allocated area of memory containing the nul-terminated string | ||
| 62 | .Qq foobar : | ||
| 63 | .Bd -literal -offset indent | ||
| 64 | const char *o = "foobar"; | ||
| 65 | wchar_t *p, b[32]; | ||
| 66 | size_t blen; | ||
| 67 | |||
| 68 | blen = sizeof(b) / sizeof(b[0]); | ||
| 69 | if (mbstowcs(b, o, blen) == (size_t)-1) | ||
| 70 | err(1, NULL); | ||
| 71 | b[blen - 1] = 0; | ||
| 72 | if ((p = wcsdup(b)) == NULL) | ||
| 73 | err(1, NULL); | ||
| 74 | .Ed | ||
| 75 | .Sh ERRORS | ||
| 76 | The | ||
| 77 | .Fn wcsdup | ||
| 78 | function may fail and set the external variable | ||
| 79 | .Va errno | ||
| 80 | for any of the errors specified for the library function | ||
| 81 | .Xr malloc 3 . | ||
| 82 | .Sh SEE ALSO | ||
| 83 | .Xr free 3 , | ||
| 84 | .Xr malloc 3 , | ||
| 85 | .Xr strdup 3 | ||
| 86 | .Sh STANDARDS | ||
| 87 | The | ||
| 88 | .Fn wcsdup | ||
| 89 | function conforms to | ||
| 90 | .St -p1003.1-2008 . | ||
| 91 | .Sh HISTORY | ||
| 92 | The | ||
| 93 | .Fn wcsdup | ||
| 94 | function was ported from | ||
| 95 | .Nx | ||
| 96 | and first appeared in | ||
| 97 | .Ox 5.0 . | ||
diff --git a/src/lib/libc/string/wcsdup.c b/src/lib/libc/string/wcsdup.c new file mode 100644 index 0000000000..57a328a8c2 --- /dev/null +++ b/src/lib/libc/string/wcsdup.c | |||
| @@ -0,0 +1,31 @@ | |||
| 1 | /* $OpenBSD: wcsdup.c,v 1.1 2011/07/04 04:37:34 nicm Exp $ */ | ||
| 2 | /* $NetBSD: wcsdup.c,v 1.3 2008/05/26 13:17:48 haad Exp $ */ | ||
| 3 | |||
| 4 | /* | ||
| 5 | * Copyright (C) 2006 Aleksey Cheusov | ||
| 6 | * | ||
| 7 | * This material is provided "as is", with absolutely no warranty expressed | ||
| 8 | * or implied. Any use is at your own risk. | ||
| 9 | * | ||
| 10 | * Permission to use or copy this software for any purpose is hereby granted | ||
| 11 | * without fee. Permission to modify the code and to distribute modified | ||
| 12 | * code is also granted without any restrictions. | ||
| 13 | */ | ||
| 14 | |||
| 15 | #include <stdlib.h> | ||
| 16 | #include <wchar.h> | ||
| 17 | |||
| 18 | wchar_t * | ||
| 19 | wcsdup(const wchar_t *str) | ||
| 20 | { | ||
| 21 | wchar_t *copy; | ||
| 22 | size_t len; | ||
| 23 | |||
| 24 | len = wcslen(str) + 1; | ||
| 25 | copy = malloc(len * sizeof (wchar_t)); | ||
| 26 | |||
| 27 | if (!copy) | ||
| 28 | return (NULL); | ||
| 29 | |||
| 30 | return (wmemcpy(copy, str, len)); | ||
| 31 | } | ||
diff --git a/src/lib/libc/string/wcslcat.c b/src/lib/libc/string/wcslcat.c new file mode 100644 index 0000000000..ee8ff3c343 --- /dev/null +++ b/src/lib/libc/string/wcslcat.c | |||
| @@ -0,0 +1,56 @@ | |||
| 1 | /* $OpenBSD: wcslcat.c,v 1.4 2011/07/24 15:21:28 millert Exp $ */ | ||
| 2 | /* $NetBSD: wcslcat.c,v 1.2 2001/01/03 14:33:02 lukem Exp $ */ | ||
| 3 | |||
| 4 | /* | ||
| 5 | * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> | ||
| 6 | * | ||
| 7 | * Permission to use, copy, modify, and distribute this software for any | ||
| 8 | * purpose with or without fee is hereby granted, provided that the above | ||
| 9 | * copyright notice and this permission notice appear in all copies. | ||
| 10 | * | ||
| 11 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 12 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 13 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 14 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 15 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 16 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 17 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <sys/types.h> | ||
| 21 | #include <wchar.h> | ||
| 22 | |||
| 23 | /* | ||
| 24 | * Appends src to string dst of size siz (unlike wcsncat, siz is the | ||
| 25 | * full size of dst, not space left). At most siz-1 characters | ||
| 26 | * will be copied. Always NUL terminates (unless siz <= wcslen(dst)). | ||
| 27 | * Returns wcslen(src) + MIN(siz, wcslen(initial dst)). | ||
| 28 | * If retval >= siz, truncation occurred. | ||
| 29 | */ | ||
| 30 | size_t | ||
| 31 | wcslcat(wchar_t *dst, const wchar_t *src, size_t siz) | ||
| 32 | { | ||
| 33 | wchar_t *d = dst; | ||
| 34 | const wchar_t *s = src; | ||
| 35 | size_t n = siz; | ||
| 36 | size_t dlen; | ||
| 37 | |||
| 38 | /* Find the end of dst and adjust bytes left but don't go past end */ | ||
| 39 | while (n-- != 0 && *d != '\0') | ||
| 40 | d++; | ||
| 41 | dlen = d - dst; | ||
| 42 | n = siz - dlen; | ||
| 43 | |||
| 44 | if (n == 0) | ||
| 45 | return(dlen + wcslen(s)); | ||
| 46 | while (*s != '\0') { | ||
| 47 | if (n != 1) { | ||
| 48 | *d++ = *s; | ||
| 49 | n--; | ||
| 50 | } | ||
| 51 | s++; | ||
| 52 | } | ||
| 53 | *d = '\0'; | ||
| 54 | |||
| 55 | return(dlen + (s - src)); /* count does not include NUL */ | ||
| 56 | } | ||
diff --git a/src/lib/libc/string/wcslcpy.3 b/src/lib/libc/string/wcslcpy.3 new file mode 100644 index 0000000000..7af6c74614 --- /dev/null +++ b/src/lib/libc/string/wcslcpy.3 | |||
| @@ -0,0 +1,153 @@ | |||
| 1 | .\" $OpenBSD: wcslcpy.3,v 1.6 2013/09/25 21:49:31 millert Exp $ | ||
| 2 | .\" | ||
| 3 | .\" Copyright (c) 1998, 2000 Todd C. Miller <Todd.Miller@courtesan.com> | ||
| 4 | .\" | ||
| 5 | .\" Permission to use, copy, modify, and distribute this software for any | ||
| 6 | .\" purpose with or without fee is hereby granted, provided that the above | ||
| 7 | .\" copyright notice and this permission notice appear in all copies. | ||
| 8 | .\" | ||
| 9 | .\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 10 | .\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 11 | .\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 12 | .\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 13 | .\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 14 | .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 15 | .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 16 | .\" | ||
| 17 | .Dd $Mdocdate: September 25 2013 $ | ||
| 18 | .Dt WCSLCPY 3 | ||
| 19 | .Os | ||
| 20 | .Sh NAME | ||
| 21 | .Nm wcslcpy , | ||
| 22 | .Nm wcslcat | ||
| 23 | .Nd size-bounded wide string copying and concatenation | ||
| 24 | .Sh SYNOPSIS | ||
| 25 | .In wchar.h | ||
| 26 | .Ft size_t | ||
| 27 | .Fn wcslcpy "wchar_t *dst" "const wchar_t *src" "size_t size" | ||
| 28 | .Ft size_t | ||
| 29 | .Fn wcslcat "wchar_t *dst" "const wchar_t *src" "size_t size" | ||
| 30 | .Sh DESCRIPTION | ||
| 31 | The | ||
| 32 | .Fn wcslcpy | ||
| 33 | and | ||
| 34 | .Fn wcslcat | ||
| 35 | functions copy and concatenate wide strings respectively. | ||
| 36 | They are designed to be safer, more consistent, and less error prone | ||
| 37 | replacements for | ||
| 38 | .Xr wcsncpy 3 | ||
| 39 | and | ||
| 40 | .Xr wcsncat 3 . | ||
| 41 | Unlike those functions, | ||
| 42 | .Fn wcslcpy | ||
| 43 | and | ||
| 44 | .Fn wcslcat | ||
| 45 | take the full size of the buffer (not just the length) and guarantee to | ||
| 46 | terminate the result with a null wide character (as long as | ||
| 47 | .Fa size | ||
| 48 | is larger than 0 or, in the case of | ||
| 49 | .Fn wcslcat , | ||
| 50 | as long as there is at least one wide character free in | ||
| 51 | .Fa dst ) . | ||
| 52 | Note that a wide character for the null wide character should be included in | ||
| 53 | .Fa size . | ||
| 54 | Also note that | ||
| 55 | .Fn wcslcpy | ||
| 56 | and | ||
| 57 | .Fn wcslcat | ||
| 58 | only operate on wide strings that are terminated with a null wide character | ||
| 59 | (L'\e0'). | ||
| 60 | This means that for | ||
| 61 | .Fn wcslcpy | ||
| 62 | .Fa src | ||
| 63 | must be terminated with a null wide character and for | ||
| 64 | .Fn wcslcat | ||
| 65 | both | ||
| 66 | .Fa src | ||
| 67 | and | ||
| 68 | .Fa dst | ||
| 69 | must be terminated with a null wide character. | ||
| 70 | .Pp | ||
| 71 | The | ||
| 72 | .Fn wcslcpy | ||
| 73 | function copies up to | ||
| 74 | .Fa size | ||
| 75 | \(mi 1 wide characters from the wide string | ||
| 76 | .Fa src | ||
| 77 | to | ||
| 78 | .Fa dst , | ||
| 79 | terminating the result with a null wide character. | ||
| 80 | .Pp | ||
| 81 | The | ||
| 82 | .Fn wcslcat | ||
| 83 | function appends the wide string | ||
| 84 | .Fa src | ||
| 85 | to the end of | ||
| 86 | .Fa dst . | ||
| 87 | It will append at most | ||
| 88 | .Fa size | ||
| 89 | \(mi wcslen(dst) \(mi 1 wide characters, terminating the result with a null | ||
| 90 | wide character. | ||
| 91 | .Pp | ||
| 92 | If the | ||
| 93 | .Fa src | ||
| 94 | and | ||
| 95 | .Fa dst | ||
| 96 | strings overlap, the behavior is undefined. | ||
| 97 | .Sh RETURN VALUES | ||
| 98 | The | ||
| 99 | .Fn wcslcpy | ||
| 100 | and | ||
| 101 | .Fn wcslcat | ||
| 102 | functions return the total length of the wide string they tried to create. | ||
| 103 | For | ||
| 104 | .Fn wcslcpy | ||
| 105 | that means the length of | ||
| 106 | .Fa src . | ||
| 107 | For | ||
| 108 | .Fn wcslcat | ||
| 109 | that means the initial length of | ||
| 110 | .Fa dst | ||
| 111 | plus | ||
| 112 | the length of | ||
| 113 | .Fa src . | ||
| 114 | While this may seem somewhat confusing, it was done to make | ||
| 115 | truncation detection simple. | ||
| 116 | .Pp | ||
| 117 | Note, however, that if | ||
| 118 | .Fn wcslcat | ||
| 119 | traverses | ||
| 120 | .Fa size | ||
| 121 | wide characters without finding a null wide character, the length of the | ||
| 122 | string is considered to be | ||
| 123 | .Fa size | ||
| 124 | and the destination wide string will not be terminated with a null wide | ||
| 125 | character (since there was no space for it). | ||
| 126 | This keeps | ||
| 127 | .Fn wcslcat | ||
| 128 | from running off the end of a wide string. | ||
| 129 | In practice this should not happen (as it means that either | ||
| 130 | .Fa size | ||
| 131 | is incorrect or that | ||
| 132 | .Fa dst | ||
| 133 | is not terminated with a null wide character). | ||
| 134 | The check exists to prevent potential security problems in incorrect code. | ||
| 135 | .Sh SEE ALSO | ||
| 136 | .Xr strlcpy 3 , | ||
| 137 | .Xr swprintf 3 , | ||
| 138 | .Xr wcsncat 3 , | ||
| 139 | .Xr wcsncpy 3 | ||
| 140 | .Sh HISTORY | ||
| 141 | The | ||
| 142 | .Fn wcslcpy | ||
| 143 | and | ||
| 144 | .Fn wcslcat | ||
| 145 | functions first appeared in | ||
| 146 | .Ox 3.8 . | ||
| 147 | .Sh AUTHORS | ||
| 148 | The | ||
| 149 | .Fn wcslcpy | ||
| 150 | and | ||
| 151 | .Fn wcslcat | ||
| 152 | functions are based on code by | ||
| 153 | .An Todd C. Miller Aq Mt Todd.Miller@courtesan.com . | ||
diff --git a/src/lib/libc/string/wcslcpy.c b/src/lib/libc/string/wcslcpy.c new file mode 100644 index 0000000000..f49936a885 --- /dev/null +++ b/src/lib/libc/string/wcslcpy.c | |||
| @@ -0,0 +1,52 @@ | |||
| 1 | /* $OpenBSD: wcslcpy.c,v 1.5 2011/07/24 15:21:28 millert Exp $ */ | ||
| 2 | /* $NetBSD: wcslcpy.c,v 1.2 2001/01/03 14:33:02 lukem Exp $ */ | ||
| 3 | |||
| 4 | /* | ||
| 5 | * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> | ||
| 6 | * | ||
| 7 | * Permission to use, copy, modify, and distribute this software for any | ||
| 8 | * purpose with or without fee is hereby granted, provided that the above | ||
| 9 | * copyright notice and this permission notice appear in all copies. | ||
| 10 | * | ||
| 11 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 12 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 13 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 14 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 15 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 16 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 17 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <sys/types.h> | ||
| 21 | #include <wchar.h> | ||
| 22 | |||
| 23 | /* | ||
| 24 | * Copy src to string dst of size siz. At most siz-1 characters | ||
| 25 | * will be copied. Always NUL terminates (unless siz == 0). | ||
| 26 | * Returns wcslen(src); if retval >= siz, truncation occurred. | ||
| 27 | */ | ||
| 28 | size_t | ||
| 29 | wcslcpy(wchar_t *dst, const wchar_t *src, size_t siz) | ||
| 30 | { | ||
| 31 | wchar_t *d = dst; | ||
| 32 | const wchar_t *s = src; | ||
| 33 | size_t n = siz; | ||
| 34 | |||
| 35 | /* Copy as many bytes as will fit */ | ||
| 36 | if (n != 0) { | ||
| 37 | while (--n != 0) { | ||
| 38 | if ((*d++ = *s++) == '\0') | ||
| 39 | break; | ||
| 40 | } | ||
| 41 | } | ||
| 42 | |||
| 43 | /* Not enough room in dst, add NUL and traverse rest of src */ | ||
| 44 | if (n == 0) { | ||
| 45 | if (siz != 0) | ||
| 46 | *d = '\0'; /* NUL-terminate dst */ | ||
| 47 | while (*s++) | ||
| 48 | ; | ||
| 49 | } | ||
| 50 | |||
| 51 | return(s - src - 1); /* count does not include NUL */ | ||
| 52 | } | ||
diff --git a/src/lib/libc/string/rindex.3 b/src/lib/libc/string/wcslen.3 index b13b3513e0..12f81763ba 100644 --- a/src/lib/libc/string/rindex.3 +++ b/src/lib/libc/string/wcslen.3 | |||
| @@ -1,8 +1,12 @@ | |||
| 1 | .\" $OpenBSD: wcslen.3,v 1.3 2013/06/05 03:39:23 tedu Exp $ | ||
| 2 | .\" | ||
| 1 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. | 3 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. |
| 2 | .\" All rights reserved. | 4 | .\" All rights reserved. |
| 3 | .\" | 5 | .\" |
| 4 | .\" This code is derived from software contributed to Berkeley by | 6 | .\" This code is derived from software contributed to Berkeley by |
| 5 | .\" Chris Torek. | 7 | .\" Chris Torek and the American National Standards Committee X3, |
| 8 | .\" on Information Processing Systems. | ||
| 9 | .\" | ||
| 6 | .\" Redistribution and use in source and binary forms, with or without | 10 | .\" Redistribution and use in source and binary forms, with or without |
| 7 | .\" modification, are permitted provided that the following conditions | 11 | .\" modification, are permitted provided that the following conditions |
| 8 | .\" are met: | 12 | .\" are met: |
| @@ -11,11 +15,7 @@ | |||
| 11 | .\" 2. Redistributions in binary form must reproduce the above copyright | 15 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 12 | .\" notice, this list of conditions and the following disclaimer in the | 16 | .\" notice, this list of conditions and the following disclaimer in the |
| 13 | .\" documentation and/or other materials provided with the distribution. | 17 | .\" documentation and/or other materials provided with the distribution. |
| 14 | .\" 3. All advertising materials mentioning features or use of this software | 18 | .\" 3. Neither the name of the University nor the names of its contributors |
| 15 | .\" must display the following acknowledgement: | ||
| 16 | .\" This product includes software developed by the University of | ||
| 17 | .\" California, Berkeley and its contributors. | ||
| 18 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 19 | .\" may be used to endorse or promote products derived from this software | 19 | .\" may be used to endorse or promote products derived from this software |
| 20 | .\" without specific prior written permission. | 20 | .\" without specific prior written permission. |
| 21 | .\" | 21 | .\" |
| @@ -31,51 +31,40 @@ | |||
| 31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 32 | .\" SUCH DAMAGE. | 32 | .\" SUCH DAMAGE. |
| 33 | .\" | 33 | .\" |
| 34 | .\" from: @(#)rindex.3 5.2 (Berkeley) 4/19/91 | 34 | .Dd $Mdocdate: June 5 2013 $ |
| 35 | .\" $Id: rindex.3,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $ | 35 | .Dt WCSLEN 3 |
| 36 | .\" | ||
| 37 | .Dd April 19, 1991 | ||
| 38 | .Dt RINDEX 3 | ||
| 39 | .Os | 36 | .Os |
| 40 | .Sh NAME | 37 | .Sh NAME |
| 41 | .Nm rindex | 38 | .Nm wcslen |
| 42 | .Nd locate character in string | 39 | .Nd find length of a wide string |
| 43 | .Sh SYNOPSIS | 40 | .Sh SYNOPSIS |
| 44 | .Fd #include <string.h> | 41 | .In wchar.h |
| 45 | .Ft char * | 42 | .Ft size_t |
| 46 | .Fn rindex "const char *s" "int c" | 43 | .Fn wcslen "const wchar_t *s" |
| 47 | .Sh DESCRIPTION | 44 | .Sh DESCRIPTION |
| 48 | The | 45 | The |
| 49 | .Fn rindex | 46 | .Fn wcslen |
| 50 | function | 47 | function computes the length of the wide string |
| 51 | locates the last character | ||
| 52 | matching | ||
| 53 | .Fa c | ||
| 54 | (converted to a | ||
| 55 | .Em char ) | ||
| 56 | in the null-terminated string | ||
| 57 | .Fa s . | 48 | .Fa s . |
| 58 | The character c is returned if it is found; otherwise NULL is returned. | 49 | .Sh RETURN VALUES |
| 59 | If | 50 | The |
| 60 | .Fa c | 51 | .Fn wcslen |
| 61 | is | 52 | function returns the number of wide characters that precede the terminating |
| 62 | .Ql \e0 , | 53 | null wide character. |
| 63 | .Fn rindex | ||
| 64 | locates the terminating | ||
| 65 | .Ql \e0 . | ||
| 66 | .Sh SEE ALSO | 54 | .Sh SEE ALSO |
| 67 | .Xr index 3 , | 55 | .Xr strlen 3 , |
| 68 | .Xr memchr 3 , | 56 | .Xr wcswidth 3 |
| 69 | .Xr strchr 3 , | 57 | .Sh STANDARDS |
| 70 | .Xr strcspn 3 , | 58 | The |
| 71 | .Xr strpbrk 3 , | 59 | .Fn wcslen |
| 72 | .Xr strrchr 3 , | 60 | function conforms to |
| 73 | .Xr strsep 3 , | 61 | .St -isoC-99 |
| 74 | .Xr strspn 3 , | 62 | and was first introduced in |
| 75 | .Xr strstr 3 , | 63 | .St -isoC-amd1 . |
| 76 | .Xr strtok 3 | ||
| 77 | .Sh HISTORY | 64 | .Sh HISTORY |
| 78 | A | 65 | The |
| 79 | .Fn rindex | 66 | .Fn wcslen |
| 80 | function appeared in | 67 | function was ported from |
| 81 | .At v6 . | 68 | .Nx |
| 69 | and first appeared in | ||
| 70 | .Ox 3.8 . | ||
diff --git a/src/lib/libc/string/wcslen.c b/src/lib/libc/string/wcslen.c new file mode 100644 index 0000000000..c1de4a271e --- /dev/null +++ b/src/lib/libc/string/wcslen.c | |||
| @@ -0,0 +1,44 @@ | |||
| 1 | /* $OpenBSD: wcslen.c,v 1.3 2005/08/08 08:05:37 espie Exp $ */ | ||
| 2 | /* $NetBSD: wcslen.c,v 1.2 2001/01/03 14:29:36 lukem Exp $ */ | ||
| 3 | |||
| 4 | /*- | ||
| 5 | * Copyright (c)1999 Citrus Project, | ||
| 6 | * All rights reserved. | ||
| 7 | * | ||
| 8 | * Redistribution and use in source and binary forms, with or without | ||
| 9 | * modification, are permitted provided that the following conditions | ||
| 10 | * are met: | ||
| 11 | * 1. Redistributions of source code must retain the above copyright | ||
| 12 | * notice, this list of conditions and the following disclaimer. | ||
| 13 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in the | ||
| 15 | * documentation and/or other materials provided with the distribution. | ||
| 16 | * | ||
| 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | ||
| 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
| 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 27 | * SUCH DAMAGE. | ||
| 28 | * | ||
| 29 | * citrus Id: wcslen.c,v 1.1 1999/12/29 21:47:45 tshiozak Exp | ||
| 30 | */ | ||
| 31 | |||
| 32 | #include <wchar.h> | ||
| 33 | |||
| 34 | size_t | ||
| 35 | wcslen(const wchar_t *s) | ||
| 36 | { | ||
| 37 | const wchar_t *p; | ||
| 38 | |||
| 39 | p = s; | ||
| 40 | while (*p) | ||
| 41 | p++; | ||
| 42 | |||
| 43 | return p - s; | ||
| 44 | } | ||
diff --git a/src/lib/libc/string/wcsncat.c b/src/lib/libc/string/wcsncat.c new file mode 100644 index 0000000000..eb9a701514 --- /dev/null +++ b/src/lib/libc/string/wcsncat.c | |||
| @@ -0,0 +1,52 @@ | |||
| 1 | /* $OpenBSD: wcsncat.c,v 1.3 2005/08/08 08:05:37 espie Exp $ */ | ||
| 2 | /* $NetBSD: wcsncat.c,v 1.2 2001/01/03 14:29:36 lukem Exp $ */ | ||
| 3 | |||
| 4 | /*- | ||
| 5 | * Copyright (c)1999 Citrus Project, | ||
| 6 | * All rights reserved. | ||
| 7 | * | ||
| 8 | * Redistribution and use in source and binary forms, with or without | ||
| 9 | * modification, are permitted provided that the following conditions | ||
| 10 | * are met: | ||
| 11 | * 1. Redistributions of source code must retain the above copyright | ||
| 12 | * notice, this list of conditions and the following disclaimer. | ||
| 13 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in the | ||
| 15 | * documentation and/or other materials provided with the distribution. | ||
| 16 | * | ||
| 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | ||
| 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
| 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 27 | * SUCH DAMAGE. | ||
| 28 | * | ||
| 29 | * citrus Id: wcsncat.c,v 1.1 1999/12/29 21:47:45 tshiozak Exp | ||
| 30 | */ | ||
| 31 | |||
| 32 | #include <wchar.h> | ||
| 33 | |||
| 34 | wchar_t * | ||
| 35 | wcsncat(wchar_t *s1, const wchar_t *s2, size_t n) | ||
| 36 | { | ||
| 37 | wchar_t *p; | ||
| 38 | wchar_t *q; | ||
| 39 | const wchar_t *r; | ||
| 40 | |||
| 41 | p = s1; | ||
| 42 | while (*p) | ||
| 43 | p++; | ||
| 44 | q = p; | ||
| 45 | r = s2; | ||
| 46 | while (*r && n) { | ||
| 47 | *q++ = *r++; | ||
| 48 | n--; | ||
| 49 | } | ||
| 50 | *q = '\0'; | ||
| 51 | return s1; | ||
| 52 | } | ||
diff --git a/src/lib/libc/string/wcsncmp.c b/src/lib/libc/string/wcsncmp.c new file mode 100644 index 0000000000..fb3c7057cf --- /dev/null +++ b/src/lib/libc/string/wcsncmp.c | |||
| @@ -0,0 +1,52 @@ | |||
| 1 | /* $OpenBSD: wcsncmp.c,v 1.4 2005/08/08 08:05:37 espie Exp $ */ | ||
| 2 | /* $NetBSD: wcsncmp.c,v 1.5 2003/08/07 16:43:54 agc Exp $ */ | ||
| 3 | |||
| 4 | /* | ||
| 5 | * Copyright (c) 1989, 1993 | ||
| 6 | * The Regents of the University of California. All rights reserved. | ||
| 7 | * | ||
| 8 | * Redistribution and use in source and binary forms, with or without | ||
| 9 | * modification, are permitted provided that the following conditions | ||
| 10 | * are met: | ||
| 11 | * 1. Redistributions of source code must retain the above copyright | ||
| 12 | * notice, this list of conditions and the following disclaimer. | ||
| 13 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in the | ||
| 15 | * documentation and/or other materials provided with the distribution. | ||
| 16 | * 3. Neither the name of the University nor the names of its contributors | ||
| 17 | * may be used to endorse or promote products derived from this software | ||
| 18 | * without specific prior written permission. | ||
| 19 | * | ||
| 20 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
| 21 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 22 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 23 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
| 24 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 25 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 26 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 27 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 28 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 29 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 30 | * SUCH DAMAGE. | ||
| 31 | */ | ||
| 32 | |||
| 33 | #include <wchar.h> | ||
| 34 | #include "locale/runetype.h" | ||
| 35 | |||
| 36 | int | ||
| 37 | wcsncmp(const wchar_t *s1, const wchar_t *s2, size_t n) | ||
| 38 | { | ||
| 39 | |||
| 40 | if (n == 0) | ||
| 41 | return (0); | ||
| 42 | do { | ||
| 43 | if (*s1 != *s2++) { | ||
| 44 | /* XXX assumes wchar_t = int */ | ||
| 45 | return (*(const rune_t *)s1 - | ||
| 46 | *(const rune_t *)--s2); | ||
| 47 | } | ||
| 48 | if (*s1++ == 0) | ||
| 49 | break; | ||
| 50 | } while (--n != 0); | ||
| 51 | return (0); | ||
| 52 | } | ||
diff --git a/src/lib/libc/string/wcsncpy.c b/src/lib/libc/string/wcsncpy.c new file mode 100644 index 0000000000..107696f1de --- /dev/null +++ b/src/lib/libc/string/wcsncpy.c | |||
| @@ -0,0 +1,50 @@ | |||
| 1 | /* $OpenBSD: wcsncpy.c,v 1.4 2006/04/17 18:05:35 espie Exp $ */ | ||
| 2 | /* $NetBSD: wcsncpy.c,v 1.2 2001/01/03 14:29:37 lukem Exp $ */ | ||
| 3 | |||
| 4 | /*- | ||
| 5 | * Copyright (c)1999 Citrus Project, | ||
| 6 | * All rights reserved. | ||
| 7 | * | ||
| 8 | * Redistribution and use in source and binary forms, with or without | ||
| 9 | * modification, are permitted provided that the following conditions | ||
| 10 | * are met: | ||
| 11 | * 1. Redistributions of source code must retain the above copyright | ||
| 12 | * notice, this list of conditions and the following disclaimer. | ||
| 13 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in the | ||
| 15 | * documentation and/or other materials provided with the distribution. | ||
| 16 | * | ||
| 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | ||
| 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
| 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 27 | * SUCH DAMAGE. | ||
| 28 | * | ||
| 29 | * citrus Id: wcsncpy.c,v 1.1 1999/12/29 21:47:45 tshiozak Exp | ||
| 30 | */ | ||
| 31 | |||
| 32 | #include <wchar.h> | ||
| 33 | |||
| 34 | wchar_t * | ||
| 35 | wcsncpy(wchar_t *s1, const wchar_t *s2, size_t n) | ||
| 36 | { | ||
| 37 | wchar_t *p; | ||
| 38 | |||
| 39 | p = s1; | ||
| 40 | while (n && *s2) { | ||
| 41 | *p++ = *s2++; | ||
| 42 | n--; | ||
| 43 | } | ||
| 44 | while (n) { | ||
| 45 | *p++ = L'\0'; | ||
| 46 | n--; | ||
| 47 | } | ||
| 48 | |||
| 49 | return s1; | ||
| 50 | } | ||
diff --git a/src/lib/libc/string/wcspbrk.3 b/src/lib/libc/string/wcspbrk.3 new file mode 100644 index 0000000000..602bfdc3d6 --- /dev/null +++ b/src/lib/libc/string/wcspbrk.3 | |||
| @@ -0,0 +1,81 @@ | |||
| 1 | .\" $OpenBSD: wcspbrk.3,v 1.3 2013/06/05 03:39:23 tedu Exp $ | ||
| 2 | .\" | ||
| 3 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. | ||
| 4 | .\" All rights reserved. | ||
| 5 | .\" | ||
| 6 | .\" This code is derived from software contributed to Berkeley by | ||
| 7 | .\" Chris Torek and the American National Standards Committee X3, | ||
| 8 | .\" on Information Processing Systems. | ||
| 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. 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 $Mdocdate: June 5 2013 $ | ||
| 35 | .Dt WCSPBRK 3 | ||
| 36 | .Os | ||
| 37 | .Sh NAME | ||
| 38 | .Nm wcspbrk | ||
| 39 | .Nd locate multiple wide characters in a wide string | ||
| 40 | .Sh SYNOPSIS | ||
| 41 | .In wchar.h | ||
| 42 | .Ft wchar_t * | ||
| 43 | .Fn wcspbrk "const wchar_t *s" "const wchar_t *charset" | ||
| 44 | .Sh DESCRIPTION | ||
| 45 | The | ||
| 46 | .Fn wcspbrk | ||
| 47 | function locates in the wide string | ||
| 48 | .Fa s | ||
| 49 | the first occurrence of any wide character in the wide string | ||
| 50 | .Fa charset | ||
| 51 | and returns a pointer to this wide character. | ||
| 52 | If no wide characters from | ||
| 53 | .Fa charset | ||
| 54 | occur anywhere in | ||
| 55 | .Fa s , | ||
| 56 | .Fn wcspbrk | ||
| 57 | returns | ||
| 58 | .Dv NULL . | ||
| 59 | .Sh SEE ALSO | ||
| 60 | .Xr strpbrk 3 , | ||
| 61 | .Xr wcschr 3 , | ||
| 62 | .Xr wcscspn 3 , | ||
| 63 | .Xr wcsrchr 3 , | ||
| 64 | .Xr wcsspn 3 , | ||
| 65 | .Xr wcsstr 3 , | ||
| 66 | .Xr wcstok 3 , | ||
| 67 | .Xr wmemchr 3 | ||
| 68 | .Sh STANDARDS | ||
| 69 | The | ||
| 70 | .Fn wcspbrk | ||
| 71 | function conforms to | ||
| 72 | .St -isoC-99 | ||
| 73 | and was first introduced in | ||
| 74 | .St -isoC-amd1 . | ||
| 75 | .Sh HISTORY | ||
| 76 | The | ||
| 77 | .Fn wcspbrk | ||
| 78 | function was ported from | ||
| 79 | .Nx | ||
| 80 | and first appeared in | ||
| 81 | .Ox 3.8 . | ||
diff --git a/src/lib/libc/string/wcspbrk.c b/src/lib/libc/string/wcspbrk.c new file mode 100644 index 0000000000..1923abfc89 --- /dev/null +++ b/src/lib/libc/string/wcspbrk.c | |||
| @@ -0,0 +1,53 @@ | |||
| 1 | /* $OpenBSD: wcspbrk.c,v 1.3 2005/08/08 08:05:37 espie Exp $ */ | ||
| 2 | /* $NetBSD: wcspbrk.c,v 1.2 2001/01/03 14:29:37 lukem Exp $ */ | ||
| 3 | |||
| 4 | /*- | ||
| 5 | * Copyright (c)1999 Citrus Project, | ||
| 6 | * All rights reserved. | ||
| 7 | * | ||
| 8 | * Redistribution and use in source and binary forms, with or without | ||
| 9 | * modification, are permitted provided that the following conditions | ||
| 10 | * are met: | ||
| 11 | * 1. Redistributions of source code must retain the above copyright | ||
| 12 | * notice, this list of conditions and the following disclaimer. | ||
| 13 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in the | ||
| 15 | * documentation and/or other materials provided with the distribution. | ||
| 16 | * | ||
| 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | ||
| 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
| 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 27 | * SUCH DAMAGE. | ||
| 28 | * | ||
| 29 | * citrus Id: wcspbrk.c,v 1.2 2000/12/21 05:07:25 itojun Exp | ||
| 30 | */ | ||
| 31 | |||
| 32 | #include <wchar.h> | ||
| 33 | |||
| 34 | wchar_t * | ||
| 35 | wcspbrk(const wchar_t *s, const wchar_t *set) | ||
| 36 | { | ||
| 37 | const wchar_t *p; | ||
| 38 | const wchar_t *q; | ||
| 39 | |||
| 40 | p = s; | ||
| 41 | while (*p) { | ||
| 42 | q = set; | ||
| 43 | while (*q) { | ||
| 44 | if (*p == *q) { | ||
| 45 | /* LINTED interface specification */ | ||
| 46 | return (wchar_t *)p; | ||
| 47 | } | ||
| 48 | q++; | ||
| 49 | } | ||
| 50 | p++; | ||
| 51 | } | ||
| 52 | return NULL; | ||
| 53 | } | ||
diff --git a/src/lib/libc/string/wcsrchr.3 b/src/lib/libc/string/wcsrchr.3 new file mode 100644 index 0000000000..d4a2e7cf78 --- /dev/null +++ b/src/lib/libc/string/wcsrchr.3 | |||
| @@ -0,0 +1,85 @@ | |||
| 1 | .\" $OpenBSD: wcsrchr.3,v 1.3 2013/06/05 03:39:23 tedu Exp $ | ||
| 2 | .\" | ||
| 3 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. | ||
| 4 | .\" All rights reserved. | ||
| 5 | .\" | ||
| 6 | .\" This code is derived from software contributed to Berkeley by | ||
| 7 | .\" Chris Torek and the American National Standards Committee X3, | ||
| 8 | .\" on Information Processing Systems. | ||
| 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. 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 $Mdocdate: June 5 2013 $ | ||
| 35 | .Dt WCSRCHR 3 | ||
| 36 | .Os | ||
| 37 | .Sh NAME | ||
| 38 | .Nm wcsrchr | ||
| 39 | .Nd locate last occurrence of a wide character in a wide string | ||
| 40 | .Sh SYNOPSIS | ||
| 41 | .In wchar.h | ||
| 42 | .Ft wchar_t * | ||
| 43 | .Fn wcsrchr "const wchar_t *s" "wchar_t c" | ||
| 44 | .Sh DESCRIPTION | ||
| 45 | The | ||
| 46 | .Fn wcsrchr | ||
| 47 | function locates the last occurrence of the wide character | ||
| 48 | .Fa c | ||
| 49 | in the wide string | ||
| 50 | .Fa s . | ||
| 51 | The terminating null wide character is considered part of the wide string. | ||
| 52 | If | ||
| 53 | .Fa c | ||
| 54 | is the null wide character (L'\e0'), | ||
| 55 | .Fn wcsrchr | ||
| 56 | locates the terminating null wide character. | ||
| 57 | .Sh RETURN VALUES | ||
| 58 | The | ||
| 59 | .Fn wcsrchr | ||
| 60 | function returns a pointer to the located wide character or | ||
| 61 | .Dv NULL | ||
| 62 | if the wide character does not appear in the wide string. | ||
| 63 | .Sh SEE ALSO | ||
| 64 | .Xr strrchr 3 , | ||
| 65 | .Xr wcschr 3 , | ||
| 66 | .Xr wcscspn 3 , | ||
| 67 | .Xr wcspbrk 3 , | ||
| 68 | .Xr wcsspn 3 , | ||
| 69 | .Xr wcsstr 3 , | ||
| 70 | .Xr wcstok 3 , | ||
| 71 | .Xr wmemchr 3 | ||
| 72 | .Sh STANDARDS | ||
| 73 | The | ||
| 74 | .Fn wcsrchr | ||
| 75 | function conforms to | ||
| 76 | .St -isoC-99 | ||
| 77 | and was first introduced in | ||
| 78 | .St -isoC-amd1 . | ||
| 79 | .Sh HISTORY | ||
| 80 | The | ||
| 81 | .Fn wcsrchr | ||
| 82 | function was ported from | ||
| 83 | .Nx | ||
| 84 | and first appeared in | ||
| 85 | .Ox 3.8 . | ||
diff --git a/src/lib/libc/string/wcsrchr.c b/src/lib/libc/string/wcsrchr.c new file mode 100644 index 0000000000..3433310c56 --- /dev/null +++ b/src/lib/libc/string/wcsrchr.c | |||
| @@ -0,0 +1,50 @@ | |||
| 1 | /* $OpenBSD: wcsrchr.c,v 1.3 2005/08/08 08:05:37 espie Exp $ */ | ||
| 2 | /* $NetBSD: wcsrchr.c,v 1.2 2001/01/03 14:29:37 lukem Exp $ */ | ||
| 3 | |||
| 4 | /*- | ||
| 5 | * Copyright (c)1999 Citrus Project, | ||
| 6 | * All rights reserved. | ||
| 7 | * | ||
| 8 | * Redistribution and use in source and binary forms, with or without | ||
| 9 | * modification, are permitted provided that the following conditions | ||
| 10 | * are met: | ||
| 11 | * 1. Redistributions of source code must retain the above copyright | ||
| 12 | * notice, this list of conditions and the following disclaimer. | ||
| 13 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in the | ||
| 15 | * documentation and/or other materials provided with the distribution. | ||
| 16 | * | ||
| 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | ||
| 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
| 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 27 | * SUCH DAMAGE. | ||
| 28 | * | ||
| 29 | * citrus Id: wcsrchr.c,v 1.2 2000/12/21 05:07:25 itojun Exp | ||
| 30 | */ | ||
| 31 | |||
| 32 | #include <wchar.h> | ||
| 33 | |||
| 34 | wchar_t * | ||
| 35 | wcsrchr(const wchar_t *s, wchar_t c) | ||
| 36 | { | ||
| 37 | const wchar_t *p; | ||
| 38 | |||
| 39 | p = s; | ||
| 40 | while (*p) | ||
| 41 | p++; | ||
| 42 | while (s <= p) { | ||
| 43 | if (*p == c) { | ||
| 44 | /* LINTED interface specification */ | ||
| 45 | return (wchar_t *)p; | ||
| 46 | } | ||
| 47 | p--; | ||
| 48 | } | ||
| 49 | return NULL; | ||
| 50 | } | ||
diff --git a/src/lib/libc/string/wcsspn.3 b/src/lib/libc/string/wcsspn.3 new file mode 100644 index 0000000000..3be82344dd --- /dev/null +++ b/src/lib/libc/string/wcsspn.3 | |||
| @@ -0,0 +1,79 @@ | |||
| 1 | .\" $OpenBSD: wcsspn.3,v 1.3 2013/06/05 03:39:23 tedu Exp $ | ||
| 2 | .\" | ||
| 3 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. | ||
| 4 | .\" All rights reserved. | ||
| 5 | .\" | ||
| 6 | .\" This code is derived from software contributed to Berkeley by | ||
| 7 | .\" Chris Torek and the American National Standards Committee X3, | ||
| 8 | .\" on Information Processing Systems. | ||
| 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. 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 $Mdocdate: June 5 2013 $ | ||
| 35 | .Dt WCSSPN 3 | ||
| 36 | .Os | ||
| 37 | .Sh NAME | ||
| 38 | .Nm wcsspn | ||
| 39 | .Nd span a wide string | ||
| 40 | .Sh SYNOPSIS | ||
| 41 | .In wchar.h | ||
| 42 | .Ft size_t | ||
| 43 | .Fn wcsspn "const wchar_t *s" "const wchar_t *charset" | ||
| 44 | .Sh DESCRIPTION | ||
| 45 | The | ||
| 46 | .Fn wcsspn | ||
| 47 | function spans the initial part of the wide string | ||
| 48 | .Fa s | ||
| 49 | as long as the wide characters from | ||
| 50 | .Fa s | ||
| 51 | occur in the wide string | ||
| 52 | .Fa charset . | ||
| 53 | .Sh RETURN VALUES | ||
| 54 | The | ||
| 55 | .Fn wcsspn | ||
| 56 | function returns the number of wide characters spanned. | ||
| 57 | .Sh SEE ALSO | ||
| 58 | .Xr strspn 3 , | ||
| 59 | .Xr wcschr 3 , | ||
| 60 | .Xr wcscspn 3 , | ||
| 61 | .Xr wcspbrk 3 , | ||
| 62 | .Xr wcsrchr 3 , | ||
| 63 | .Xr wcsstr 3 , | ||
| 64 | .Xr wcstok 3 , | ||
| 65 | .Xr wmemchr 3 | ||
| 66 | .Sh STANDARDS | ||
| 67 | The | ||
| 68 | .Fn wcsspn | ||
| 69 | function conforms to | ||
| 70 | .St -isoC-99 | ||
| 71 | and was first introduced in | ||
| 72 | .St -isoC-amd1 . | ||
| 73 | .Sh HISTORY | ||
| 74 | The | ||
| 75 | .Fn wcsspn | ||
| 76 | function was ported from | ||
| 77 | .Nx | ||
| 78 | and first appeared in | ||
| 79 | .Ox 3.8 . | ||
diff --git a/src/lib/libc/string/wcsspn.c b/src/lib/libc/string/wcsspn.c new file mode 100644 index 0000000000..5162fa0763 --- /dev/null +++ b/src/lib/libc/string/wcsspn.c | |||
| @@ -0,0 +1,55 @@ | |||
| 1 | /* $OpenBSD: wcsspn.c,v 1.3 2005/08/08 08:05:37 espie Exp $ */ | ||
| 2 | /* $NetBSD: wcsspn.c,v 1.3 2001/09/21 16:09:15 yamt Exp $ */ | ||
| 3 | |||
| 4 | /*- | ||
| 5 | * Copyright (c)1999,2001 Citrus Project, | ||
| 6 | * All rights reserved. | ||
| 7 | * | ||
| 8 | * Redistribution and use in source and binary forms, with or without | ||
| 9 | * modification, are permitted provided that the following conditions | ||
| 10 | * are met: | ||
| 11 | * 1. Redistributions of source code must retain the above copyright | ||
| 12 | * notice, this list of conditions and the following disclaimer. | ||
| 13 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in the | ||
| 15 | * documentation and/or other materials provided with the distribution. | ||
| 16 | * | ||
| 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | ||
| 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
| 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 27 | * SUCH DAMAGE. | ||
| 28 | * | ||
| 29 | * $Citrus: xpg4dl/FreeBSD/lib/libc/string/wcsspn.c,v 1.3 2001/09/21 16:06:43 yamt Exp $ | ||
| 30 | */ | ||
| 31 | |||
| 32 | #include <wchar.h> | ||
| 33 | |||
| 34 | size_t | ||
| 35 | wcsspn(const wchar_t *s, const wchar_t *set) | ||
| 36 | { | ||
| 37 | const wchar_t *p; | ||
| 38 | const wchar_t *q; | ||
| 39 | |||
| 40 | p = s; | ||
| 41 | while (*p) { | ||
| 42 | q = set; | ||
| 43 | while (*q) { | ||
| 44 | if (*p == *q) | ||
| 45 | break; | ||
| 46 | q++; | ||
| 47 | } | ||
| 48 | if (!*q) | ||
| 49 | goto done; | ||
| 50 | p++; | ||
| 51 | } | ||
| 52 | |||
| 53 | done: | ||
| 54 | return (p - s); | ||
| 55 | } | ||
diff --git a/src/lib/libc/string/wcsstr.3 b/src/lib/libc/string/wcsstr.3 new file mode 100644 index 0000000000..203a76ded3 --- /dev/null +++ b/src/lib/libc/string/wcsstr.3 | |||
| @@ -0,0 +1,88 @@ | |||
| 1 | .\" $OpenBSD: wcsstr.3,v 1.3 2013/06/05 03:39:23 tedu Exp $ | ||
| 2 | .\" | ||
| 3 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. | ||
| 4 | .\" All rights reserved. | ||
| 5 | .\" | ||
| 6 | .\" This code is derived from software contributed to Berkeley by | ||
| 7 | .\" Chris Torek and the American National Standards Committee X3, | ||
| 8 | .\" on Information Processing Systems. | ||
| 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. 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 $Mdocdate: June 5 2013 $ | ||
| 35 | .Dt WCSSTR 3 | ||
| 36 | .Os | ||
| 37 | .Sh NAME | ||
| 38 | .Nm wcsstr | ||
| 39 | .Nd locate a wide substring in a wide string | ||
| 40 | .Sh SYNOPSIS | ||
| 41 | .In wchar.h | ||
| 42 | .Ft wchar_t * | ||
| 43 | .Fn wcsstr "const wchar_t *big" "const wchar_t *little" | ||
| 44 | .Sh DESCRIPTION | ||
| 45 | The | ||
| 46 | .Fn wcsstr | ||
| 47 | function locates the first occurrence of the wide string | ||
| 48 | .Fa little | ||
| 49 | in the wide string | ||
| 50 | .Fa big . | ||
| 51 | .Pp | ||
| 52 | If | ||
| 53 | .Fa little | ||
| 54 | is an empty wide string, | ||
| 55 | .Fa big | ||
| 56 | is returned; | ||
| 57 | if | ||
| 58 | .Fa little | ||
| 59 | occurs nowhere in | ||
| 60 | .Fa big , | ||
| 61 | .Dv NULL | ||
| 62 | is returned; | ||
| 63 | otherwise a pointer to the first wide character of the first occurrence of | ||
| 64 | .Fa little | ||
| 65 | is returned. | ||
| 66 | .Sh SEE ALSO | ||
| 67 | .Xr strstr 3 , | ||
| 68 | .Xr wcschr 3 , | ||
| 69 | .Xr wcscspn 3 , | ||
| 70 | .Xr wcspbrk 3 , | ||
| 71 | .Xr wcsrchr 3 , | ||
| 72 | .Xr wcsspn 3 , | ||
| 73 | .Xr wcstok 3 , | ||
| 74 | .Xr wmemchr 3 | ||
| 75 | .Sh STANDARDS | ||
| 76 | The | ||
| 77 | .Fn wcsstr | ||
| 78 | function conforms to | ||
| 79 | .St -isoC-99 | ||
| 80 | and was first introduced in | ||
| 81 | .St -isoC-amd1 . | ||
| 82 | .Sh HISTORY | ||
| 83 | The | ||
| 84 | .Fn wcsstr | ||
| 85 | function was ported from | ||
| 86 | .Nx | ||
| 87 | and first appeared in | ||
| 88 | .Ox 3.8 . | ||
diff --git a/src/lib/libc/string/wcsstr.c b/src/lib/libc/string/wcsstr.c new file mode 100644 index 0000000000..669e340280 --- /dev/null +++ b/src/lib/libc/string/wcsstr.c | |||
| @@ -0,0 +1,70 @@ | |||
| 1 | /* $OpenBSD: wcsstr.c,v 1.3 2005/08/08 08:05:37 espie Exp $ */ | ||
| 2 | /* $NetBSD: wcsstr.c,v 1.3 2003/03/05 20:18:17 tshiozak Exp $ */ | ||
| 3 | |||
| 4 | /*- | ||
| 5 | * Copyright (c)1999 Citrus Project, | ||
| 6 | * All rights reserved. | ||
| 7 | * | ||
| 8 | * Redistribution and use in source and binary forms, with or without | ||
| 9 | * modification, are permitted provided that the following conditions | ||
| 10 | * are met: | ||
| 11 | * 1. Redistributions of source code must retain the above copyright | ||
| 12 | * notice, this list of conditions and the following disclaimer. | ||
| 13 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in the | ||
| 15 | * documentation and/or other materials provided with the distribution. | ||
| 16 | * | ||
| 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | ||
| 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
| 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 27 | * SUCH DAMAGE. | ||
| 28 | * | ||
| 29 | * citrus Id: wcsstr.c,v 1.2 2000/12/21 05:07:25 itojun Exp | ||
| 30 | */ | ||
| 31 | |||
| 32 | #include <wchar.h> | ||
| 33 | |||
| 34 | wchar_t * | ||
| 35 | #ifdef WCSWCS | ||
| 36 | wcswcs(const wchar_t *big, const wchar_t *little) | ||
| 37 | #else | ||
| 38 | wcsstr(const wchar_t *big, const wchar_t *little) | ||
| 39 | #endif | ||
| 40 | { | ||
| 41 | const wchar_t *p; | ||
| 42 | const wchar_t *q; | ||
| 43 | const wchar_t *r; | ||
| 44 | |||
| 45 | if (!*little) { | ||
| 46 | /* LINTED interface specification */ | ||
| 47 | return (wchar_t *)big; | ||
| 48 | } | ||
| 49 | if (wcslen(big) < wcslen(little)) | ||
| 50 | return NULL; | ||
| 51 | |||
| 52 | p = big; | ||
| 53 | q = little; | ||
| 54 | while (*p) { | ||
| 55 | q = little; | ||
| 56 | r = p; | ||
| 57 | while (*q) { | ||
| 58 | if (*r != *q) | ||
| 59 | break; | ||
| 60 | q++; | ||
| 61 | r++; | ||
| 62 | } | ||
| 63 | if (!*q) { | ||
| 64 | /* LINTED interface specification */ | ||
| 65 | return (wchar_t *)p; | ||
| 66 | } | ||
| 67 | p++; | ||
| 68 | } | ||
| 69 | return NULL; | ||
| 70 | } | ||
diff --git a/src/lib/libc/string/wcstok.3 b/src/lib/libc/string/wcstok.3 new file mode 100644 index 0000000000..33ba1318a1 --- /dev/null +++ b/src/lib/libc/string/wcstok.3 | |||
| @@ -0,0 +1,151 @@ | |||
| 1 | .\" $OpenBSD: wcstok.3,v 1.7 2011/07/25 00:38:53 schwarze Exp $ | ||
| 2 | .\" | ||
| 3 | .\" $NetBSD: wcstok.3,v 1.3 2003/09/08 17:54:33 wiz Exp $ | ||
| 4 | .\" | ||
| 5 | .\" Copyright (c) 1998 Softweyr LLC. All rights reserved. | ||
| 6 | .\" | ||
| 7 | .\" strtok_r, from Berkeley strtok | ||
| 8 | .\" Oct 13, 1998 by Wes Peters <wes@softweyr.com> | ||
| 9 | .\" | ||
| 10 | .\" Copyright (c) 1988, 1991, 1993 | ||
| 11 | .\" The Regents of the University of California. All rights reserved. | ||
| 12 | .\" | ||
| 13 | .\" This code is derived from software contributed to Berkeley by | ||
| 14 | .\" the American National Standards Committee X3, on Information | ||
| 15 | .\" Processing Systems. | ||
| 16 | .\" | ||
| 17 | .\" Redistribution and use in source and binary forms, with or without | ||
| 18 | .\" modification, are permitted provided that the following conditions | ||
| 19 | .\" are met: | ||
| 20 | .\" | ||
| 21 | .\" 1. Redistributions of source code must retain the above copyright | ||
| 22 | .\" notices, this list of conditions and the following disclaimer. | ||
| 23 | .\" | ||
| 24 | .\" 2. Redistributions in binary form must reproduce the above | ||
| 25 | .\" copyright notices, this list of conditions and the following | ||
| 26 | .\" disclaimer in the documentation and/or other materials provided | ||
| 27 | .\" with the distribution. | ||
| 28 | .\" | ||
| 29 | .\" 3. All advertising materials mentioning features or use of this | ||
| 30 | .\" software must display the following acknowledgement: | ||
| 31 | .\" | ||
| 32 | .\" This product includes software developed by Softweyr LLC, the | ||
| 33 | .\" University of California, Berkeley, and its contributors. | ||
| 34 | .\" | ||
| 35 | .\" 4. Neither the name of Softweyr LLC, the University nor the names | ||
| 36 | .\" of its contributors may be used to endorse or promote products | ||
| 37 | .\" derived from this software without specific prior written | ||
| 38 | .\" permission. | ||
| 39 | .\" | ||
| 40 | .\" THIS SOFTWARE IS PROVIDED BY SOFTWEYR LLC, THE REGENTS AND | ||
| 41 | .\" CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, | ||
| 42 | .\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
| 43 | .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
| 44 | .\" DISCLAIMED. IN NO EVENT SHALL SOFTWEYR LLC, THE REGENTS, OR | ||
| 45 | .\" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
| 46 | .\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
| 47 | .\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
| 48 | .\" USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
| 49 | .\" ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | ||
| 50 | .\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | ||
| 51 | .\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 52 | .\" SUCH DAMAGE. | ||
| 53 | .\" | ||
| 54 | .\" Original version ID: | ||
| 55 | .\" FreeBSD: src/lib/libc/string/wcstok.3,v 1.4 2002/10/15 09:49:54 tjr Exp | ||
| 56 | .\" | ||
| 57 | .Dd $Mdocdate: July 25 2011 $ | ||
| 58 | .Dt WCSTOK 3 | ||
| 59 | .Os | ||
| 60 | .Sh NAME | ||
| 61 | .Nm wcstok | ||
| 62 | .Nd split wide-character string into tokens | ||
| 63 | .Sh SYNOPSIS | ||
| 64 | .In wchar.h | ||
| 65 | .Ft wchar_t * | ||
| 66 | .Fn wcstok "wchar_t * restrict str" "const wchar_t * restrict sep" "wchar_t ** restrict last" | ||
| 67 | .Sh DESCRIPTION | ||
| 68 | The | ||
| 69 | .Fn wcstok | ||
| 70 | function | ||
| 71 | is used to isolate sequential tokens in a NUL-terminated wide-character | ||
| 72 | string, | ||
| 73 | .Fa str . | ||
| 74 | These tokens are separated in the string by at least one of the | ||
| 75 | characters in | ||
| 76 | .Fa sep . | ||
| 77 | The first time that | ||
| 78 | .Fn wcstok | ||
| 79 | is called, | ||
| 80 | .Fa str | ||
| 81 | should be specified; subsequent calls, wishing to obtain further tokens | ||
| 82 | from the same string, should pass a null pointer instead. | ||
| 83 | The separator string, | ||
| 84 | .Fa sep , | ||
| 85 | must be supplied each time, and may change between calls. | ||
| 86 | The context pointer | ||
| 87 | .Fa last | ||
| 88 | must be provided on each call. | ||
| 89 | .Pp | ||
| 90 | The | ||
| 91 | .Fn wcstok | ||
| 92 | function is the wide-character counterpart of the | ||
| 93 | .Xr strtok_r 3 | ||
| 94 | function. | ||
| 95 | .Pp | ||
| 96 | Since | ||
| 97 | .Fn wcstok | ||
| 98 | modifies the string, | ||
| 99 | .Fa str | ||
| 100 | should not point to an area in the initialized data segment. | ||
| 101 | .Sh RETURN VALUES | ||
| 102 | The | ||
| 103 | .Fn wcstok | ||
| 104 | function | ||
| 105 | returns a pointer to the beginning of each subsequent token in the string, | ||
| 106 | after replacing the token itself with a NUL wide character (L'\e0'). | ||
| 107 | When no more tokens remain, a null pointer is returned. | ||
| 108 | .Sh EXAMPLES | ||
| 109 | The following code fragment splits a wide-character string on | ||
| 110 | .Tn ASCII | ||
| 111 | space, tab, and newline characters and writes the tokens to | ||
| 112 | standard output: | ||
| 113 | .Bd -literal -offset indent | ||
| 114 | const wchar_t *seps = L" \et\en"; | ||
| 115 | wchar_t *last, *tok, text[] = L" \enone\ettwo\et\etthree \en"; | ||
| 116 | |||
| 117 | for (tok = wcstok(text, seps, &last); tok != NULL; | ||
| 118 | tok = wcstok(NULL, seps, &last)) | ||
| 119 | wprintf(L"%ls\en", tok); | ||
| 120 | .Ed | ||
| 121 | .Sh SEE ALSO | ||
| 122 | .Xr strtok 3 , | ||
| 123 | .Xr wcschr 3 , | ||
| 124 | .Xr wcscspn 3 , | ||
| 125 | .Xr wcspbrk 3 , | ||
| 126 | .Xr wcsrchr 3 , | ||
| 127 | .Xr wcsspn 3 , | ||
| 128 | .Xr wcsstr 3 , | ||
| 129 | .Xr wmemchr 3 | ||
| 130 | .Sh STANDARDS | ||
| 131 | The | ||
| 132 | .Fn wcstok | ||
| 133 | function | ||
| 134 | conforms to | ||
| 135 | .St -isoC-99 . | ||
| 136 | .Sh HISTORY | ||
| 137 | The | ||
| 138 | .Fn wcstok | ||
| 139 | function was ported from | ||
| 140 | .Nx | ||
| 141 | and first appeared in | ||
| 142 | .Ox 3.8 . | ||
| 143 | .Pp | ||
| 144 | Some early implementations of | ||
| 145 | .Fn wcstok | ||
| 146 | omit the | ||
| 147 | context pointer argument, | ||
| 148 | .Fa last , | ||
| 149 | and maintain state across calls in a static variable like | ||
| 150 | .Xr strtok 3 | ||
| 151 | does. | ||
diff --git a/src/lib/libc/string/wcstok.c b/src/lib/libc/string/wcstok.c new file mode 100644 index 0000000000..bc1ac3e8cb --- /dev/null +++ b/src/lib/libc/string/wcstok.c | |||
| @@ -0,0 +1,93 @@ | |||
| 1 | /* $OpenBSD: wcstok.c,v 1.3 2005/08/08 08:05:37 espie Exp $ */ | ||
| 2 | /* $NetBSD: wcstok.c,v 1.3 2003/07/10 08:50:48 tshiozak Exp $ */ | ||
| 3 | |||
| 4 | /*- | ||
| 5 | * Copyright (c) 1998 Softweyr LLC. All rights reserved. | ||
| 6 | * | ||
| 7 | * strtok_r, from Berkeley strtok | ||
| 8 | * Oct 13, 1998 by Wes Peters <wes@softweyr.com> | ||
| 9 | * | ||
| 10 | * Copyright (c) 1988, 1993 | ||
| 11 | * The Regents of the University of California. All rights reserved. | ||
| 12 | * | ||
| 13 | * Redistribution and use in source and binary forms, with or without | ||
| 14 | * modification, are permitted provided that the following conditions | ||
| 15 | * are met: | ||
| 16 | * 1. Redistributions of source code must retain the above copyright | ||
| 17 | * notices, this list of conditions and the following disclaimer. | ||
| 18 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 19 | * notices, this list of conditions and the following disclaimer in the | ||
| 20 | * documentation and/or other materials provided with the distribution. | ||
| 21 | * 3. All advertising materials mentioning features or use of this software | ||
| 22 | * must display the following acknowledgement: | ||
| 23 | * This product includes software developed by Softweyr LLC, the | ||
| 24 | * University of California, Berkeley, and its contributors. | ||
| 25 | * 4. Neither the name of the University nor the names of its contributors | ||
| 26 | * may be used to endorse or promote products derived from this software | ||
| 27 | * without specific prior written permission. | ||
| 28 | * | ||
| 29 | * THIS SOFTWARE IS PROVIDED BY SOFTWEYR LLC, THE REGENTS AND CONTRIBUTORS | ||
| 30 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 31 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A | ||
| 32 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SOFTWEYR LLC, THE | ||
| 33 | * REGENTS, OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
| 34 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED | ||
| 35 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
| 36 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
| 37 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
| 38 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
| 39 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 40 | * | ||
| 41 | * Original version ID: | ||
| 42 | * FreeBSD: src/lib/libc/string/wcstok.c,v 1.1 2002/09/07 08:16:57 tjr Exp | ||
| 43 | */ | ||
| 44 | |||
| 45 | #include <wchar.h> | ||
| 46 | |||
| 47 | wchar_t * | ||
| 48 | wcstok(wchar_t * __restrict s, const wchar_t * __restrict delim, | ||
| 49 | wchar_t ** __restrict last) | ||
| 50 | { | ||
| 51 | const wchar_t *spanp; | ||
| 52 | wchar_t c, sc; | ||
| 53 | wchar_t *tok; | ||
| 54 | |||
| 55 | if (s == NULL && (s = *last) == NULL) | ||
| 56 | return (NULL); | ||
| 57 | |||
| 58 | /* | ||
| 59 | * Skip (span) leading delimiters (s += wcsspn(s, delim), sort of). | ||
| 60 | */ | ||
| 61 | cont: | ||
| 62 | c = *s++; | ||
| 63 | for (spanp = delim; (sc = *spanp++) != L'\0';) { | ||
| 64 | if (c == sc) | ||
| 65 | goto cont; | ||
| 66 | } | ||
| 67 | |||
| 68 | if (c == L'\0') { /* no non-delimiter characters */ | ||
| 69 | *last = NULL; | ||
| 70 | return (NULL); | ||
| 71 | } | ||
| 72 | tok = s - 1; | ||
| 73 | |||
| 74 | /* | ||
| 75 | * Scan token (scan for delimiters: s += wcscspn(s, delim), sort of). | ||
| 76 | * Note that delim must have one NUL; we stop if we see that, too. | ||
| 77 | */ | ||
| 78 | for (;;) { | ||
| 79 | c = *s++; | ||
| 80 | spanp = delim; | ||
| 81 | do { | ||
| 82 | if ((sc = *spanp++) == c) { | ||
| 83 | if (c == L'\0') | ||
| 84 | s = NULL; | ||
| 85 | else | ||
| 86 | s[-1] = L'\0'; | ||
| 87 | *last = s; | ||
| 88 | return (tok); | ||
| 89 | } | ||
| 90 | } while (sc != L'\0'); | ||
| 91 | } | ||
| 92 | /* NOTREACHED */ | ||
| 93 | } | ||
diff --git a/src/lib/libc/string/wcswcs.c b/src/lib/libc/string/wcswcs.c new file mode 100644 index 0000000000..bd35605547 --- /dev/null +++ b/src/lib/libc/string/wcswcs.c | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | /* $OpenBSD: wcswcs.c,v 1.1 2005/04/13 16:35:58 espie Exp $ */ | ||
| 2 | /* $NetBSD: wcswcs.c,v 1.1 2003/03/05 20:18:17 tshiozak Exp $ */ | ||
| 3 | |||
| 4 | #define WCSWCS | ||
| 5 | #include "wcsstr.c" | ||
diff --git a/src/lib/libc/string/wcswidth.3 b/src/lib/libc/string/wcswidth.3 new file mode 100644 index 0000000000..a2a5b2df86 --- /dev/null +++ b/src/lib/libc/string/wcswidth.3 | |||
| @@ -0,0 +1,69 @@ | |||
| 1 | .\" $OpenBSD: wcswidth.3,v 1.2 2011/07/25 00:38:53 schwarze Exp $ | ||
| 2 | .\" | ||
| 3 | .\" Copyright (c) 2002 Tim J. Robbins | ||
| 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 | .\" | ||
| 15 | .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | ||
| 16 | .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 17 | .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 18 | .\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
| 19 | .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 20 | .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 21 | .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 22 | .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 23 | .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 24 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 25 | .\" SUCH DAMAGE. | ||
| 26 | .\" | ||
| 27 | .Dd $Mdocdate: July 25 2011 $ | ||
| 28 | .Dt WCSWIDTH 3 | ||
| 29 | .Os | ||
| 30 | .Sh NAME | ||
| 31 | .Nm wcswidth | ||
| 32 | .Nd number of column positions in wide-character string | ||
| 33 | .Sh SYNOPSIS | ||
| 34 | .In wchar.h | ||
| 35 | .Ft int | ||
| 36 | .Fn wcswidth "const wchar_t *pwcs" "size_t n" | ||
| 37 | .Sh DESCRIPTION | ||
| 38 | The | ||
| 39 | .Fn wcswidth | ||
| 40 | function determines the number of column positions required for the first | ||
| 41 | .Fa n | ||
| 42 | characters of | ||
| 43 | .Fa pwcs , | ||
| 44 | or until a null wide character (L'\e0') is encountered. | ||
| 45 | .Sh RETURN VALUES | ||
| 46 | The | ||
| 47 | .Fn wcswidth | ||
| 48 | function returns 0 if | ||
| 49 | .Fa pwcs | ||
| 50 | is an empty string (L""), | ||
| 51 | \-1 if a non-printing wide character is encountered, | ||
| 52 | otherwise it returns the number of column positions occupied. | ||
| 53 | .Sh SEE ALSO | ||
| 54 | .Xr iswprint 3 , | ||
| 55 | .Xr strlen 3 , | ||
| 56 | .Xr wcslen 3 , | ||
| 57 | .Xr wcwidth 3 | ||
| 58 | .Sh STANDARDS | ||
| 59 | The | ||
| 60 | .Fn wcswidth | ||
| 61 | function conforms to | ||
| 62 | .St -p1003.1-2001 . | ||
| 63 | .Sh HISTORY | ||
| 64 | The | ||
| 65 | .Fn wcswidth | ||
| 66 | function was ported from | ||
| 67 | .Nx | ||
| 68 | and first appeared in | ||
| 69 | .Ox 3.8 . | ||
diff --git a/src/lib/libc/string/wcswidth.c b/src/lib/libc/string/wcswidth.c new file mode 100644 index 0000000000..8ea1bdf6e6 --- /dev/null +++ b/src/lib/libc/string/wcswidth.c | |||
| @@ -0,0 +1,50 @@ | |||
| 1 | /* $OpenBSD: wcswidth.c,v 1.4 2011/04/04 18:16:24 stsp Exp $ */ | ||
| 2 | /* $NetBSD: wcswidth.c,v 1.2 2001/01/03 14:29:37 lukem Exp $ */ | ||
| 3 | |||
| 4 | /*- | ||
| 5 | * Copyright (c)1999 Citrus Project, | ||
| 6 | * All rights reserved. | ||
| 7 | * | ||
| 8 | * Redistribution and use in source and binary forms, with or without | ||
| 9 | * modification, are permitted provided that the following conditions | ||
| 10 | * are met: | ||
| 11 | * 1. Redistributions of source code must retain the above copyright | ||
| 12 | * notice, this list of conditions and the following disclaimer. | ||
| 13 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in the | ||
| 15 | * documentation and/or other materials provided with the distribution. | ||
| 16 | * | ||
| 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | ||
| 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
| 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 27 | * SUCH DAMAGE. | ||
| 28 | * | ||
| 29 | * citrus Id: wcswidth.c,v 1.1 1999/12/29 21:47:45 tshiozak Exp | ||
| 30 | */ | ||
| 31 | |||
| 32 | #include <wchar.h> | ||
| 33 | |||
| 34 | int | ||
| 35 | wcswidth(const wchar_t *s, size_t n) | ||
| 36 | { | ||
| 37 | int w, q; | ||
| 38 | |||
| 39 | w = 0; | ||
| 40 | while (n && *s) { | ||
| 41 | q = wcwidth(*s); | ||
| 42 | if (q == -1) | ||
| 43 | return (-1); | ||
| 44 | w += q; | ||
| 45 | s++; | ||
| 46 | n--; | ||
| 47 | } | ||
| 48 | |||
| 49 | return w; | ||
| 50 | } | ||
diff --git a/src/lib/libc/string/index.3 b/src/lib/libc/string/wmemchr.3 index 847b03628b..17fbc9dbc5 100644 --- a/src/lib/libc/string/index.3 +++ b/src/lib/libc/string/wmemchr.3 | |||
| @@ -1,8 +1,12 @@ | |||
| 1 | .\" $OpenBSD: wmemchr.3,v 1.10 2013/06/05 03:39:23 tedu Exp $ | ||
| 2 | .\" | ||
| 1 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. | 3 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. |
| 2 | .\" All rights reserved. | 4 | .\" All rights reserved. |
| 3 | .\" | 5 | .\" |
| 4 | .\" This code is derived from software contributed to Berkeley by | 6 | .\" This code is derived from software contributed to Berkeley by |
| 5 | .\" Chris Torek. | 7 | .\" Chris Torek and the American National Standards Committee X3, |
| 8 | .\" on Information Processing Systems. | ||
| 9 | .\" | ||
| 6 | .\" Redistribution and use in source and binary forms, with or without | 10 | .\" Redistribution and use in source and binary forms, with or without |
| 7 | .\" modification, are permitted provided that the following conditions | 11 | .\" modification, are permitted provided that the following conditions |
| 8 | .\" are met: | 12 | .\" are met: |
| @@ -11,11 +15,7 @@ | |||
| 11 | .\" 2. Redistributions in binary form must reproduce the above copyright | 15 | .\" 2. Redistributions in binary form must reproduce the above copyright |
| 12 | .\" notice, this list of conditions and the following disclaimer in the | 16 | .\" notice, this list of conditions and the following disclaimer in the |
| 13 | .\" documentation and/or other materials provided with the distribution. | 17 | .\" documentation and/or other materials provided with the distribution. |
| 14 | .\" 3. All advertising materials mentioning features or use of this software | 18 | .\" 3. Neither the name of the University nor the names of its contributors |
| 15 | .\" must display the following acknowledgement: | ||
| 16 | .\" This product includes software developed by the University of | ||
| 17 | .\" California, Berkeley and its contributors. | ||
| 18 | .\" 4. Neither the name of the University nor the names of its contributors | ||
| 19 | .\" may be used to endorse or promote products derived from this software | 19 | .\" may be used to endorse or promote products derived from this software |
| 20 | .\" without specific prior written permission. | 20 | .\" without specific prior written permission. |
| 21 | .\" | 21 | .\" |
| @@ -31,53 +31,51 @@ | |||
| 31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 32 | .\" SUCH DAMAGE. | 32 | .\" SUCH DAMAGE. |
| 33 | .\" | 33 | .\" |
| 34 | .\" from: @(#)index.3 5.3 (Berkeley) 4/19/91 | 34 | .Dd $Mdocdate: June 5 2013 $ |
| 35 | .\" $Id: index.3,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $ | 35 | .Dt WMEMCHR 3 |
| 36 | .\" | ||
| 37 | .Dd April 19, 1991 | ||
| 38 | .Dt INDEX 3 | ||
| 39 | .Os | 36 | .Os |
| 40 | .Sh NAME | 37 | .Sh NAME |
| 41 | .Nm index | 38 | .Nm wmemchr |
| 42 | .Nd locate character in string | 39 | .Nd locate wide character in wide string |
| 43 | .Sh SYNOPSIS | 40 | .Sh SYNOPSIS |
| 44 | .Fd #include <string.h> | 41 | .In wchar.h |
| 45 | .Ft char * | 42 | .Ft wchar_t * |
| 46 | .Fn index "const char *s" "int c" | 43 | .Fn wmemchr "const wchar_t *b" "wchar_t c" "size_t len" |
| 47 | .Sh DESCRIPTION | 44 | .Sh DESCRIPTION |
| 48 | The | 45 | The |
| 49 | .Fn index | 46 | .Fn wmemchr |
| 50 | function | 47 | function locates the first occurrence of |
| 51 | locates the first character matching | ||
| 52 | .Fa c | 48 | .Fa c |
| 53 | (converted to a | 49 | in wide string |
| 54 | .Em char ) | 50 | .Fa b . |
| 55 | in the null-terminated string | ||
| 56 | .Fa s . | ||
| 57 | .Sh RETURN VALUES | 51 | .Sh RETURN VALUES |
| 58 | The character | 52 | The |
| 59 | .Fa c | 53 | .Fn wmemchr |
| 60 | is returned if it is found; otherwise | 54 | function returns a pointer to the wide character located, or |
| 61 | .Dv NULL | 55 | .Dv NULL |
| 62 | is returned. | 56 | if no such wide character exists within |
| 63 | If | 57 | .Fa len |
| 64 | .Fa c | 58 | wide characters. |
| 65 | is '\e0', | ||
| 66 | .Fn index | ||
| 67 | locates the terminating '\e0'. | ||
| 68 | .Sh SEE ALSO | 59 | .Sh SEE ALSO |
| 69 | .Xr memchr 3 , | 60 | .Xr memchr 3 , |
| 70 | .Xr rindex 3 , | 61 | .Xr wcschr 3 , |
| 71 | .Xr strchr 3 , | 62 | .Xr wcscspn 3 , |
| 72 | .Xr strcspn 3 , | 63 | .Xr wcspbrk 3 , |
| 73 | .Xr strpbrk 3 , | 64 | .Xr wcsrchr 3 , |
| 74 | .Xr strrchr 3 , | 65 | .Xr wcsspn 3 , |
| 75 | .Xr strsep 3 , | 66 | .Xr wcsstr 3 , |
| 76 | .Xr strspn 3 , | 67 | .Xr wcstok 3 |
| 77 | .Xr strstr 3 , | 68 | .Sh STANDARDS |
| 78 | .Xr strtok 3 | 69 | The |
| 70 | .Fn wmemchr | ||
| 71 | function conforms to | ||
| 72 | .St -isoC-99 | ||
| 73 | and was first introduced in | ||
| 74 | .St -isoC-amd1 . | ||
| 79 | .Sh HISTORY | 75 | .Sh HISTORY |
| 80 | A | 76 | The |
| 81 | .Fn index | 77 | .Fn wmemchr |
| 82 | function appeared in | 78 | function was ported from |
| 83 | .At v6 . | 79 | .Nx |
| 80 | and first appeared in | ||
| 81 | .Ox 3.8 . | ||
diff --git a/src/lib/libc/string/wmemchr.c b/src/lib/libc/string/wmemchr.c new file mode 100644 index 0000000000..8c9517861b --- /dev/null +++ b/src/lib/libc/string/wmemchr.c | |||
| @@ -0,0 +1,47 @@ | |||
| 1 | /* $OpenBSD: wmemchr.c,v 1.3 2005/08/08 08:05:37 espie Exp $ */ | ||
| 2 | /* $NetBSD: wmemchr.c,v 1.2 2001/01/03 14:29:37 lukem Exp $ */ | ||
| 3 | |||
| 4 | /*- | ||
| 5 | * Copyright (c)1999 Citrus Project, | ||
| 6 | * All rights reserved. | ||
| 7 | * | ||
| 8 | * Redistribution and use in source and binary forms, with or without | ||
| 9 | * modification, are permitted provided that the following conditions | ||
| 10 | * are met: | ||
| 11 | * 1. Redistributions of source code must retain the above copyright | ||
| 12 | * notice, this list of conditions and the following disclaimer. | ||
| 13 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in the | ||
| 15 | * documentation and/or other materials provided with the distribution. | ||
| 16 | * | ||
| 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | ||
| 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
| 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 27 | * SUCH DAMAGE. | ||
| 28 | * | ||
| 29 | * citrus Id: wmemchr.c,v 1.2 2000/12/20 14:08:31 itojun Exp | ||
| 30 | */ | ||
| 31 | |||
| 32 | #include <wchar.h> | ||
| 33 | |||
| 34 | wchar_t * | ||
| 35 | wmemchr(const wchar_t *s, wchar_t c, size_t n) | ||
| 36 | { | ||
| 37 | size_t i; | ||
| 38 | |||
| 39 | for (i = 0; i < n; i++) { | ||
| 40 | if (*s == c) { | ||
| 41 | /* LINTED const castaway */ | ||
| 42 | return (wchar_t *)s; | ||
| 43 | } | ||
| 44 | s++; | ||
| 45 | } | ||
| 46 | return NULL; | ||
| 47 | } | ||
diff --git a/src/lib/libc/string/wmemcmp.3 b/src/lib/libc/string/wmemcmp.3 new file mode 100644 index 0000000000..bd8ddfd120 --- /dev/null +++ b/src/lib/libc/string/wmemcmp.3 | |||
| @@ -0,0 +1,78 @@ | |||
| 1 | .\" $OpenBSD: wmemcmp.3,v 1.3 2013/06/05 03:39:23 tedu Exp $ | ||
| 2 | .\" | ||
| 3 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. | ||
| 4 | .\" All rights reserved. | ||
| 5 | .\" | ||
| 6 | .\" This code is derived from software contributed to Berkeley by | ||
| 7 | .\" Chris Torek and the American National Standards Committee X3, | ||
| 8 | .\" on Information Processing Systems. | ||
| 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. 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 $Mdocdate: June 5 2013 $ | ||
| 35 | .Dt WMEMCMP 3 | ||
| 36 | .Os | ||
| 37 | .Sh NAME | ||
| 38 | .Nm wmemcmp | ||
| 39 | .Nd compare wide strings | ||
| 40 | .Sh SYNOPSIS | ||
| 41 | .In wchar.h | ||
| 42 | .Ft int | ||
| 43 | .Fn wmemcmp "const wchar_t *s1" "const wchar_t *s2" "size_t len" | ||
| 44 | .Sh DESCRIPTION | ||
| 45 | The | ||
| 46 | .Fn wmemcmp | ||
| 47 | function compares the wide string | ||
| 48 | .Fa s1 | ||
| 49 | against the wide string | ||
| 50 | .Fa s2 . | ||
| 51 | Both wide strings are assumed to be | ||
| 52 | .Fa len | ||
| 53 | wide characters long. | ||
| 54 | .Sh RETURN VALUES | ||
| 55 | The | ||
| 56 | .Fn wmemcmp | ||
| 57 | function returns zero if the two wide strings are identical, | ||
| 58 | otherwise the difference between the first two differing wide characters is | ||
| 59 | returned. | ||
| 60 | Zero-length wide strings are always identical. | ||
| 61 | .Sh SEE ALSO | ||
| 62 | .Xr memcmp 3 , | ||
| 63 | .Xr wcscasecmp 3 , | ||
| 64 | .Xr wcscmp 3 | ||
| 65 | .Sh STANDARDS | ||
| 66 | The | ||
| 67 | .Fn wmemcmp | ||
| 68 | function conforms to | ||
| 69 | .St -isoC-99 | ||
| 70 | and was first introduced in | ||
| 71 | .St -isoC-amd1 . | ||
| 72 | .Sh HISTORY | ||
| 73 | The | ||
| 74 | .Fn wmemcmp | ||
| 75 | function was ported from | ||
| 76 | .Nx | ||
| 77 | and first appeared in | ||
| 78 | .Ox 3.8 . | ||
diff --git a/src/lib/libc/string/wmemcmp.c b/src/lib/libc/string/wmemcmp.c new file mode 100644 index 0000000000..39419aeddc --- /dev/null +++ b/src/lib/libc/string/wmemcmp.c | |||
| @@ -0,0 +1,50 @@ | |||
| 1 | /* $OpenBSD: wmemcmp.c,v 1.4 2005/08/08 08:05:37 espie Exp $ */ | ||
| 2 | /* $NetBSD: wmemcmp.c,v 1.3 2003/04/06 18:33:23 tshiozak Exp $ */ | ||
| 3 | |||
| 4 | /*- | ||
| 5 | * Copyright (c)1999 Citrus Project, | ||
| 6 | * All rights reserved. | ||
| 7 | * | ||
| 8 | * Redistribution and use in source and binary forms, with or without | ||
| 9 | * modification, are permitted provided that the following conditions | ||
| 10 | * are met: | ||
| 11 | * 1. Redistributions of source code must retain the above copyright | ||
| 12 | * notice, this list of conditions and the following disclaimer. | ||
| 13 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in the | ||
| 15 | * documentation and/or other materials provided with the distribution. | ||
| 16 | * | ||
| 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | ||
| 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
| 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 27 | * SUCH DAMAGE. | ||
| 28 | * | ||
| 29 | * citrus Id: wmemcmp.c,v 1.2 2000/12/20 14:08:31 itojun Exp | ||
| 30 | */ | ||
| 31 | |||
| 32 | #include <wchar.h> | ||
| 33 | #include "locale/runetype.h" | ||
| 34 | |||
| 35 | int | ||
| 36 | wmemcmp(const wchar_t *s1, const wchar_t *s2, size_t n) | ||
| 37 | { | ||
| 38 | size_t i; | ||
| 39 | |||
| 40 | for (i = 0; i < n; i++) { | ||
| 41 | if (*s1 != *s2) { | ||
| 42 | /* wchar might be unsigned */ | ||
| 43 | return *(const rune_t *)s1 > | ||
| 44 | *(const rune_t *)s2 ? 1 : -1; | ||
| 45 | } | ||
| 46 | s1++; | ||
| 47 | s2++; | ||
| 48 | } | ||
| 49 | return 0; | ||
| 50 | } | ||
diff --git a/src/lib/libc/string/wmemcpy.3 b/src/lib/libc/string/wmemcpy.3 new file mode 100644 index 0000000000..2a6d528a1a --- /dev/null +++ b/src/lib/libc/string/wmemcpy.3 | |||
| @@ -0,0 +1,79 @@ | |||
| 1 | .\" $OpenBSD: wmemcpy.3,v 1.5 2013/06/05 03:39:23 tedu Exp $ | ||
| 2 | .\" | ||
| 3 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. | ||
| 4 | .\" All rights reserved. | ||
| 5 | .\" | ||
| 6 | .\" This code is derived from software contributed to Berkeley by | ||
| 7 | .\" Chris Torek and the American National Standards Committee X3, | ||
| 8 | .\" on Information Processing Systems. | ||
| 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. 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 $Mdocdate: June 5 2013 $ | ||
| 35 | .Dt WMEMCPY 3 | ||
| 36 | .Os | ||
| 37 | .Sh NAME | ||
| 38 | .Nm wmemcpy | ||
| 39 | .Nd copy wide characters | ||
| 40 | .Sh SYNOPSIS | ||
| 41 | .In wchar.h | ||
| 42 | .Ft wchar_t * | ||
| 43 | .Fn wmemcpy "wchar_t * restrict dst" "const wchar_t * restrict src" "size_t len" | ||
| 44 | .Sh DESCRIPTION | ||
| 45 | The | ||
| 46 | .Fn wmemcpy | ||
| 47 | function copies | ||
| 48 | .Fa len | ||
| 49 | wide characters from buffer | ||
| 50 | .Fa src | ||
| 51 | to buffer | ||
| 52 | .Fa dst . | ||
| 53 | If the two buffers may overlap, | ||
| 54 | .Xr wmemmove 3 | ||
| 55 | must be used instead. | ||
| 56 | .Sh RETURN VALUES | ||
| 57 | The | ||
| 58 | .Fn wmemcpy | ||
| 59 | function returns the original value of | ||
| 60 | .Fa dst . | ||
| 61 | .Sh SEE ALSO | ||
| 62 | .Xr memcpy 3 , | ||
| 63 | .Xr wcscpy 3 , | ||
| 64 | .Xr wcslcpy 3 , | ||
| 65 | .Xr wmemmove 3 | ||
| 66 | .Sh STANDARDS | ||
| 67 | The | ||
| 68 | .Fn wmemcpy | ||
| 69 | function conforms to | ||
| 70 | .St -isoC-99 | ||
| 71 | and was first introduced in | ||
| 72 | .St -isoC-amd1 . | ||
| 73 | .Sh HISTORY | ||
| 74 | The | ||
| 75 | .Fn wmemcpy | ||
| 76 | function was ported from | ||
| 77 | .Nx | ||
| 78 | and first appeared in | ||
| 79 | .Ox 3.8 . | ||
diff --git a/src/lib/libc/string/wmemcpy.c b/src/lib/libc/string/wmemcpy.c new file mode 100644 index 0000000000..9bbd83648e --- /dev/null +++ b/src/lib/libc/string/wmemcpy.c | |||
| @@ -0,0 +1,40 @@ | |||
| 1 | /* $OpenBSD: wmemcpy.c,v 1.3 2005/08/08 08:05:37 espie Exp $ */ | ||
| 2 | /* $NetBSD: wmemcpy.c,v 1.2 2001/01/03 14:29:37 lukem Exp $ */ | ||
| 3 | |||
| 4 | /*- | ||
| 5 | * Copyright (c)1999 Citrus Project, | ||
| 6 | * All rights reserved. | ||
| 7 | * | ||
| 8 | * Redistribution and use in source and binary forms, with or without | ||
| 9 | * modification, are permitted provided that the following conditions | ||
| 10 | * are met: | ||
| 11 | * 1. Redistributions of source code must retain the above copyright | ||
| 12 | * notice, this list of conditions and the following disclaimer. | ||
| 13 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in the | ||
| 15 | * documentation and/or other materials provided with the distribution. | ||
| 16 | * | ||
| 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | ||
| 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
| 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 27 | * SUCH DAMAGE. | ||
| 28 | * | ||
| 29 | * citrus Id: wmemcpy.c,v 1.2 2000/12/20 14:08:31 itojun Exp | ||
| 30 | */ | ||
| 31 | |||
| 32 | #include <string.h> | ||
| 33 | #include <wchar.h> | ||
| 34 | |||
| 35 | wchar_t * | ||
| 36 | wmemcpy(wchar_t *d, const wchar_t *s, size_t n) | ||
| 37 | { | ||
| 38 | |||
| 39 | return (wchar_t *)memcpy(d, s, n * sizeof(wchar_t)); | ||
| 40 | } | ||
diff --git a/src/lib/libc/string/wmemmove.3 b/src/lib/libc/string/wmemmove.3 new file mode 100644 index 0000000000..46942e7928 --- /dev/null +++ b/src/lib/libc/string/wmemmove.3 | |||
| @@ -0,0 +1,78 @@ | |||
| 1 | .\" $OpenBSD: wmemmove.3,v 1.3 2013/06/05 03:39:23 tedu Exp $ | ||
| 2 | .\" | ||
| 3 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. | ||
| 4 | .\" All rights reserved. | ||
| 5 | .\" | ||
| 6 | .\" This code is derived from software contributed to Berkeley by | ||
| 7 | .\" Chris Torek and the American National Standards Committee X3, | ||
| 8 | .\" on Information Processing Systems. | ||
| 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. 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 $Mdocdate: June 5 2013 $ | ||
| 35 | .Dt WMEMMOVE 3 | ||
| 36 | .Os | ||
| 37 | .Sh NAME | ||
| 38 | .Nm wmemmove | ||
| 39 | .Nd copy wide characters | ||
| 40 | .Sh SYNOPSIS | ||
| 41 | .In wchar.h | ||
| 42 | .Ft wchar_t * | ||
| 43 | .Fn wmemmove "wchar_t *dst" "const wchar_t *src" "size_t len" | ||
| 44 | .Sh DESCRIPTION | ||
| 45 | The | ||
| 46 | .Fn wmemmove | ||
| 47 | function copies | ||
| 48 | .Fa len | ||
| 49 | wide characters from buffer | ||
| 50 | .Fa src | ||
| 51 | to buffer | ||
| 52 | .Fa dst . | ||
| 53 | The two buffers may overlap; | ||
| 54 | the copy is always done in a non-destructive manner. | ||
| 55 | .Sh RETURN VALUES | ||
| 56 | The | ||
| 57 | .Fn wmemmove | ||
| 58 | function returns the original value of | ||
| 59 | .Fa dst . | ||
| 60 | .Sh SEE ALSO | ||
| 61 | .Xr memmove 3 , | ||
| 62 | .Xr wcscpy 3 , | ||
| 63 | .Xr wcslcpy 3 , | ||
| 64 | .Xr wmemcpy 3 | ||
| 65 | .Sh STANDARDS | ||
| 66 | The | ||
| 67 | .Fn wmemmove | ||
| 68 | function conforms to | ||
| 69 | .St -isoC-99 | ||
| 70 | and was first introduced in | ||
| 71 | .St -isoC-amd1 . | ||
| 72 | .Sh HISTORY | ||
| 73 | The | ||
| 74 | .Fn wmemmove | ||
| 75 | function was ported from | ||
| 76 | .Nx | ||
| 77 | and first appeared in | ||
| 78 | .Ox 3.8 . | ||
diff --git a/src/lib/libc/string/wmemmove.c b/src/lib/libc/string/wmemmove.c new file mode 100644 index 0000000000..21bbabcd0c --- /dev/null +++ b/src/lib/libc/string/wmemmove.c | |||
| @@ -0,0 +1,40 @@ | |||
| 1 | /* $OpenBSD: wmemmove.c,v 1.3 2005/08/08 08:05:37 espie Exp $ */ | ||
| 2 | /* $NetBSD: wmemmove.c,v 1.2 2001/01/03 14:29:37 lukem Exp $ */ | ||
| 3 | |||
| 4 | /*- | ||
| 5 | * Copyright (c)1999 Citrus Project, | ||
| 6 | * All rights reserved. | ||
| 7 | * | ||
| 8 | * Redistribution and use in source and binary forms, with or without | ||
| 9 | * modification, are permitted provided that the following conditions | ||
| 10 | * are met: | ||
| 11 | * 1. Redistributions of source code must retain the above copyright | ||
| 12 | * notice, this list of conditions and the following disclaimer. | ||
| 13 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in the | ||
| 15 | * documentation and/or other materials provided with the distribution. | ||
| 16 | * | ||
| 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | ||
| 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
| 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 27 | * SUCH DAMAGE. | ||
| 28 | * | ||
| 29 | * citrus Id: wmemmove.c,v 1.2 2000/12/20 14:08:31 itojun Exp | ||
| 30 | */ | ||
| 31 | |||
| 32 | #include <string.h> | ||
| 33 | #include <wchar.h> | ||
| 34 | |||
| 35 | wchar_t * | ||
| 36 | wmemmove(wchar_t *d, const wchar_t *s, size_t n) | ||
| 37 | { | ||
| 38 | |||
| 39 | return (wchar_t *)memmove(d, s, n * sizeof(wchar_t)); | ||
| 40 | } | ||
diff --git a/src/lib/libc/string/wmemset.3 b/src/lib/libc/string/wmemset.3 new file mode 100644 index 0000000000..2655d68bcb --- /dev/null +++ b/src/lib/libc/string/wmemset.3 | |||
| @@ -0,0 +1,73 @@ | |||
| 1 | .\" $OpenBSD: wmemset.3,v 1.4 2013/06/05 03:39:23 tedu Exp $ | ||
| 2 | .\" | ||
| 3 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. | ||
| 4 | .\" All rights reserved. | ||
| 5 | .\" | ||
| 6 | .\" This code is derived from software contributed to Berkeley by | ||
| 7 | .\" Chris Torek and the American National Standards Committee X3, | ||
| 8 | .\" on Information Processing Systems. | ||
| 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. 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 $Mdocdate: June 5 2013 $ | ||
| 35 | .Dt WMEMSET 3 | ||
| 36 | .Os | ||
| 37 | .Sh NAME | ||
| 38 | .Nm wmemset | ||
| 39 | .Nd write a wide string | ||
| 40 | .Sh SYNOPSIS | ||
| 41 | .In wchar.h | ||
| 42 | .Ft wchar_t * | ||
| 43 | .Fn wmemset "wchar_t *s" "wchar_t c" "size_t len" | ||
| 44 | .Sh DESCRIPTION | ||
| 45 | The | ||
| 46 | .Fn wmemset | ||
| 47 | function writes | ||
| 48 | .Fa len | ||
| 49 | wide characters of value | ||
| 50 | .Fa c | ||
| 51 | to the wide string | ||
| 52 | .Fa s . | ||
| 53 | .Sh RETURN VALUES | ||
| 54 | The | ||
| 55 | .Fn wmemset | ||
| 56 | function returns the original value of | ||
| 57 | .Fa s . | ||
| 58 | .Sh SEE ALSO | ||
| 59 | .Xr memset 3 | ||
| 60 | .Sh STANDARDS | ||
| 61 | The | ||
| 62 | .Fn wmemset | ||
| 63 | function conforms to | ||
| 64 | .St -isoC-99 | ||
| 65 | and was first introduced in | ||
| 66 | .St -isoC-amd1 . | ||
| 67 | .Sh HISTORY | ||
| 68 | The | ||
| 69 | .Fn wmemset | ||
| 70 | function was ported from | ||
| 71 | .Nx | ||
| 72 | and first appeared in | ||
| 73 | .Ox 3.8 . | ||
diff --git a/src/lib/libc/string/wmemset.c b/src/lib/libc/string/wmemset.c new file mode 100644 index 0000000000..ac476dba6a --- /dev/null +++ b/src/lib/libc/string/wmemset.c | |||
| @@ -0,0 +1,46 @@ | |||
| 1 | /* $OpenBSD: wmemset.c,v 1.3 2005/08/08 08:05:37 espie Exp $ */ | ||
| 2 | /* $NetBSD: wmemset.c,v 1.2 2001/01/03 14:29:37 lukem Exp $ */ | ||
| 3 | |||
| 4 | /*- | ||
| 5 | * Copyright (c)1999 Citrus Project, | ||
| 6 | * All rights reserved. | ||
| 7 | * | ||
| 8 | * Redistribution and use in source and binary forms, with or without | ||
| 9 | * modification, are permitted provided that the following conditions | ||
| 10 | * are met: | ||
| 11 | * 1. Redistributions of source code must retain the above copyright | ||
| 12 | * notice, this list of conditions and the following disclaimer. | ||
| 13 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in the | ||
| 15 | * documentation and/or other materials provided with the distribution. | ||
| 16 | * | ||
| 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | ||
| 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
| 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 27 | * SUCH DAMAGE. | ||
| 28 | * | ||
| 29 | * citrus Id: wmemset.c,v 1.2 2000/12/20 14:08:31 itojun Exp | ||
| 30 | */ | ||
| 31 | |||
| 32 | #include <wchar.h> | ||
| 33 | |||
| 34 | wchar_t * | ||
| 35 | wmemset(wchar_t *s, wchar_t c, size_t n) | ||
| 36 | { | ||
| 37 | size_t i; | ||
| 38 | wchar_t *p; | ||
| 39 | |||
| 40 | p = s; | ||
| 41 | for (i = 0; i < n; i++) { | ||
| 42 | *p = c; | ||
| 43 | p++; | ||
| 44 | } | ||
| 45 | return s; | ||
| 46 | } | ||
